Ir diretamente para o conteúdo principal

L4 Book Updates Dataset

Atualizado em
Jun 10, 2026

Visão geral

O StreamL4BookUpdates stream delivers typed order-level book changes as NEW, UPDATE, e 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

Como funciona

  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 dados 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

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

Coin Naming

O 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 meta ou spotMeta info endpoints.

Response Fields

L4BookUpdatesUpdate

CampoTipoDescription
tempouint64Block timestamp in milliseconds
alturauint64Block 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

CampoTipoDescription
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)
moedacadeia de caracteresSymbol (e.g., "BTC", "ETH")
oiduint64Unique order ID
usercadeia de caracteresEthereum address of the order owner
ladocadeia de caracteres"A" (Ask/Sell) or "B" (Bid/Buy)
pxcadeia de caracteresOrder price as a decimal string
szcadeia de caracteresNew/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

FeatureStreamL4BookUpdatesStreamL4BookBOOK_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 bootstrapNoNoSim
Coins per streamMultiple (or all coins)One coin per streamFilterable
Per-order detailsUser, oid, side, px, szUser, oid, triggers, timestamps, tifUser, oid, size
Ideal paraPer-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 moeda, user, lado, 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.)
Partilhar este documento