Streams referenceQuickNode-compatible

Raw book diffs

Every order-book delta (new, update, modified, remove) for full reconstruction.

The lowest-level book surface: every captured change to every order book. Pair it with a compatible snapshot and apply deltas in order for queue-position and microstructure research within the data range you hold.

Method
hyperliquid.Streaming/StreamData (stream_type: BOOK_UPDATES)
Endpoint
stream.hyperliquidrpc.com:443 · gRPC over TLS (HTTP/2)
Auth
API key in x-api-key metadata
Volume
The highest-volume stream: every book change on every market. Filter by coin unless you genuinely need the firehose.

When to use it

This is the research-grade surface: every change to every order book, as it happened, in strict block order. Use it when the L4 book's per-coin subscriptions are the wrong shape: cross-market microstructure studies, building your own book-keeping engine with custom data structures, or recording the raw delta tape for later replay against strategies.

If you just want a correct live book for a handful of coins, the L4 stream does the snapshot bookkeeping for you and is the easier choice. Diffs alone are not a book; you must pair them with a snapshot to have state to apply them to.

Method

// stream.hyperliquidrpc.com:443 — gRPC over TLS (HTTP/2)// auth: API key in x-api-key metadata · server reflection enabledpackage hyperliquid; service Streaming {  // Bidirectional: send one subscription, then read updates.  // Subscribe with stream_type: BOOK_UPDATES.  rpc StreamData (stream SubscribeRequest) returns (stream SubscribeUpdate);}

QuickNode-compatible StreamData with stream_type: BOOK_UPDATES. Each update carries the block number and the delta payload as JSON.

Subscribe

# StreamData is bidirectional; grpcurl sends the subscription for you.grpcurl -H 'x-api-key: YOUR_KEY' \  -d '{"subscribe":{"stream_type":"BOOK_UPDATES","filters":{"coin":{"values":["BTC"]}}}}' \  stream.hyperliquidrpc.com:443 \  hyperliquid.Streaming/StreamData

Unfiltered, this is the highest-volume stream we serve, with over 1B book updates archived so far. Subscribe with a coin filter unless you genuinely need every market.

Message fields

FieldTypeDescription
update_typeenumNEW / UPDATE / MODIFIED / REMOVE.
coinstringMarket symbol.
oiduint64Order id the delta applies to.
userstringOwner's wallet address.
sidestringB (bid) or A (ask).
pxstringPrice of the affected order.Byte-exact decimal string.
szstringSize after the change (0 on remove).Byte-exact decimal string.
block_heightuint64Block the delta belongs to; apply in order.

Raw financial fields typed string preserve their decimal representation from the node. Store them as strings or arbitrary-precision decimals. Calculated fields, including aggregated book sizes, are identified by their field notes.

Server-side filters

  • coins[]
  • recent replay up to 6 hours

Filters are applied on the server, so filtered-out messages never leave our edge. You only pay for what you subscribe to. Request shapes for every stream family are on Filtering; backfill semantics on Replay & backfill.

Semantics & gotchas

Pure delta stream in strict block order. For recovery, replay from a checkpoint only when you retained the compatible prior book state; otherwise resubscribe to StreamL4Book for current state.

  • Deltas without a snapshot are not a book. Take an initial state from the L4 stream's snapshot (or the historical archive at a chosen block), then apply deltas with block_height greater than the snapshot's.
  • Apply strictly in block order. Deltas are emitted in order; if your pipeline buffers or shards, re-serialize by block_height before applying or the book silently diverges.
  • sz is the size after the change. MODIFIED/UPDATE carry the new remaining size, and removals leave sz at 0. Keep your apply logic to “set, don't add.”
  • Every delta is wallet-attributed. user on each change means placement and cancellation behavior is analyzable per firm, not just per price level.

Sample message

{  "block_height": 612408136,  "coin": "BTC",  "update_type": "MODIFIED",  "oid": 91834220771,  "user": "0x5d20af913cc01b76e4a8f20de33c197a40b8e641",  "side": "B",  "px": "67009.0",  "sz": "0.40000"}

The highest-volume stream: every book change on every market. Filter by coin unless you genuinely need the firehose.

Recipes

Reconstruct a book within the data range you hold

Start with a compatible snapshot, then fold captured deltas forward to a target height in your connected or recently replayed range. Raw px and sz values retain the decimal strings the node emitted.

book = load_l4_snapshot("BTC")  # from StreamL4Book for update in stub.StreamData(iter([subscribe]), metadata=meta):    d = json.loads(update.data.data)    if d["block_height"] <= book.height:        continue  # already inside the snapshot    apply_delta(book, d)  # set by oid; remove when update_type == "REMOVE"

Record the delta tape for offline replay

Append each JSON delta to date-partitioned files keyed by block_height. Strategies can then be replayed against the exact sequence of book states they would have observed, with no resampling artifacts.

Order-flow imbalance per block

Group deltas by block_height and net the added versus removed size per side. Spikes in one-sided cancellation ahead of price moves are visible only at this granularity.

Related