Streams referenceQuickNode-compatible

Raw book diffs

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

The lowest-level book surface: every change to every order book, as it happened. Pair with a snapshot to reconstruct the exact book state at any block; the basis of queue-position and microstructure research. Over 1B book updates archived so far.

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.

Fields typed string that carry numbers are byte-exact decimal strings, verbatim from the node. Compare and store them as strings or arbitrary-precision decimals. Never parseFloat a price you intend to reconcile.

Server-side filters

  • coins[]
  • replay from a block height

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. Apply deltas to a snapshot (from StreamL4Book or the historical archive) for exact reconstruction.

  • 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 the exact book at any block

Snapshot once, then fold deltas forward to your target height. The result is byte-exact: the same px and sz strings the node emitted.

book = load_l4_snapshot("BTC")  # from StreamL4Book or the archive 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