Passer au contenu principal

L4 Book Updates Dataset

Mis à jour le
10 juin 2026

Aperçu

Le StreamL4BookUpdates stream delivers typed order-level book changes as NEW, UPDATE, et REMOVE diffs for one or more coins. It gives clients per-order L4 movement without consuming full L4 book snapshots every block, and without parsing JSON-encoded payloads: every diff is a strongly typed protobuf message.

gRPC Service: OrderBookStreaming
gRPC Method: StreamL4BookUpdates
Update Model: Full reset snapshot on subscribe, then typed per-order diffs per block

Comment ça marche ?

  1. On subscribe: The first message has snapshot: true and contains every resting order as a L4_ORDER_DIFF_TYPE_NEW diff, a full reset snapshot of the book
  2. Per block thereafter: Each L4BookUpdatesUpdate contains typed diffs for orders that changed: NEW (order entered the book), UPDATE (order size changed), REMOVE (order left the book, sz is omitted)
  3. Apply diffs to a local order map keyed by oid to maintain the current book

Unlike StreamL4Book, which sends diffs as a JSON-encoded données string, every field here is a typed protobuf field, so no secondary JSON parsing is required. A single stream can cover multiple coins (or all coins with an empty coins list).

Data Structure

Each L4BookUpdatesUpdate message contains the typed diffs for one block:

{
"time": 1781109115476,
"height": 586405189,
"diffs": [
{ "diff_type": "L4_ORDER_DIFF_TYPE_NEW", "coin": "ETH", "oid": 54764586686,
"user": "0x768484F7e2EBB675C57838366C02Ae99ba2A9B08", "side": "B", "px": "1649.1", "sz": "1.022" }
]
}

Request Parameters

ChampTypeRequiredDescription
coinsrepeated stringNonList of symbols to subscribe to (e.g., "BTC", "ETH"). Empty means all coins

Coin Naming

Le coins parameter follows Hyperliquid's naming convention, which unambiguously distinguishes perpetuals from spot:

  • Perpetuals: Human-readable names, such as "BTC", "ETH", "HYPE", "SOL"
  • Spot tokens: @{index} format, such as "@1", "@107", "@142", "@166"
  • Outcome markets (HIP-4): #N format. Each outcome has two #N coins, one per side (Yes and No). Multi-price question markets consist of multiple grouped outcomes (price buckets plus a fallback), each with its own Yes/No coin pair. Use the outcomeMeta endpoint to map coin indices to market names and sides.
  • Exception: "PURR/USDC" is the only spot coin with a readable name

There is no overlap between formats. "BTC" always refers to the BTC perpetual; spot BTC is "@142". To discover @index mappings for spot tokens, query the méta ou spotMeta info endpoints.

Response Fields

L4BookUpdatesUpdate

ChampTypeDescription
Heureuint64Block timestamp in milliseconds
Hauteuruint64Block height
snapshotboolTrue when the diffs carry a full reset snapshot of all resting orders (sent on subscribe)
diffsL4OrderDiff[]Typed per-order diffs for this block

L4OrderDiff

ChampTypeDescription
diff_typeL4OrderDiffTypeL4_ORDER_DIFF_TYPE_NEW (order entered the book), L4_ORDER_DIFF_TYPE_UPDATE (order size changed), or L4_ORDER_DIFF_TYPE_REMOVE (order left the book)
pièce de monnaiechaîne de caractèresSymbol (e.g., "BTC", "ETH")
oiduint64Unique order ID
utilisateurchaîne de caractèresEthereum address of the order owner
côtéchaîne de caractères"A" (Ask/Sell) or "B" (Bid/Buy)
pxchaîne de caractèresOrder price as a decimal string
szchaîne de caractèresNew/current order size for NEW and UPDATE diffs. Omitted on REMOVE

Proto Definition

StreamL4BookUpdates is defined in orderbook.proto:

service OrderBookStreaming {
rpc StreamL4BookUpdates (L4BookUpdatesRequest) returns (stream L4BookUpdatesUpdate);
}

message L4BookUpdatesRequest {
repeated string coins = 1;
}

enum L4OrderDiffType {
L4_ORDER_DIFF_TYPE_UNSPECIFIED = 0;
L4_ORDER_DIFF_TYPE_NEW = 1;
L4_ORDER_DIFF_TYPE_UPDATE = 2;
L4_ORDER_DIFF_TYPE_REMOVE = 3;
}

message L4BookUpdatesUpdate {
uint64 time = 1;
uint64 height = 2;
repeated L4OrderDiff diffs = 3;
bool snapshot = 4;
}

message L4OrderDiff {
L4OrderDiffType diff_type = 1;
string coin = 2;
uint64 oid = 3;
string user = 4;
string side = 5;
string px = 6;
string sz = 7;
}

Example Updates

Initial Snapshot (first message, truncated)

The first message has snapshot: true and contains every resting order as a NEW diff:

{
"time": 1781109063794,
"height": 586404872,
"snapshot": true,
"diffs": [
{ "diff_type": "L4_ORDER_DIFF_TYPE_NEW", "coin": "BTC", "oid": 54764492622,
"user": "0x039442e06b482Bf01A1a65742cf061bD73A80f31", "side": "B", "px": "62963", "sz": "0.00009" },
{ "diff_type": "L4_ORDER_DIFF_TYPE_NEW", "coin": "BTC", "oid": 54764537698,
"user": "0x3643290CD5DE72b37d2f10A351Ce57c30d103969", "side": "B", "px": "62963", "sz": "0.00024" },
{ "diff_type": "L4_ORDER_DIFF_TYPE_NEW", "coin": "BTC", "oid": 54764482173,
"user": "0x4547B9E33F07965711f67d0bE2423939A4E33aF5", "side": "B", "px": "62955", "sz": "0.00015" }
]
}
Per-Block Update with Removals

sz is omitted on REMOVE diffs:

{
"time": 1781109083796,
"height": 586404997,
"diffs": [
{ "diff_type": "L4_ORDER_DIFF_TYPE_REMOVE", "coin": "BTC", "oid": 54764554671,
"user": "0xc64cc00B46101bd40aA1C3121195E85c0B0918d8", "side": "B", "px": "62389.0" },
{ "diff_type": "L4_ORDER_DIFF_TYPE_REMOVE", "coin": "BTC", "oid": 54764557274,
"user": "0xc64cc00B46101bd40aA1C3121195E85c0B0918d8", "side": "B", "px": "62421.0" }
]
}
New Order and Size Update

A new order entering the book:

{
"time": 1781109115476,
"height": 586405189,
"diffs": [
{ "diff_type": "L4_ORDER_DIFF_TYPE_NEW", "coin": "ETH", "oid": 54764586686,
"user": "0x768484F7e2EBB675C57838366C02Ae99ba2A9B08", "side": "B", "px": "1649.1", "sz": "1.022" }
]
}

A size change on a resting order (sz is the new current size):

{ "diff_type": "L4_ORDER_DIFF_TYPE_UPDATE", "coin": "ETH", "oid": 54764551695,
"user": "0x4547B9E33F07965711f67d0bE2423939A4E33aF5", "side": "B", "px": "1702.9", "sz": "0.0032" }

API Usage

gRPC Streaming
// Single coin
const request = {
coins: ['BTC']
};

// Multiple coins in one stream
const multiRequest = {
coins: ['BTC', 'ETH']
};

// All coins
const allCoinsRequest = {
coins: []
};

gRPC Only

StreamL4BookUpdates is only available via the gRPC Streaming API (OrderBookStreaming service). It is not available through JSON-RPC or WebSocket.

Comparison: L4 Book Updates vs L4 Book vs Book Updates Dataset

FonctionnalitéStreamL4BookUpdatesStreamL4BookBOOK_UPDATES
GranularityIndividual orders, typed diffsIndividual ordersIndividual order-level diffs
Diff encodingTyped protobuf (NEW/UPDATE/REMOVE)JSON-encoded data stringJSON objects
Includes current stateYes (reset snapshot as NEW diffs)Yes (initial snapshot)No (forward-only)
Needs REST bootstrapNonNonOui
Coins per streamMultiple (or all coins)One coin per streamFilterable
Per-order detailsUser, oid, side, px, szUser, oid, triggers, timestamps, tifUser, oid, size
Idéal pourPer-order book tracking without JSON parsingFull order detail (triggers, tif, cloid)Customers who only need book updates

Important Notes


  • Reset snapshot on subscribe and reconnect: The first message has snapshot: true with all resting orders as NEW diffs. Clear any local state and rebuild from it
  • REMOVE omits sz: Remove diffs identify the order by oid (with pièce de monnaie, utilisateur, côté, px) but carry no size. Delete the order from your local map
  • Typed alternative to StreamL4Book: If you need trigger info, timestamps, tif, ou cloid per order, use StreamL4Book; if you need lean typed per-order movement, use this stream
  • zstd compression recommended: Enable zstd compression on your gRPC channel to reduce bandwidth, especially when streaming multiple coins

  • StreamL4Book - Full order book at order granularity with snapshot + JSON-encoded diffs
  • StreamL2BookDiff - Incremental L2 price-level changes with sequence numbers
  • Orders - Order lifecycle events (open, filled, canceled, etc.)
Partager ce document