Blockchain

Bitcoin Payment, Wallet & Transaction Data

AsyncAPI Specification

blockchain-com-asyncapi.yml 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