Real-time orderbook updates for perpetual markets.
Channel: orderbook
Authentication: Not required
Subscribe
{
"method": "subscribe",
"params": {
"channel": "orderbook",
"market_ids": [1, 2]
}
}| Parameter | Type | Required | Description |
|---|---|---|---|
market_ids | number[] | No | Filter by market IDs. Empty = all markets |
Message Format
Snapshot
Sent immediately after subscribing. Contains the full orderbook state.
{
"method": "snapshot",
"channel": "orderbook",
"type": "snapshot",
"market_id": "1",
"data": {
"market_id": 1,
"bids": [
{
"price": "50000000000000000000000",
"quantity": "1000000000000000000",
"order_count": 3,
"block_number": 12345678,
"log_index": 0
},
{
"price": "49900000000000000000000",
"quantity": "2500000000000000000",
"order_count": 5,
"block_number": 12345670,
"log_index": 2
}
],
"asks": [
{
"price": "50100000000000000000000",
"quantity": "800000000000000000",
"order_count": 2,
"block_number": 12345675,
"log_index": 1
},
{
"price": "50200000000000000000000",
"quantity": "1200000000000000000",
"order_count": 4,
"block_number": 12345672,
"log_index": 0
}
]
},
"level_count": 4,
"timestamp": "1703123456123456789"
}Update
Sent when the orderbook changes. Contains only the modified price levels.
{
"channel": "orderbook",
"type": "update",
"market_id": "1",
"data": {
"market_id": 1,
"bids": [
{
"price": "50000000000000000000000",
"quantity": "1500000000000000000",
"order_count": 4,
"block_number": 12345679,
"log_index": 1
}
],
"asks": []
},
"checksum": 3947812456,
"block_number": 12345679,
"log_index": 1,
"tx_hash": "0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef",
"block_timestamp": "1703123457000000000",
"timestamp": "1703123457123456789"
}Level Deletion
When a price level is removed, it is sent with quantity: "0":
{
"channel": "orderbook",
"type": "update",
"market_id": "1",
"data": {
"market_id": 1,
"bids": [
{
"price": "49900000000000000000000",
"quantity": "0",
"order_count": 0,
"block_number": 12345680,
"log_index": 2
}
],
"asks": []
},
"checksum": 1234567890,
"block_number": 12345680,
"log_index": 2,
"tx_hash": "0xabcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890",
"block_timestamp": "1703123458000000000",
"timestamp": "1703123458123456789"
}Data Fields
Snapshot Message Fields
| Field | Type | Description |
|---|---|---|
method | string | Always "snapshot" |
channel | string | Always "orderbook" |
type | string | Always "snapshot" |
market_id | string | Market ID |
data | object | Contains market_id, bids, and asks arrays |
level_count | number | Total number of price levels |
timestamp | string | Server timestamp (nanoseconds) |
Update Message Fields
| Field | Type | Description |
|---|---|---|
channel | string | Always "orderbook" |
type | string | Always "update" |
market_id | string | Market ID |
data | object | Contains market_id, bids, and asks arrays |
checksum | number | CRC32 checksum for validation |
block_number | number | Blockchain block number |
log_index | number | Log index within the block |
tx_hash | string | Transaction hash |
block_timestamp | string | Blockchain timestamp (nanoseconds) |
timestamp | string | Server timestamp (nanoseconds) |
Snapshot Level Object
| Field | Type | Description |
|---|---|---|
price | string | Price level (wei, 18 decimals) |
quantity | string | Total quantity at this price (wei, 18 decimals) |
order_count | number | Number of orders at this price level |
block_number | number | Block number when this level was last updated |
log_index | number | Log index within the block |
Update Level Object
| Field | Type | Description |
|---|---|---|
price | string | Price level (wei, 18 decimals) |
quantity | string | Total quantity at this price (wei, 18 decimals). "0" indicates deletion |
order_count | number | Number of orders at this price level |
block_number | number | Block number when this level was last updated |
log_index | number | Log index within the block |
Ordering
- Bids: Sorted descending by price (highest first)
- Asks: Sorted ascending by price (lowest first)
CRC32 Checksum
The checksum allows you to verify orderbook integrity. If your local orderbook state doesn't match the checksum, you should resubscribe to get a fresh snapshot.
Algorithm
The checksum is computed using CRC32-IEEE on an interleaved string of bid and ask levels:
bid_price:bid_quantity:ask_price:ask_quantity:bid_price:bid_quantity:ask_price:ask_quantity:...
Computation Steps
- Sort bids descending by price (highest first)
- Sort asks ascending by price (lowest first)
- Interleave levels:
bids[0], asks[0], bids[1], asks[1], ... - Build string:
price:quantity:price:quantity:... - Compute CRC32-IEEE checksum
Python Implementation
import binascii
def compute_checksum(bids, asks):
parts = []
max_len = max(len(bids), len(asks))
for i in range(max_len):
if i < len(bids):
parts.append(bids[i]['price'])
parts.append(bids[i]['quantity'])
if i < len(asks):
parts.append(asks[i]['price'])
parts.append(asks[i]['quantity'])
s = ':'.join(parts)
return binascii.crc32(s.encode()) & 0xffffffffChecksum Mismatch
If your computed checksum doesn't match the received checksum:
- Your local orderbook state may be corrupted
- Unsubscribe and resubscribe to get a fresh snapshot
- Check your update application logic
Examples
Subscribe to all markets
{
"method": "subscribe",
"params": {
"channel": "orderbook"
}
}Subscribe to specific markets
{
"method": "subscribe",
"params": {
"channel": "orderbook",
"market_ids": [1, 2]
}
}Subscribe to single market
{
"method": "subscribe",
"params": {
"channel": "orderbook",
"market_ids": [1]
}
}Unsubscribe
{
"method": "unsubscribe",
"params": {
"channel": "orderbook"
}
}Notes
Throttling
Updates are throttled to a maximum of 4 updates per second per market (250ms bucket). This prevents overwhelming clients with rapid-fire updates during high-volume trading.
Catchup Skip
If the block age is greater than 30 seconds, broadcasts may be skipped to allow the system to catch up with the blockchain.