L4 Order Book

Use L4 streams when you need a full order-level snapshot first, then live diffs.

Data
Snapshot and diffs
For
Order-level books
Tier
Higher-depth streaming

Channels

L4 orderbook streaming

L4 channels deliver a full snapshot first, then continuous diff batches so you can reconstruct the live order-level book.

Python
import websockets, json, asyncio
async def stream_l4():
uri = "wss://api.0xarchive.io/ws?apiKey=YOUR_KEY"
async with websockets.connect(uri, max_size=20_000_000) as ws:
# Subscribe to L4 diffs (works for l4_diffs or hip3_l4_diffs)
await ws.send(json.dumps({
"op": "subscribe",
"channel": "l4_diffs",
"symbol": "BTC"
}))
book = {"bids": {}, "asks": {}}
snapshot_ts = None
async for msg in ws:
data = json.loads(msg)
if data["type"] == "l4_snapshot":
# Full book delivered first (every order including triggers)
snapshot_ts = data["timestamp"]
for order in data["data"]["bids"]:
book["bids"][order["oid"]] = order
for order in data["data"]["asks"]:
book["asks"][order["oid"]] = order
print(f"Snapshot: {len(book['bids'])} bids, {len(book['asks'])} asks")
elif data["type"] == "l4_batch" and snapshot_ts is not None:
# Apply diffs to maintain the book
for diff in data["data"]:
if diff["ts"] <= snapshot_ts:
continue
side = "bids" if diff["side"] == "B" else "asks"
oid = diff["oid"]
if diff["dt"] == "new":
book[side][oid] = {
"oid": oid, "side": diff["side"],
"price": diff["px"], "size": diff["sz"],
"user_address": diff["user"]
}
elif diff["dt"] == "update":
if oid in book[side]:
book[side][oid]["size"] = diff["sz"]
elif diff["dt"] == "remove":
book[side].pop(oid, None)
asyncio.run(stream_l4())

Keep exploring WebSocket