Skip to content
Alchemy Logo

Stream an L2 order book

Beta

HyperCore APIs are in beta. Message fields, limits, and behavior may change, including breaking changes. To request access, contact [email protected].

  • l2Book sends a complete window of levels for each market whenever it changes. No local state needed. Good for displays and periodic reads.
  • l2BookDiff sends a snapshot, then only changed levels. Much less data for the same book, but you maintain local state. See rebuild a book from diffs.

{"method":"subscribe","subscriptionId":"books","subscription":{"type":"l2Book","coins":["BTC","ETH","SOL"],"nLevels":20}}
  • List several markets in coins to receive them on one subscription. Each message contains only the markets that changed in that block.
  • Add nSigFigs (and optionally mantissa) to group prices. See price aggregation.
  • Omit coins to receive every market. This is a large stream; filter where you can.

function onMessage(msg) {
  if (msg.error && (msg.channel === "error" || msg.subscriptionId === "books")) {
    handleError(msg.error);         // see errors and limits
    return;
  }
  if (msg.subscriptionId !== "books" || msg.seq === undefined) return;  // other subscriptions, acks
  for (const { coin, levels: [bids, asks] } of msg.data.books) {
    display[coin] = { bids, asks, blockTime: msg.data.blockTime };
  }
}

handleError is yours. book_reset isn't a failure: the subscription stays open and the next message is a fresh snapshot that replaces each market's view, so keep listening. Retry book_not_ready after a short delay. For other codes, fix the request. See errors and limits.

Each entry replaces that market's view, so a missed message leaves a market stale only until it next changes. To avoid even that, track seq and resubscribe when it skips. After a disconnect, reconnect and subscribe again. The first message is a fresh snapshot of every subscribed market.

Was this page helpful?