Order Book
The live central limit order book for one instrument: aggregated resting bids and asks at each price. Read a snapshot with getOrderBook, then keep it current from the public:book socket stream.
A book is identified by an asset configuration and a graded/condition key — the same pair a submission targets. Optionally scope it to one market to see only the liquidity you can trade against on that venue.
Snapshot
query {
getOrderBook(input: {
assetConfigurationId: "315bc6db-3f16-49ec-b649-8be3b8753fb7"
keyId: "4a9a2cca-c05f-5474-9979-428dc6f41107"
levelsLimit: 10
}) {
bids { priceCents quantity numMakers restingSince isMine ownSubmissionIds }
asks { priceCents quantity numMakers restingSince isMine ownSubmissionIds }
summary { topBidCents topAskCents midCents bidUnits askUnits imbalancePercent }
sequence
serverNow
error { message }
}
}
Open to anonymous callers. Authenticated with an API key, the viewer's own levels are marked (isMine, ownQuantity, ownSubmissionIds) — that is the handle to amend or cancel from a book row.
GetOrderBookInput
| Field | Type | Description |
|---|---|---|
assetConfigurationId | ID! | The product |
keyId | ID | The graded/condition key. Omit for the consolidated book across every key of the product — useful for a glance, but it has no delta stream, so pass a key when you intend to subscribe |
marketId | ID | Scope to one venue's liquidity |
levelsLimit | Int | Cap the levels per side, best first |
OrderBookLevel
Bids are ordered best (highest) first, asks best (lowest) first.
| Field | Type | Description |
|---|---|---|
priceCents | Int! | Base price at this level, before fees |
quantity | Int | Units resting. Null when a maker at the level is uncapped |
minQuantity | Int | Smallest fill a maker at this level accepts |
numMakers | Int! | Distinct orders aggregated into the level |
restingSince | DateTime | When the oldest order still at this level was placed — how long the front of the queue has stood |
lastChangedAt | DateTime | When the level last changed size |
isMine | Boolean! | You have an order resting here. Always false anonymously |
ownQuantity | Int! | Your units at this level |
ownSubmissionIds | [UUID!]! | Your submission ids at this level — pass to updateOrderSubmission / cancelOrderSubmission |
OrderBookSummary
| Field | Type | Description |
|---|---|---|
topBidCents / topAskCents | Int | Best bid and ask; null on an empty side |
midCents | Int | Midpoint of the touch |
bidUnits / askUnits | Int! | Total units per side |
bidDepthCents / askDepthCents | Int! | Total notional per side |
imbalancePercent | Float | Bid share of total units, as a percentage |
The payload also carries priorityBids — service-level bids resting on the leaf, each its own row rather than a level. They are excluded from bids, the summary, and the delta stream; a seller takes one whole via priorityBidId.
Prices on the book are clean base prices. What you actually pay or receive is fee-adjusted — see Clean prices and all-in prices; getOrderQuote walks the same book and returns the all-in numbers.
Streaming
Subscribe to public:book:<assetConfigurationId>:<keyId> on the realtime socket. Each push is one level, as an absolute value after the change — not an increment:
{
"side": "BID",
"price": 1000,
"qty": 3,
"makers": 2,
"seq": 4812,
"action": "PLACED",
"restingSince": "2026-09-12T18:02:11.104Z",
"lastChangedAt": "2026-09-12T18:04:37.551Z",
"emittedAt": "2026-09-12T18:04:37.560Z"
}
| Field | Description |
|---|---|
side | BID or ASK |
price | The level, in cents |
qty | Units now resting at the level. Zero means the level emptied — remove it |
makers | Distinct orders now at the level |
seq | Monotonic per book, both sides on one counter |
action | Why it changed: PLACED, AMENDED, CANCELLED, FILLED, EXPIRED, or RESYNC |
Applying it:
- Subscribe, then call
getOrderBookwith the samekeyId. - Drop any push whose
seqis at or below the snapshot'ssequence. - For each later push, set
(side, price)toqty/makers— delete the level whenqtyis zero. - On
action: RESYNC, re-read the snapshot. It carries no side or price; the book changed in bulk and per-level deltas were not emitted.
Pushes can arrive out of order. For any (side, price), keep the highest seq you've seen.
To follow one venue instead of the pooled book, subscribe to public:book:<configId>:<keyId>:<marketId> and snapshot with the matching marketId. Each venue channel has its own seq.
Use serverNow on the snapshot and emittedAt on pushes to measure your clock offset before rendering restingSince ages — a wrong device clock otherwise ages the whole book.