Présentation générale
Le StreamL2BookDiff stream delivers incremental L2 price-level changes for one or more coins instead of full snapshots. Each message contains only the levels that changed since the previous block, allowing clients to maintain a local L2 order book efficiently with far less bandwidth than full snapshots.
gRPC : OrderBookStreaming
gRPC : StreamL2BookDiff
Modèle de mise à jour : Initial per-coin snapshot (optional), then incremental diffs per block with sequence numbers
Comment ça marche ?
- Lors de l'inscription : Unless
skip_initial_snapshotis set, the first update for each coin contains the current price levels as a snapshot (snapshot: trueon the message and the per-coin diff) - Par bloc supplémentaire : Each
L2BookDiffUpdatecontains only the price levels that changed. A level withsz: "0"means the level was removed - Apply diffs to your local copy of the book, using
seq/prev_seqto verify continuity: each coin's diff carries a sequence number, andprev_seqshould match theseqof the previous diff you applied for that coin
A single stream can cover multiple coins (or all coins with an empty coins list). The maximum tracked depth per side defaults to 20 levels, matching StreamL2Book, and the same price-bucketing parameters (n_sig_figs, mantissa) are supported.
Structure de données
Initial snapshot (first message per coin)
{
"time": 1781109048255,
"height": 586404776,
"snapshot": true,
"diffs": [
{
"coin": "BTC",
"seq": 1,
"snapshot": true,
"bids": [
{ "px": "62963", "sz": "0.00072", "n": 2 },
{ "px": "62959", "sz": "0.001", "n": 1 }
],
"asks": [
{ "px": "63054", "sz": "0.00008", "n": 1 },
{ "px": "63082", "sz": "0.00035", "n": 1 }
]
}
]
}
Diff (messages suivants)
{
"time": 1781109048660,
"height": 586404778,
"diffs": [
{
"coin": "BTC",
"seq": 2,
"prev_seq": 1,
"asks": [
{ "px": "63168", "sz": "0.00001", "n": 1 },
{ "px": "63210", "sz": "0" }
]
}
]
}
A level with sz: "0" has been removed from the book; any other level value replaces the previous state at that price.
Paramètres de requête
| Champ | Type | Obligatoire | Description |
|---|---|---|---|
| coins | repeated string | Non | List of symbols to subscribe to (e.g., "BTC", "ETH"). Empty means all coins |
| n_niveaux | uint32 | Oui | Maximum number of price levels tracked per side (default 20, max 100) |
| n_sig_figs | uint32 | Non | Significant figures for price bucketing (2–5). Omit for exact price-level aggregation. |
| mantissa | uint64 | Non | Mantissa for price bucketing (1, 2, or 5). Used with n_sig_figs to control bucket width. |
| skip_initial_snapshot | bool | Non | If false (default), the first update per coin contains the current levels as a snapshot |
Dénomination des pièces
Le coins Ce paramètre respecte la convention de nommage Hyperliquid, qui distingue sans ambiguïté les contrats à durée indéterminée des contrats au comptant :
- Titre perpétuel: Human-readable names, such as
« BTC »,« ETH »,« HYPE »,« SOL » - Jetons au comptant:
@{index}format, such as« @1 »,« @107 »,« @142 »,« @166 » - Marchés des résultats (HIP-4):
#Nformat. Chaque résultat comporte deux#Ncoins, 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 theoutcomeMetaendpoint mettre en correspondance les indices des cryptomonnaies avec les noms et les côtés du marché. - Exception:
« PURR/USDC »C'est la seule pièce de monnaie dont le nom est lisible.
Il n'y a pas de chevauchement entre les formats. « BTC » fait toujours référence au contrat à terme perpétuel sur BTC ; le BTC au comptant est « @142 ». Pour découvrir @index mappages pour les jetons ponctuels, interroger le méta ou spotMeta points de terminaison d'information.
Champs de réponse
L2BookDiffUpdate
| Champ | Type | Description |
|---|---|---|
| temps | uint64 | Horodatage du bloc en millisecondes |
| hauteur | uint64 | Hauteur du bloc |
| instantané | bool | True when this update carries the initial levels as a snapshot for any coin |
| diffs | L2CoinDiff[] | Per-coin diffs of changed price levels |
L2CoinDiff
| Champ | Type | Description |
|---|---|---|
| pièce de monnaie | chaîne de caractères | Symbole (par exemple, « BTC », « ETH ») |
| seq | uint64 | Per-coin sequence number of this diff |
| prev_seq | uint64 | Sequence number of the previous diff for this coin. Compare against the last applied seq to detect gaps |
| offres | L2Level[] | Changed bid levels. A level with sz "0" was removed |
| demande | L2Level[] | Changed ask levels. A level with sz "0" was removed |
| instantané | bool | True when this diff carries the initial levels for the coin as a snapshot |
L2Level
| Champ | Type | Description |
|---|---|---|
| px | chaîne de caractères | Price as a decimal string |
| sz | chaîne de caractères | Total size across all orders at this price level, as a decimal string. "0" means the level was removed |
| n | uint32 | Number of individual orders at this price level (0/omitted on removed levels) |
Définition de « proto »
StreamL2BookDiff est défini dans orderbook.proto:
service OrderBookStreaming {
rpc StreamL2BookDiff (L2BookDiffRequest) returns (stream L2BookDiffUpdate);
}
message L2BookDiffRequest {
repeated string coins = 1;
uint32 n_levels = 2;
optional uint32 n_sig_figs = 3;
optional uint64 mantissa = 4;
bool skip_initial_snapshot = 5;
}
message L2BookDiffUpdate {
uint64 time = 1;
uint64 height = 2;
bool snapshot = 3;
repeated L2CoinDiff diffs = 4;
}
message L2CoinDiff {
string coin = 1;
uint64 seq = 2;
uint64 prev_seq = 3;
repeated L2Level bids = 4;
repeated L2Level asks = 5;
bool snapshot = 6;
}
message L2Level {
string px = 1;
string sz = 2;
uint32 n = 3;
}
Exemples de mises à jour
Initial Snapshot (first message)
{
"time": 1781109048255,
"height": 586404776,
"snapshot": true,
"diffs": [
{
"coin": "BTC",
"seq": 1,
"snapshot": true,
"bids": [
{ "px": "62963", "sz": "0.00072", "n": 2 },
{ "px": "62959", "sz": "0.001", "n": 1 },
{ "px": "62955", "sz": "0.00015", "n": 1 },
{ "px": "62922", "sz": "0.00074", "n": 1 },
{ "px": "62892", "sz": "0.00035", "n": 1 }
],
"asks": [
{ "px": "63054", "sz": "0.00008", "n": 1 },
{ "px": "63082", "sz": "0.00035", "n": 1 },
{ "px": "63146", "sz": "0.00035", "n": 1 },
{ "px": "63187", "sz": "0.00074", "n": 1 },
{ "px": "63210", "sz": "0.00035", "n": 1 }
]
}
]
}
Incremental Diff (level added and level removed)
A level with sz: "0" means the level was removed:
{
"time": 1781109048660,
"height": 586404778,
"diffs": [
{
"coin": "BTC",
"seq": 2,
"prev_seq": 1,
"asks": [
{ "px": "63168", "sz": "0.00001", "n": 1 },
{ "px": "63210", "sz": "0" }
]
}
]
}
Level Size Change Only
{
"time": 1781109050268,
"height": 586404788,
"diffs": [
{ "coin": "BTC", "seq": 3, "prev_seq": 2,
"bids": [ { "px": "62963", "sz": "0.00052", "n": 2 } ] }
]
}
Quand skip_initial_snapshot is vrai, the first message is a plain diff (no instantané flags) with seq starting at 1.
Utilisation de l'API
gRPC
// Single coin
const request = {
coins: ['BTC'],
n_levels: 20
};
// Multiple coins with price bucketing
const bucketedRequest = {
coins: ['BTC', 'ETH'],
n_levels: 20,
n_sig_figs: 3,
mantissa: 1
};
// Diffs only, no initial snapshot
const diffOnlyRequest = {
coins: ['BTC'],
n_levels: 20,
skip_initial_snapshot: true
};
StreamL2BookDiff n'est disponible que via l'API gRPC (OrderBookStreaming service). Il n'est pas disponible via JSON-RPC ou WebSocket.
Comparison with StreamL2Book
| Fonctionnalité | StreamL2BookDiff | StreamL2Book |
|---|---|---|
| Data per message | Only changed price levels | Full snapshot every block |
| Includes current book state | Yes (initial per-coin snapshot) | Yes (every message) |
| Client-side state management | Apply diffs to local book, track seq | Aucun |
| Gap detection | seq / prev_seq per coin | Not needed |
| Coins per stream | Multiple (or all coins) | One coin per stream |
| Bande passante | Faible (différentielles uniquement) | Moyen (limité à n_levels) |
| Price bucketing | Supported (n_sig_figs, mantissa) | Supported (n_sig_figs, mantissa) |
| Idéal pour | Efficient local book maintenance at scale | Simplest depth consumption |
Remarques importantes
sz: "0"means removed: A changed level with size"0"(andn0/omitted) has been removed from the book. Delete it from your local state- Track sequence numbers: Verify
prev_seqmatches the lastseqyou applied per coin; on a gap, resubscribe to receive a fresh snapshot - Default depth matches StreamL2Book:
n_niveauxdefaults to 20 tracked levels per side (max 100) - Multi-coin in one stream: A single subscription can cover multiple coins (or all coins). Demultiplex by the
pièce de monnaiefield on each diff - zstd compression recommended: Enable zstd compression on your gRPC channel to reduce bandwidth, especially when streaming multiple coins
Streams associés
- StreamL2Book - Aggregated price-level depth, full snapshot every block
- StreamBboBook - Top-of-book best bid/ask, emitted only when the BBO changes
- Book Updates - Forward-only incremental diffs via StreamData