L4 Order Book
Use L4 streams when you need a full order-level snapshot first, then live diffs.
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())