Skip to main content

Websocket Connection

Websockets are used to receive real-time updates from the Blink API.
Implemented using the GraphQL over WebSocket Protocol

Available Websocket Events

  • myUpdates
  • lnInvoicePaymentStatus
  • realtimePrice
  • price

Websocket Endpoint

wss://ws.blink.sv/graphql

Apollo Playground

To try the subscriptions and explore the schema use the
Apollo Playground for Blink subscriptions

After loading the playground:

  • open the SANDBOX connection settings and set:
    wss://ws.blink.sv/graphql as the Subscriptions URL then Save.

Authentication with X-API-KEY

WebSocket connections require authentication using your API key from the Blink Dashboard.

Unlike regular HTTP requests where the API key is sent in a header, for WebSocket connections, the API key is included in the connection initialization payload:

{
"type": "connection_init",
"payload": {
"X-API-KEY": "blink_your_api_key_here"
}
}

This authentication method is required for accessing user-specific subscription data like myUpdates.

Postman

Try the websocket connection examples in the Galoy API collection

To use the raw websocket protocol in Postman there are a few steps to follow:

Header to Use

  • Define the protocol
    Sec-WebSocket-Protocol: graphql-transport-ws

Send the connection_init Request

  • to get a connection_ack response
    {
    "type": "connection_init",
    "payload": {}
    }

For Authenticated Requests

  • include the api key in the payload of the connection_init request
    {
    "type": "connection_init",
    "payload": {
    "X-API-KEY": "<your api key>"
    }
    }

Send a Subscription Request

  • use the format described in the GraphQL over WebSocket Protocol
  • need to paste the message in place of the connection_init message to continue using the same connection
    {
    "id": "1",
    "type": "subscribe",
    "payload": {
    "query": "subscription { price( input: { amount: 100 amountCurrencyUnit: BTCSAT priceCurrencyUnit: USDCENT } ) { errors { message } price { base offset currencyUnit } }}",
    "variables": {}
    }
    }

Websocat

  • Install with:

    • Linux (with a Rust toolchain installed)
      cargo install websocat
    • MacOS
      brew install websocat
  • Connect to the websocket endpoint

    websocat ${websocket_endpoint} -H 'Sec-WebSocket-Protocol: graphql-transport-ws' -v

Usage without Authentication

  • Send the connection_init request for non-authenticated requests

    { "type": "connection_init", "payload": {} }
  • price subscription message

    { "id": "1", "type": "subscribe", "payload": {  "query": "subscription { price( input: { amount: 100 amountCurrencyUnit: BTCSAT priceCurrencyUnit: USDCENT } ) { errors { message } price { base offset currencyUnit } }}",  "variables": {} }}
  • realtimePrice subscription message

    { "id": "2", "type": "subscribe", "payload": { "query": "subscription realtimePrice($input: RealtimePriceInput!) { realtimePrice(input: $input) { realtimePrice { id btcSatPrice { base offset } } errors { code message path } }}", "variables": { "input": { "currency": "USD" } } }}

Example Output

  • websocat ${websocket_endpoint} -H 'Sec-WebSocket-Protocol: graphql-transport-ws' -v
    [INFO websocat::lints] Auto-inserting the line mode
    [INFO websocat::stdio_threaded_peer] get_stdio_peer (threaded)
    [INFO websocat::ws_client_peer] get_ws_client_peer
    [INFO websocat::ws_client_peer] Connected to ws
    { "type": "connection_init", "payload": {}}
    {"type":"connection_ack"}
    { "id": "1", "type": "subscribe", "payload": { "query": "subscription { price( input: { amount: 100 amountCurrencyUnit: BTCSAT priceCurrencyUnit: USDCENT } ) { errors { message } price { base offset currencyUnit } }}", "variables": {} }}
    {"id":"1","type":"next","payload":{"data":{"price":{"errors":[],"price":{"base":4364414843750,"offset":12,"currencyUnit":"USDCENT"}}}}}
    [INFO websocat::ws_peer] Received WebSocket ping
    { "id": "2", "type": "subscribe", "payload": { "query": "subscription realtimePrice($input: RealtimePriceInput!) { realtimePrice(input: $input) { realtimePrice { id btcSatPrice { base offset } } errors { code message path } }}", "variables": { "input": { "currency": "USD" } } }}
    {"id":"2","type":"next","payload":{"data":{"realtimePrice":{"realtimePrice":{"id":"a6e2abdb-431e-5455-81c1-92fbaccfb0de","btcSatPrice":{"base":43623050781,"offset":12}},"errors":[]}}}}
    [INFO websocat::ws_peer] Received WebSocket ping
    {"id":"1","type":"next","payload":{"data":{"price":{"errors":[],"price":{"base":4362700000000,"offset":12,"currencyUnit":"USDCENT"}}}}}
    {"id":"2","type":"next","payload":{"data":{"realtimePrice":{"realtimePrice":{"id":"6d453741-e0ad-5fec-b27f-3d987571f5ad","btcSatPrice":{"base":43627000000,"offset":12}},"errors":[]}}}}

Authenticated Usage

  • Send the connection_init request for authenticated requests

    { "type": "connection_init", "payload": { "X-API-KEY": "blink_xxxx" } }
  • myUpdates subscription message

    { "id": "1", "type": "subscribe", "payload": { "query": "subscription { myUpdates { update { ... on LnUpdate { transaction { initiationVia { ... on InitiationViaLn { paymentHash } } direction } } } } }", "variables": {} }}
  • lnInvoicePaymentStatus subscription message

    { "id": "2", "type": "subscribe", "payload": { "query": "subscription LnInvoicePaymentStatus($input: LnInvoicePaymentStatusInput!) { lnInvoicePaymentStatus(input: $input) { status errors { code message path } }}", "variables": { "input": { "paymentRequest": "lnbc...." } } }}

Example Output

  • websocat ${websocket_endpoint} -H 'Sec-WebSocket-Protocol: graphql-transport-ws' -v
    [INFO websocat::lints] Auto-inserting the line mode
    [INFO websocat::stdio_threaded_peer] get_stdio_peer (threaded)
    [INFO websocat::ws_client_peer] get_ws_client_peer
    [INFO websocat::ws_client_peer] Connected to ws
    { "type": "connection_init", "payload": { "X-API-KEY": "blink_xxxx" } }
    {"type":"connection_ack"}
    [INFO websocat::ws_peer] Received WebSocket ping
    { "id": "1", "type": "subscribe", "payload": { "query": "subscription { myUpdates { update { ... on LnUpdate { transaction { initiationVia { ... on InitiationViaLn { paymentHash } } direction } } } } }", "variables": {} }}
    {"id":"1","type":"next","payload":{"data":{"myUpdates":{"update":{}}}}}
    {"id":"1","type":"next","payload":{"data":{"myUpdates":{"update":{}}}}}
    [INFO websocat::ws_peer] Received WebSocket ping
    {"id":"1","type":"next","payload":{"data":{"myUpdates":{"update":{}}}}}
    {"id":"1","type":"next","payload":{"data":{"myUpdates":{"update":{}}}}}
    { "id": "2", "type": "subscribe", "payload": { "query": "subscription LnInvoicePaymentStatus($input: LnInvoicePaymentStatusInput!) { lnInvoicePaymentStatus(input: $input) { status errors { code message path } }}", "variables": { "input": { "paymentRequest": "lntbs1220n1pjklpx5pp5wn0zrhygl8u8p7k5nggsa3hcj9htkk0t8df5mxm2hrumk5gedgwsdq0w3jhxapqd4jk6mccqzpuxqyz5vqsp566v7qag22wnl5spf3zhrfruxyaek5m3uv5pu4dzpwmffk6adykpq9qyyssq62exrk3zcwfeh9c0hnhlpv9lmn33fryz4l9acmq79myp57lgj29390tucf4rycxn3zxtre8fzuzs6acu0w4umuetu9zr04zusa56duspsmsxv5" } } }}
    {"id":"2","type":"next","payload":{"data":{"lnInvoicePaymentStatus":{"status":"PAID","errors":[]}}}}
    [INFO websocat::ws_peer] Received WebSocket ping