Blockchain · AsyncAPI Specification

Blockchain.com WebSocket APIs

Version 1.0.0

Real-time WebSocket APIs published by Blockchain.com covering two distinct surfaces: 1. Bitcoin / blockchain.info Explorer WebSocket — subscribe to unconfirmed transactions, new blocks, address activity, and OP_RETURN data; plus ping operations for the latest block and transaction. 2. Blockchain.com Exchange WebSocket (mercury-gateway) — market data (heartbeat, ticker, L2 / L3 order books, prices, symbols, trades) and authenticated channels (auth, balances, trading). All messages are JSON. Exchange trading uses FIX 4.2 field names. Each Exchange message includes a monotonically increasing `seqnum`; gaps indicate dropped messages and warrant reconnection. Sources: - https://www.blockchain.com/explorer/api/api_websocket - https://github.com/blockchain/docs-exchange-api (source of exchange.blockchain.com/api)

View Spec View on GitHub CryptocurrencyPublic APIsAsyncAPIWebhooksEvents

Channels

/inv#unconfirmed_sub
publish subscribeUnconfirmed
Subscribe / unsubscribe to all unconfirmed transactions.
Stream of all new unconfirmed Bitcoin transactions broadcast to the network. Subscribe with `{"op":"unconfirmed_sub"}`; unsubscribe with `{"op":"unconfirmed_unsub"}`.
/inv#blocks_sub
publish subscribeBlocks
Subscribe / unsubscribe to new block notifications.
Stream of newly mined Bitcoin blocks. Subscribe with `{"op":"blocks_sub"}`; unsubscribe with `{"op":"blocks_unsub"}`.
/inv#addr_sub
publish subscribeAddress
Subscribe / unsubscribe to transactions for a specific Bitcoin address.
Stream of transactions involving a specific Bitcoin address. The `addr` parameter is required and identifies the address being watched. Subscribe with `{"op":"addr_sub","addr":"$bitcoin_address"}`; unsubscribe with the matching `addr_unsub`.
/inv#op_return_sub
publish subscribeOpReturn
Subscribe to transactions containing OP_RETURN outputs.
Stream of transactions containing OP_RETURN outputs (arbitrary data embeds).
/inv#ping_tx
publish pingTx
Request the most recently seen transaction.
Debug ping that requests the latest transaction observed by the server.
/inv#ping_block
publish pingBlock
Request the most recently seen block.
Debug ping that requests the latest block observed by the server.
/inv#ping
publish pingConnection
Keep the connection alive.
Generic connection-keepalive ping. Send `{"op":"ping"}` to keep the connection open.
/mercury-gateway/v1/ws#heartbeat
publish subscribeHeartbeat
Subscribe / unsubscribe to heartbeats.
Server-pushed heartbeat sent every 5 seconds after subscription.
/mercury-gateway/v1/ws#l2
publish subscribeL2
Subscribe / unsubscribe to L2 order book updates for a symbol.
Level 2 (price-aggregated) order book per symbol. Each entry has price (`px`), aggregated quantity (`qty`), and order count (`num`). Updates with `qty:0` indicate the price level should be removed.
/mercury-gateway/v1/ws#l3
publish subscribeL3
Subscribe / unsubscribe to L3 order book updates for a symbol.
Level 3 (order-by-order) book per symbol. Each entry has order `id`, `px`, and `qty`. Updates with `qty:0` indicate the order should be removed.
/mercury-gateway/v1/ws#prices
publish subscribePrices
Subscribe / unsubscribe to candlestick updates.
Candlestick (OHLCV) market data per symbol. Subscriptions require `granularity` in seconds; supported values are 60, 300, 900, 3600, 21600, 86400. Updates contain a `price` array: [timestamp, open, high, low, close, volume].
/mercury-gateway/v1/ws#symbols
publish subscribeSymbols
Subscribe / unsubscribe to symbol status updates.
Symbol reference data: a snapshot of all trading symbols with their currency, scale, order size limits, status (open / close / suspend / halt / halt-freeze), and any auction details. Subsequent updates are sent when a symbol's status changes.
/mercury-gateway/v1/ws#ticker
publish subscribeTicker
Subscribe / unsubscribe to ticker updates for a symbol.
Ticker snapshot for a symbol: 24-hour reference price, 24-hour volume, and last trade price.
/mercury-gateway/v1/ws#trades
publish subscribeTrades
Subscribe / unsubscribe to trade execution updates for a symbol.
Per-symbol stream of executed trades on the Exchange, including side, size, price, and `trade_id`.
/mercury-gateway/v1/ws#auth
publish subscribeAuth
Submit credentials to authenticate the connection.
Authenticates the WebSocket connection using an API secret as `token`. As an alternative, a connection may set the `auth_token` cookie header at handshake time, in which case authentication happens automatically without sending this message.
/mercury-gateway/v1/ws#balances
publish subscribeBalances
Subscribe / unsubscribe to balance snapshots.
Authenticated channel that emits a `snapshot` of the user's balances on initial subscription and again on every balance change. Zero balances are omitted from the initial snapshot.
/mercury-gateway/v1/ws#trading
publish tradingActions
Subscribe to or interact with the trading channel.
Authenticated trading channel. Subscribers receive an initial snapshot of live orders and execution-report updates thereafter. The channel supports the following actions: `NewOrderSingle`, `CancelOrderRequest`, `OrderMassCancelRequest`, `OrderMassStatusRequest`. Subscribing with `cancelOnDisconnect: true` causes all live orders to be cancelled if the connection drops; the flag cannot be turned off once enabled. Order messages use FIX 4.2 field names.

Messages

BitcoinOpPing
Generic ping
BitcoinOpPingTx
Ping for latest transaction
BitcoinOpPingBlock
Ping for latest block
BitcoinOpUnconfirmedSub
Subscribe to unconfirmed transactions
BitcoinOpUnconfirmedUnsub
Unsubscribe from unconfirmed transactions
BitcoinOpBlocksSub
Subscribe to new blocks
BitcoinOpBlocksUnsub
Unsubscribe from new blocks
BitcoinOpAddrSub
Subscribe to address activity
BitcoinOpAddrUnsub
Unsubscribe from address activity
BitcoinOpOpReturnSub
Subscribe to OP_RETURN transactions
BitcoinUtxMessage
Unconfirmed transaction (utx)
BitcoinBlockMessage
New Bitcoin block
ExchangeSubscribeAction
Generic subscribe / unsubscribe (no symbol)
ExchangeSubscribeSymbolAction
Subscribe / unsubscribe to a per-symbol channel
ExchangeSubscribePricesAction
Subscribe / unsubscribe to the prices channel
ExchangeAdminEvent
Subscription admin event (subscribed / unsubscribed / rejected)
ExchangeHeartbeatUpdate
Heartbeat update (every 5 seconds)
ExchangeL2Event
L2 order book snapshot / update
ExchangeL3Event
L3 order book snapshot / update
ExchangePricesUpdate
Candlestick update
ExchangeSymbolsSnapshot
Symbols snapshot
ExchangeSymbolUpdate
Symbol status update
ExchangeTickerSnapshot
Ticker snapshot
ExchangeTradeUpdate
Trade execution update
ExchangeAuthSubscribe
Authenticate the connection
ExchangeAuthSubscribed
Authentication accepted
ExchangeAuthRejected
Authentication failed
ExchangeBalancesSnapshot
Balances snapshot
ExchangeTradingSubscribe
Subscribe to the trading channel
ExchangeNewOrderSingle
NewOrderSingle (create order)
ExchangeCancelOrderRequest
CancelOrderRequest
ExchangeOrderMassCancelRequest
OrderMassCancelRequest
ExchangeOrderMassStatusRequest
OrderMassStatusRequest
ExchangeTradingSnapshot
Snapshot of live orders
ExchangeExecutionReport
Execution report (order update)
ExchangeTradingRejected
Trading action rejected

Servers

wss
bitcoin ws.blockchain.info/inv
Bitcoin / blockchain.info Explorer real-time WebSocket. Pushes unconfirmed transactions, new blocks, and per-address activity.
wss
exchange ws.blockchain.info/mercury-gateway/v1/ws
Blockchain.com Exchange WebSocket (mercury-gateway). Connection requires the HTTP header `Origin: https://exchange.blockchain.com`. Rate limited to 1200 messages / minute.

AsyncAPI Specification

Raw ↑
asyncapi: '2.6.0'
info:
  title: Blockchain.com WebSocket APIs
  version: '1.0.0'
  description: |
    Real-time WebSocket APIs published by Blockchain.com covering two distinct surfaces:

    1. Bitcoin / blockchain.info Explorer WebSocket — subscribe to unconfirmed transactions, new blocks,
       address activity, and OP_RETURN data; plus ping operations for the latest block and transaction.
    2. Blockchain.com Exchange WebSocket (mercury-gateway) — market data (heartbeat, ticker, L2 / L3
       order books, prices, symbols, trades) and authenticated channels (auth, balances, trading).

    All messages are JSON. Exchange trading uses FIX 4.2 field names. Each Exchange message includes a
    monotonically increasing `seqnum`; gaps indicate dropped messages and warrant reconnection.

    Sources:
      - https://www.blockchain.com/explorer/api/api_websocket
      - https://github.com/blockchain/docs-exchange-api (source of exchange.blockchain.com/api)
  contact:
    name: Blockchain.com
    url: https://www.blockchain.com
  license:
    name: Proprietary
    url: https://www.blockchain.com/legal/terms

defaultContentType: application/json

servers:
  bitcoin:
    url: ws.blockchain.info/inv
    protocol: wss
    description: |
      Bitcoin / blockchain.info Explorer real-time WebSocket. Pushes unconfirmed transactions, new
      blocks, and per-address activity.
  exchange:
    url: ws.blockchain.info/mercury-gateway/v1/ws
    protocol: wss
    description: |
      Blockchain.com Exchange WebSocket (mercury-gateway). Connection requires the HTTP header
      `Origin: https://exchange.blockchain.com`. Rate limited to 1200 messages / minute.

channels:

  # ---------------------------------------------------------------------------
  # BITCOIN / BLOCKCHAIN.INFO EXPLORER CHANNELS
  # ---------------------------------------------------------------------------

  /inv#unconfirmed_sub:
    description: |
      Stream of all new unconfirmed Bitcoin transactions broadcast to the network.
      Subscribe with `{"op":"unconfirmed_sub"}`; unsubscribe with `{"op":"unconfirmed_unsub"}`.
    servers:
      - bitcoin
    publish:
      operationId: subscribeUnconfirmed
      summary: Subscribe / unsubscribe to all unconfirmed transactions.
      message:
        oneOf:
          - $ref: '#/components/messages/BitcoinOpUnconfirmedSub'
          - $ref: '#/components/messages/BitcoinOpUnconfirmedUnsub'
    subscribe:
      operationId: receiveUnconfirmedTx
      summary: Receive utx events for newly seen unconfirmed transactions.
      message:
        $ref: '#/components/messages/BitcoinUtxMessage'

  /inv#blocks_sub:
    description: |
      Stream of newly mined Bitcoin blocks. Subscribe with `{"op":"blocks_sub"}`;
      unsubscribe with `{"op":"blocks_unsub"}`.
    servers:
      - bitcoin
    publish:
      operationId: subscribeBlocks
      summary: Subscribe / unsubscribe to new block notifications.
      message:
        oneOf:
          - $ref: '#/components/messages/BitcoinOpBlocksSub'
          - $ref: '#/components/messages/BitcoinOpBlocksUnsub'
    subscribe:
      operationId: receiveBlock
      summary: Receive block events for each newly mined block.
      message:
        $ref: '#/components/messages/BitcoinBlockMessage'

  /inv#addr_sub:
    description: |
      Stream of transactions involving a specific Bitcoin address. The `addr` parameter is required
      and identifies the address being watched. Subscribe with
      `{"op":"addr_sub","addr":"$bitcoin_address"}`; unsubscribe with the matching `addr_unsub`.
    servers:
      - bitcoin
    parameters:
      addr:
        description: Bitcoin address to monitor.
        schema:
          type: string
    publish:
      operationId: subscribeAddress
      summary: Subscribe / unsubscribe to transactions for a specific Bitcoin address.
      message:
        oneOf:
          - $ref: '#/components/messages/BitcoinOpAddrSub'
          - $ref: '#/components/messages/BitcoinOpAddrUnsub'
    subscribe:
      operationId: receiveAddressTx
      summary: Receive utx events for transactions involving the subscribed address.
      message:
        $ref: '#/components/messages/BitcoinUtxMessage'

  /inv#op_return_sub:
    description: |
      Stream of transactions containing OP_RETURN outputs (arbitrary data embeds).
    servers:
      - bitcoin
    publish:
      operationId: subscribeOpReturn
      summary: Subscribe to transactions containing OP_RETURN outputs.
      message:
        $ref: '#/components/messages/BitcoinOpOpReturnSub'
    subscribe:
      operationId: receiveOpReturnTx
      summary: Receive utx events for transactions that include OP_RETURN data.
      message:
        $ref: '#/components/messages/BitcoinUtxMessage'

  /inv#ping_tx:
    description: |
      Debug ping that requests the latest transaction observed by the server.
    servers:
      - bitcoin
    publish:
      operationId: pingTx
      summary: Request the most recently seen transaction.
      message:
        $ref: '#/components/messages/BitcoinOpPingTx'
    subscribe:
      operationId: receivePingTx
      summary: Receive the latest utx message in response to ping_tx.
      message:
        $ref: '#/components/messages/BitcoinUtxMessage'

  /inv#ping_block:
    description: |
      Debug ping that requests the latest block observed by the server.
    servers:
      - bitcoin
    publish:
      operationId: pingBlock
      summary: Request the most recently seen block.
      message:
        $ref: '#/components/messages/BitcoinOpPingBlock'
    subscribe:
      operationId: receivePingBlock
      summary: Receive the latest block message in response to ping_block.
      message:
        $ref: '#/components/messages/BitcoinBlockMessage'

  /inv#ping:
    description: |
      Generic connection-keepalive ping. Send `{"op":"ping"}` to keep the connection open.
    servers:
      - bitcoin
    publish:
      operationId: pingConnection
      summary: Keep the connection alive.
      message:
        $ref: '#/components/messages/BitcoinOpPing'

  # ---------------------------------------------------------------------------
  # EXCHANGE — ANONYMOUS CHANNELS
  # ---------------------------------------------------------------------------

  /mercury-gateway/v1/ws#heartbeat:
    description: |
      Server-pushed heartbeat sent every 5 seconds after subscription.
    servers:
      - exchange
    publish:
      operationId: subscribeHeartbeat
      summary: Subscribe / unsubscribe to heartbeats.
      message:
        $ref: '#/components/messages/ExchangeSubscribeAction'
    subscribe:
      operationId: receiveHeartbeat
      summary: Receive periodic heartbeat updates.
      message:
        oneOf:
          - $ref: '#/components/messages/ExchangeAdminEvent'
          - $ref: '#/components/messages/ExchangeHeartbeatUpdate'

  /mercury-gateway/v1/ws#l2:
    description: |
      Level 2 (price-aggregated) order book per symbol. Each entry has price (`px`),
      aggregated quantity (`qty`), and order count (`num`). Updates with `qty:0` indicate the
      price level should be removed.
    servers:
      - exchange
    publish:
      operationId: subscribeL2
      summary: Subscribe / unsubscribe to L2 order book updates for a symbol.
      message:
        $ref: '#/components/messages/ExchangeSubscribeSymbolAction'
    subscribe:
      operationId: receiveL2
      summary: Receive L2 snapshot and incremental updates.
      message:
        oneOf:
          - $ref: '#/components/messages/ExchangeAdminEvent'
          - $ref: '#/components/messages/ExchangeL2Event'

  /mercury-gateway/v1/ws#l3:
    description: |
      Level 3 (order-by-order) book per symbol. Each entry has order `id`, `px`, and `qty`.
      Updates with `qty:0` indicate the order should be removed.
    servers:
      - exchange
    publish:
      operationId: subscribeL3
      summary: Subscribe / unsubscribe to L3 order book updates for a symbol.
      message:
        $ref: '#/components/messages/ExchangeSubscribeSymbolAction'
    subscribe:
      operationId: receiveL3
      summary: Receive L3 snapshot and incremental updates.
      message:
        oneOf:
          - $ref: '#/components/messages/ExchangeAdminEvent'
          - $ref: '#/components/messages/ExchangeL3Event'

  /mercury-gateway/v1/ws#prices:
    description: |
      Candlestick (OHLCV) market data per symbol. Subscriptions require `granularity`
      in seconds; supported values are 60, 300, 900, 3600, 21600, 86400. Updates contain a
      `price` array: [timestamp, open, high, low, close, volume].
    servers:
      - exchange
    publish:
      operationId: subscribePrices
      summary: Subscribe / unsubscribe to candlestick updates.
      message:
        $ref: '#/components/messages/ExchangeSubscribePricesAction'
    subscribe:
      operationId: receivePrices
      summary: Receive OHLCV candle updates.
      message:
        oneOf:
          - $ref: '#/components/messages/ExchangeAdminEvent'
          - $ref: '#/components/messages/ExchangePricesUpdate'

  /mercury-gateway/v1/ws#symbols:
    description: |
      Symbol reference data: a snapshot of all trading symbols with their currency, scale, order size
      limits, status (open / close / suspend / halt / halt-freeze), and any auction details. Subsequent
      updates are sent when a symbol's status changes.
    servers:
      - exchange
    publish:
      operationId: subscribeSymbols
      summary: Subscribe / unsubscribe to symbol status updates.
      message:
        $ref: '#/components/messages/ExchangeSubscribeAction'
    subscribe:
      operationId: receiveSymbols
      summary: Receive symbol snapshot and status updates.
      message:
        oneOf:
          - $ref: '#/components/messages/ExchangeAdminEvent'
          - $ref: '#/components/messages/ExchangeSymbolsSnapshot'
          - $ref: '#/components/messages/ExchangeSymbolUpdate'

  /mercury-gateway/v1/ws#ticker:
    description: |
      Ticker snapshot for a symbol: 24-hour reference price, 24-hour volume, and last trade price.
    servers:
      - exchange
    publish:
      operationId: subscribeTicker
      summary: Subscribe / unsubscribe to ticker updates for a symbol.
      message:
        $ref: '#/components/messages/ExchangeSubscribeSymbolAction'
    subscribe:
      operationId: receiveTicker
      summary: Receive ticker snapshot and updates.
      message:
        oneOf:
          - $ref: '#/components/messages/ExchangeAdminEvent'
          - $ref: '#/components/messages/ExchangeTickerSnapshot'

  /mercury-gateway/v1/ws#trades:
    description: |
      Per-symbol stream of executed trades on the Exchange, including side, size, price, and
      `trade_id`.
    servers:
      - exchange
    publish:
      operationId: subscribeTrades
      summary: Subscribe / unsubscribe to trade execution updates for a symbol.
      message:
        $ref: '#/components/messages/ExchangeSubscribeSymbolAction'
    subscribe:
      operationId: receiveTrades
      summary: Receive trade execution updates.
      message:
        oneOf:
          - $ref: '#/components/messages/ExchangeAdminEvent'
          - $ref: '#/components/messages/ExchangeTradeUpdate'

  # ---------------------------------------------------------------------------
  # EXCHANGE — AUTHENTICATED CHANNELS
  # ---------------------------------------------------------------------------

  /mercury-gateway/v1/ws#auth:
    description: |
      Authenticates the WebSocket connection using an API secret as `token`. As an alternative,
      a connection may set the `auth_token` cookie header at handshake time, in which case
      authentication happens automatically without sending this message.
    servers:
      - exchange
    publish:
      operationId: subscribeAuth
      summary: Submit credentials to authenticate the connection.
      message:
        $ref: '#/components/messages/ExchangeAuthSubscribe'
    subscribe:
      operationId: receiveAuth
      summary: Authentication result.
      message:
        oneOf:
          - $ref: '#/components/messages/ExchangeAuthSubscribed'
          - $ref: '#/components/messages/ExchangeAuthRejected'

  /mercury-gateway/v1/ws#balances:
    description: |
      Authenticated channel that emits a `snapshot` of the user's balances on initial subscription
      and again on every balance change. Zero balances are omitted from the initial snapshot.
    servers:
      - exchange
    publish:
      operationId: subscribeBalances
      summary: Subscribe / unsubscribe to balance snapshots.
      message:
        $ref: '#/components/messages/ExchangeSubscribeAction'
    subscribe:
      operationId: receiveBalances
      summary: Receive user balance snapshots.
      message:
        oneOf:
          - $ref: '#/components/messages/ExchangeAdminEvent'
          - $ref: '#/components/messages/ExchangeBalancesSnapshot'

  /mercury-gateway/v1/ws#trading:
    description: |
      Authenticated trading channel. Subscribers receive an initial snapshot of live orders and
      execution-report updates thereafter. The channel supports the following actions:
      `NewOrderSingle`, `CancelOrderRequest`, `OrderMassCancelRequest`, `OrderMassStatusRequest`.
      Subscribing with `cancelOnDisconnect: true` causes all live orders to be cancelled if the
      connection drops; the flag cannot be turned off once enabled. Order messages use FIX 4.2 field
      names.
    servers:
      - exchange
    publish:
      operationId: tradingActions
      summary: Subscribe to or interact with the trading channel.
      message:
        oneOf:
          - $ref: '#/components/messages/ExchangeTradingSubscribe'
          - $ref: '#/components/messages/ExchangeNewOrderSingle'
          - $ref: '#/components/messages/ExchangeCancelOrderRequest'
          - $ref: '#/components/messages/ExchangeOrderMassCancelRequest'
          - $ref: '#/components/messages/ExchangeOrderMassStatusRequest'
    subscribe:
      operationId: receiveTrading
      summary: Receive order snapshots, execution reports and admin events.
      message:
        oneOf:
          - $ref: '#/components/messages/ExchangeAdminEvent'
          - $ref: '#/components/messages/ExchangeTradingSnapshot'
          - $ref: '#/components/messages/ExchangeExecutionReport'
          - $ref: '#/components/messages/ExchangeTradingRejected'

components:
  messages:

    # ---- Bitcoin / blockchain.info messages ----

    BitcoinOpPing:
      name: BitcoinOpPing
      title: Generic ping
      payload:
        type: object
        required: [op]
        properties:
          op:
            type: string
            const: ping
      examples:
        - payload: { op: ping }

    BitcoinOpPingTx:
      name: BitcoinOpPingTx
      title: Ping for latest transaction
      payload:
        type: object
        required: [op]
        properties:
          op:
            type: string
            const: ping_tx
      examples:
        - payload: { op: ping_tx }

    BitcoinOpPingBlock:
      name: BitcoinOpPingBlock
      title: Ping for latest block
      payload:
        type: object
        required: [op]
        properties:
          op:
            type: string
            const: ping_block
      examples:
        - payload: { op: ping_block }

    BitcoinOpUnconfirmedSub:
      name: BitcoinOpUnconfirmedSub
      title: Subscribe to unconfirmed transactions
      payload:
        type: object
        required: [op]
        properties:
          op:
            type: string
            const: unconfirmed_sub
      examples:
        - payload: { op: unconfirmed_sub }

    BitcoinOpUnconfirmedUnsub:
      name: BitcoinOpUnconfirmedUnsub
      title: Unsubscribe from unconfirmed transactions
      payload:
        type: object
        required: [op]
        properties:
          op:
            type: string
            const: unconfirmed_unsub
      examples:
        - payload: { op: unconfirmed_unsub }

    BitcoinOpBlocksSub:
      name: BitcoinOpBlocksSub
      title: Subscribe to new blocks
      payload:
        type: object
        required: [op]
        properties:
          op:
            type: string
            const: blocks_sub
      examples:
        - payload: { op: blocks_sub }

    BitcoinOpBlocksUnsub:
      name: BitcoinOpBlocksUnsub
      title: Unsubscribe from new blocks
      payload:
        type: object
        required: [op]
        properties:
          op:
            type: string
            const: blocks_unsub
      examples:
        - payload: { op: blocks_unsub }

    BitcoinOpAddrSub:
      name: BitcoinOpAddrSub
      title: Subscribe to address activity
      payload:
        type: object
        required: [op, addr]
        properties:
          op:
            type: string
            const: addr_sub
          addr:
            type: string
            description: Bitcoin address to watch.
      examples:
        - payload:
            op: addr_sub
            addr: 1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa

    BitcoinOpAddrUnsub:
      name: BitcoinOpAddrUnsub
      title: Unsubscribe from address activity
      payload:
        type: object
        required: [op, addr]
        properties:
          op:
            type: string
            const: addr_unsub
          addr:
            type: string

    BitcoinOpOpReturnSub:
      name: BitcoinOpOpReturnSub
      title: Subscribe to OP_RETURN transactions
      payload:
        type: object
        required: [op]
        properties:
          op:
            type: string
            const: op_return_sub
      examples:
        - payload: { op: op_return_sub }

    BitcoinUtxMessage:
      name: BitcoinUtxMessage
      title: Unconfirmed transaction (utx)
      payload:
        type: object
        properties:
          op:
            type: string
            const: utx
          x:
            type: object
            properties:
              lock_time: { type: integer }
              ver: { type: integer }
              size: { type: integer }
              inputs:
                type: array
                items:
                  type: object
                  properties:
                    sequence: { type: integer }
                    prev_out:
                      type: object
                      properties:
                        spent: { type: boolean }
                        tx_index: { type: integer }
                        type: { type: integer }
                        addr: { type: string }
                        value: { type: integer, description: Value in satoshis. }
                        n: { type: integer }
                        script: { type: string }
                    script: { type: string }
              time: { type: integer, description: Seen-by-relay Unix timestamp. }
              tx_index: { type: integer }
              vin_sz: { type: integer }
              hash: { type: string }
              vout_sz: { type: integer }
              relayed_by: { type: string }
              out:
                type: array
                items:
                  type: object
                  properties:
                    spent: { type: boolean }
                    tx_index: { type: integer }
                    type: { type: integer }
                    addr: { type: string }
                    value: { type: integer }
                    n: { type: integer }
                    script: { type: string }

    BitcoinBlockMessage:
      name: BitcoinBlockMessage
      title: New Bitcoin block
      payload:
        type: object
        properties:
          op:
            type: string
            const: block
          x:
            type: object
            properties:
              txIndexes:
                type: array
                items: { type: integer }
              nTx: { type: integer }
              totalBTCSent: { type: integer, description: Total BTC moved, in satoshis. }
              estimatedBTCSent: { type: integer }
              reward: { type: integer }
              size: { type: integer }
              blockIndex: { type: integer }
              prevBlockIndex: { type: integer }
              height: { type: integer }
              hash: { type: string }
              mrklRoot: { type: string }
              version: { type: integer }
              time: { type: integer }
              bits: { type: integer }
              nonce: { type: integer }

    # ---- Exchange — request / admin shared messages ----

    ExchangeSubscribeAction:
      name: ExchangeSubscribeAction
      title: Generic subscribe / unsubscribe (no symbol)
      payload:
        type: object
        required: [action, channel]
        properties:
          action:
            type: string
            enum: [subscribe, unsubscribe]
          channel:
            type: string
            enum: [heartbeat, symbols, balances]
      examples:
        - payload: { action: subscribe, channel: heartbeat }

    ExchangeSubscribeSymbolAction:
      name: ExchangeSubscribeSymbolAction
      title: Subscribe / unsubscribe to a per-symbol channel
      payload:
        type: object
        required: [action, channel, symbol]
        properties:
          action:
            type: string
            enum: [subscribe, unsubscribe]
          channel:
            type: string
            enum: [l2, l3, ticker, trades]
          symbol:
            type: string
            description: Exchange symbol identifier, e.g. "BTC-USD".
      examples:
        - payload: { action: subscribe, channel: l2, symbol: BTC-USD }

    ExchangeSubscribePricesAction:
      name: ExchangeSubscribePricesAction
      title: Subscribe / unsubscribe to the prices channel
      payload:
        type: object
        required: [action, channel, symbol, granularity]
        properties:
          action:
            type: string
            enum: [subscribe, unsubscribe]
          channel:
            type: string
            const: prices
          symbol:
            type: string
          granularity:
            type: integer
            enum: [60, 300, 900, 3600, 21600, 86400]
            description: Candle bucket size in seconds.
      examples:
        - payload: { action: subscribe, channel: prices, symbol: BTC-USD, granularity: 60 }

    ExchangeAdminEvent:
      name: ExchangeAdminEvent
      title: Subscription admin event (subscribed / unsubscribed / rejected)
      payload:
        type: object
        required: [seqnum, event, channel]
        properties:
          seqnum: { type: integer }
          event:
            type: string
            enum: [subscribed, unsubscribed, rejected]
          channel: { type: string }
          symbol: { type: string }
          text:
            type: string
            description: "Reason text (provided when `event: rejected`)."
      examples:
        - payload: { seqnum: 0, event: subscribed, channel: heartbeat }
        - payload: { event: rejected, text: "Connection throttling enabled, your messages will be ignored." }

    # ---- Exchange — anonymous channel responses ----

    ExchangeHeartbeatUpdate:
      name: ExchangeHeartbeatUpdate
      title: Heartbeat update (every 5 seconds)
      payload:
        type: object
        required: [seqnum, event, channel, timestamp]
        properties:
          seqnum: { type: integer }
          event:
            type: string
            const: updated
          channel:
            type: string
            const: heartbeat
          timestamp:
            type: string
            format: date-time
      examples:
        - payload:
            seqnum: 1
            event: updated
            channel: heartbeat
            timestamp: "2019-05-31T08:36:45.666753Z"

    ExchangeL2Event:
      name: ExchangeL2Event
      title: L2 order book snapshot / update
      payload:
        type: object
        required: [seqnum, event, channel, symbol, bids, asks]
        properties:
          seqnum: { type: integer }
          event:
            type: string
            enum: [snapshot, updated]
          channel:
            type: string
            const: l2
          symbol: { type: string }
          bids:
            type: array
            items:
              type: object
              required: [px, qty, num]
              properties:
                px: { type: number }
                qty: { type: number, description: "Aggregated size at this price. 0 means remove level." }
                num: { type: integer, description: Number of orders at this price level. }
          asks:
            type: array
            items:
              type: object
              required: [px, qty, num]
              properties:
                px: { type: number }
                qty: { type: number }
                num: { type: integer }
      examples:
        - payload:
            seqnum: 2
            event: snapshot
            channel: l2
            symbol: BTC-USD
            bids: [{ px: 8723.45, qty: 1.45, num: 2 }]
            asks: [{ px: 8730.0, qty: 1.55, num: 2 }]

    ExchangeL3Event:
      name: ExchangeL3Event
      title: L3 order book snapshot / update
      payload:
        type: object
        required: [seqnum, event, channel, symbol, bids, asks]
        properties:
          seqnum: { type: integer }
          event:
            type: string
            enum: [snapshot, updated]
          channel:
            type: string
            const: l3
          symbol: { type: string }
          bids:
            type: array
            items:
              type: object
              required: [id, px, qty]
              properties:
                id: { type: string, description: Exchange order id. }
                px: { type: number }
                qty: { type: number, description: "Order size. 0 means remove the order." }
          asks:
            type: array
            items:
              type: object
              required: [id, px, qty]
              properties:
                id: { type: string }
                px: { type: number }
                qty: { type: number }

    ExchangePricesUpdate:
      name: ExchangePricesUpdate
      title: Candlestick update
      payload:
        type: object
        required: [seqnum, event, channel, symbol, price]
        properties:
          seqnum: { type: integer }
          event:
            type: string
            const: updated
          channel:
            type: string
            const: prices
          symbol: { type: string }
          price:
            type: array
            description: "[timestamp, open, high, low, close, volume]"
            minItems: 6
            maxItems: 6
            items: { type: number }
      examples:
        - payload:
            seqnum: 2
            event: updated
            channel: prices
            symbol: BTC-USD
            price: [1559039640, 8697.24, 8700.98, 8697.27, 8700.98, 0.431]

    ExchangeSymbolsSnapshot:
      name: ExchangeSymbolsSnapshot
      title: Symbols snapshot
      payload:
        type: object
        required: [seqnum, event, channel, symbols]
        properties:
          seqnum: { type: integer }
          event:
            type: string
            const: snapshot
          channel:
            type: string
            const: symbols
          symbols:
            type: object
            additionalProperties:
              type: object
              properties:
                base_currency: { type: string }
                base_currency_scale: { type: integer }
                counter_currency: { type: string }
                counter_currency_scale: { type: integer }
                min_price_increment: { type: integer }
                min_price_increment_scale: { type: integer }
                min_order_size: { type: integer }
                min_order_size_scale: { type: integer }
                max_order_size: { type: integer }
                max_order_size_scale: { type: integer }
                lot_size: { type: integer }
                lot_size_scale: { type: integer }
                status:
                  type: string
                  enum: [open, close, closed, suspend, halt, halt-freeze]
                id: { type: integer }
                auction_price: { type: number }
                auction_size: { type: number }
                auction_time: { type: string }
                imbalance: { type: number }

    ExchangeSymbolUpdate:
      name: ExchangeSymbolUpdate
      title: Symbol status update
      payload:
        type: object
        required: [seqnum, event, channel, symbol, status]
        properties:
          seqnum: { type: integer }
          event:
            type: string
            const: updated
          channel:
            type: string
            const: symbols
          symbol: { type: string }
          auction-price: { type: number }
          auction-size: { type: number }
          auction-time:
            type: string
            description: Opening time in HHMM format when symbol is halted.
          imbalance: { type: number }
          status:
            type: string
            enum: [open, close, closed, suspend, halt, halt-freeze]
      examples:
        - payload:
            seqnum: 1
            event: updated
            channel: symbols
            symbol: BTC-USD
            auction-price: 4500.5
            auction-size: 220.125
            auction-time: "2230"
            imbalance: -0.5
            status: halt

    ExchangeTickerSnapshot:
      name: ExchangeTickerSnapshot
      title: Ticker snapshot
      payload:
        type: object
        required: [seqnum, event, channel, symbol]
        properties:
          seqnum: { type: integer }
          event:
            type: string
            const: snapshot
          channel:
            type: string
            const: ticker
          symbol: { type: string }
          price_24h: { type: number }
          volume_24h: { type: number }
          last_trade_price: { type: number }
      examples:
        - payload:
            seqnum: 8
            event: snapshot
            channel: ticker
            symbol: BTC-USD
            price_24h: 4988.0
            volume_24h: 0.3015
            last_trade_price: 5000.0

    ExchangeTradeUpdate:
      name: ExchangeTradeUpdate
      title: Trade execution update
      payload:
        type: object
        required: [seqnum, event, channel, symbol, timestamp, side, qty, price, trade_id]
        properties:
          seqnum: { type: integer }
          event:
            type: string
            const: updated
          channel:
            type: string
            const: trades
          symbol: { type: string }
          timestamp:
            type: string
            format: date-time
          side:
            type: string
            enum: [buy, sell]
          qty: { type: number }
          price: { type: number }
          trade_id: { type: string }
      examples:
        - payload:
            seqnum: 21
            event: updated
            channel: trades
            symbol: BTC-USD
            timestamp: "2019-08-13T11:30:06.100140Z"
            side: sell
            qty: 0.000085
            price: 11252.4
            trade_id: "12884909920"

    # ---- Exchange — authenticated channels ----

    ExchangeAuthSubscribe:
      name: ExchangeAuthSubscribe
      title: Authenticate the connection
      payload:
        type: object
        required: [token, action, channel]
        properties:
          token:
            type: string
            description: API secret token.
          action:
            type: string
            const: subscribe
          channel:
            type: string
            const: auth
      examples:
        - payload: { token: "{API_SECRET}", action: subscribe, channel: auth }

    ExchangeAuthSubscribed:
      name: ExchangeAuthSubscribed
      title: Authentication accepted
      payload:
        type: object
        required: [seqnum, event, channel]
        properties:
          seqnum: { type: integer }
          event:
            type: string
            const: subscribed
          channel:
            type: string
            const: auth
          readOnly: { type: boolean }
      examples:
        - payload: { seqnum: 0, event: subscribed, channel: auth, readOnly: false }

    ExchangeAuthRejected:
      name: ExchangeAuthRejected
      title: Authentication failed
      payload:
        type: object
        required: [seqnum, event, channel, text]
        properties:
          seqnum: { type: integer }
          event:
            type: string
            const: rejected
          channel:
   

# --- truncated at 32 KB (43 KB total) ---
# Full source: https://raw.githubusercontent.com/api-evangelist/blockchain/refs/heads/main/asyncapi/blockchain-com-asyncapi.yml