- /
snapshotsEndpoint - up to 5,000Page size
- UP ·
DOWNSides - UTC ·
msClock
Reading the live book is one call. Reconstructing what the book did across an afternoon, a session, or an entire market’s life is a query, and /v1/markets/:id/snapshots is built for exactly that. The parameters are few, but using them well is the difference between a clean window and a million-row pull you did not mean to make.
A snapshot is one frame of the order book, best bid and ask, mid, spread, depth totals, the sequence number, and the timestamps that place it on a clock. The snapshots endpoint returns those frames for one market across a window you define, in the order and granularity you ask for.
The workflow in three moves
- 1Find the market. Resolve a slug to its 0x conditionId, via /v1/markets/by-slug/:slug or the live list, because the snapshots endpoint keys off the conditionId, not the human name.
- 2Query the window. Hit /v1/markets/:id/snapshots with from and to bracketing your range, and tune side, limit, order and include_book to shape what comes back.
- 3Analyse. Page through the result on a stable order, join it to anything else on the UTC millisecond clock, and derive your metrics from the per-snapshot fields.
The parameters, one by one
from · to
The window bounds, as UTC timestamps. Everything else narrows what falls inside this bracket, get the bracket right first.
- UTC, ms precision
- Inclusive window
- The primary filter
side · include_book
side picks UP or DOWN; include_book decides whether each row carries the full ladder or just the touch and depth totals.
- UP or DOWN only
- Book on demand
- Smaller rows by default
limit · offset · order
limit caps rows per page (up to 5,000); offset walks pages; order fixes ascending or descending so pagination is deterministic.
- ≤ 5,000 per page
- offset for paging
- asc / desc stable order
Two levers that cut your rows in half
Most over-large pulls come from asking for more than the analysis needs. Two parameters fix that directly. Choosing one side, UP or DOWN, roughly halves the rows, and because the two tokens of a market are complementary, the side you drop is usually recoverable from the one you keep. And leaving include_book off keeps each row to the touch, mid, spread and depth totals; you only pay for the full bid and ask arrays when you actually intend to walk the ladder.
- Want a price or spread time series? Skip include_book, the touch and depth totals are already on every row, so the arrays are dead weight.
- Building a depth heatmap or measuring where size rests? Then include_book is the point, request it, and budget for larger pages.
- Studying one direction of the market? Pin side to UP (or DOWN) and halve the payload; the complement is implied by the pair.
- Comparing many markets? Pull each on the same order and clock so they line up without a re-sort step.
Paginating a long window
At ~20 Hz on crypto, a single busy hour can run past what one page holds. The endpoint caps a page at 5,000 rows, so a long window is a loop: fix an order, take a page, advance the offset by the page size, and stop when a short page tells you the window is exhausted. Keep the order stable across pages or rows can shift between requests and you will double-count or skip.
- limit ≤ 5000Maximum rows returned per request
- offsetHow far into the window each page starts
- order asc /
descFix it so pagination is deterministic sequence_numberPer-snapshot counter for gap detection
Page size is a budget, not a default
A paginated time-series pull is one of the more expensive request types (5 credits per request on every tier), so the request count is also a credit count. Narrow with from/to and side before you reach for a bigger page, the cheapest row is the one you never requested. The Free tier is metered too, drawing from its 5,000-credit monthly allowance, and the 5,000-row page cap still applies.
When you join the result to another feed, a second market, or Hyperliquid perps, do it on the UTC millisecond timestamps and attach the most recent prior record, never a later one. That ordering rule is what keeps a historical study free of lookahead: nothing from the future leaks into a row that should not have seen it.
A clean historical window is mostly restraint, the right bracket, one side, the book only when you need it. Ask for less and the pull is faster, cheaper, and easier to trust.
Pull your first window
The historical guide walks the snapshots endpoint end to end; the docs list every parameter and its accepted formats.
Frequently asked questions
How many snapshots can I get per request?
Up to 5,000 rows per page. For windows that exceed that, common on crypto at ~20 Hz, fix a stable order, take a page, advance the offset by the page size, and stop when a short page signals the window is exhausted.
When should I set include_book?
Set it only when you need the full bid and ask ladder, for depth heatmaps or measuring where resting size sits. For price, spread or depth-total time series, leave it off: those fields ride on every row already, so the arrays would just inflate the payload.
Why query one side instead of both?
Pinning side to UP or DOWN roughly halves the rows you transfer and pay for. Because a market’s two tokens are complementary, the side you drop is usually recoverable from the one you keep, so for many studies one side is all you need.
How do I avoid duplicate or missing rows when paginating?
Keep the order parameter fixed across every page. If the order changes between requests, rows can shift position and you will either skip or double-count them. With a stable asc or desc order, advancing the offset walks the window cleanly, and the sequence_number lets you confirm no frames went missing.



