Endpoints
Seventeen endpoints. Five need no key.
| endpoint | key | what it answers |
|---|---|---|
GET /v2/venues |
— | Every venue in DQL, with how many listings it has and how many of them the platform collects. |
GET /v2/instruments |
— | Every selected listing: how its venue names it, the rules it trades under, and what is collected for it. |
GET /v2/dql/catalogue |
— | Every field, source, function, code and limit a query may use. |
POST /v2/dql/parse |
— | A query checked but not run: what it means, what it reads, what it costs. |
GET /v2/plans |
— | Every self-serve plan and its limits, in the order of the Compare-plans table. |
POST /v2/screen |
yes | Run a DQL query across venues and return what matched. |
POST /v2/snapshots |
yes | The latest reading of each layer for the selected listings. |
POST /v2/snapshots/history |
yes | The same snapshot as it stood in the past: one row per period, per named instant, or per message as it arrived. |
POST /v2/candles |
yes | Completed candles, in any stored period and price type. |
POST /v2/liquidations |
yes | Liquidations, one by one, in a window of up to a week. |
GET /v2/funding/settlements |
yes | Funding settlement prints, one row per print of a listing: the rate as published, the interval in force, the origin, the cap and floor. |
POST /v2/books |
yes | Order books to the depth the plan allows, with the depth resting in each band around the mid. |
GET /v2/account |
yes | What this key sees and what is left of it today: the plan, the platform’s venues, layers and limits, and today’s counters. |
GET /v2/agent/state |
yes | The state of the account’s Agent rules, polled: true, false or unknown, and what this key was told last time. |
GET /v2/agent/result |
yes | A persisted live candle decision for one rule, instrument and UTC candle close. |
GET /v2/archive |
yes | The files of the archive for one listing: the day, the rows, the size, the sha256, how many gaps the day has, and where to fetch it. |
GET /v2/archive/{listing}/{layer}/{day} |
yes | One file of the archive, as a 302 to a link that works for fifteen minutes. |
GET /v2/stream |
yes | A live stream of the selected listings, as server-sent events. |
Every one of them refuses in the same shape — a list of errors with a stable code — and every one of
them takes the same selection grammar in where. The full schemas are in
the reference; what follows is the shape of each in prose.
Receipts and replay
Section titled “Receipts and replay”Every answer that carries data has served_at (UTC, its own as-of instant, the same as evaluated_at) and receipt_id (opaque, new for every
answer and every stream event). Log them next to the decision you made from the answer. What a receipt lets you
replay, and where that stops:
The live answer is the freshest we have seen; history is what we stored. The live answer can be one reading ahead of history, until that reading’s sampling window closes (
history_cadenceon/v2/instruments); in time the two readings can be further apart than one window where the venue updates less often than that.
A live answer (snapshots, screen without as of, stream) shows the newest reading received by served_at;
its received_at and age_ms say how fresh it is. History keeps, for each layer, the last reading of every
sampling window, and a stored reading counts from the end of its window — before that a later reading of the same
window could still replace it. So a replay with as_of = served_at returns exactly what had been recorded as of
that instant — every reading visible then, with its received_at and its status — and returns the same every
time you ask. It is the tool for a post-mortem, not a copy of the live answer: a live answer may show a reading of
the window still open at served_at, which history did not have then. Once that window has ended, the two agree
field for field. To keep exactly what your code read, log the response itself — receipt_id and the values.
Ordering between venues or layers is fixed by received_at, never by arrival order at the client.
How long the window is, is history_cadence per layer on /v2/instruments: 1s, 10s, 15s or 1m — by the
listing’s group and the layer, the table is on the Freshness page (“How often history keeps a value”); funding is
kept one reading per ten seconds at the shortest, so it says 10s where the window would be a second. null for
a layer history keeps whole or does not keep (candles, trades; a layer off by policy shows policy: "off").
Every stored row carries the window it was sampled at, and the live answers are the newest tick whatever this says.
Ask a snapshot’s past with POST /v2/snapshots/history and at: [served_at] (with at, from and to are
refused: the instants are the rows) — each row is the recorded layer in a snapshot’s words, status, reason,
age_ms and all, a layer not published not_published and one off by policy off in both — a screen’s with
as of (an instant to the millisecond: the first three fractional digits of served_at), instruments with
?as_of=. Order books are not replayable: levels are never stored, and stream events are ticks, not replayed one
by one. The replay is final once settled: true. A query that names its
own as of is replayed by it. A value stamped after served_at — by a collector whose clock runs ahead, say — is
never shown in the answer and never in its replay. Collectors and the API run on one host and one clock today.
Freshness: a value says how long it is good for
Section titled “Freshness: a value says how long it is good for”Every value of a snapshot layer carries valid_until, horizon_source and anchor, its age age_ms — from the
venue’s own timestamp where the venue dates the value (anchor: venue), from our receipt otherwise — and
venue_age_ms by the venue’s clock. Past valid_until a layer is stale, with a reason, and its value is
not in the answer: values is empty, and the value is written under withheld only when the request sets
allow_stale: true (default false). A replay with as_of = served_at withholds exactly what the answer
withheld, for the same reason. What each horizon rests on, pair by pair, and which pairs rest on an assumed
cadence: Freshness and cadence.
GET /v2/venues
Section titled “GET /v2/venues”Every venue in DQL, with how many listings it has and how many of them the platform collects.
Read it before anything else: a venue that is not here cannot be named in a query, and the gap between listings and listings_collected is the coverage you actually have.
No key. What exists is not a paid fact.
What it answers
Section titled “What it answers”| field | type | meaning |
|---|---|---|
evaluated_at |
Instant |
The instant the platform evaluated this answer at (UTC). |
served_at |
ServedAt |
The response’s own as-of instant (the same as evaluated_at, six fractional digits). Replay it with as_of. |
receipt_id |
ReceiptId |
Names this exact response. Log it next to the decision made from it. |
registry_revision |
string | Stable registry snapshot identity shared by all pages: the UTC Snapshot.ReadAt timestamp, a dot, and the lowercase SHA-256 digest of the effective registry row, … |
next_cursor |
string or null | Opaque continuation cursor for the next page. Null means this is the last page. Keep all other request options unchanged; a stale cursor or changed scope … |
items |
array | The venues, by public code. |
An answer
Section titled “An answer”{ "evaluated_at": "2026-09-23T11:28:26.904Z", "registry_revision": "2026-09-23T11:28:26.904Z.f78b77f848f073634ad0df313bd48d234f27206cf523dd6f5018575231c01eed", "next_cursor": null, "items": [ { "venue": "HYPERLIQUID", "name": "Hyperliquid", "kind": "order_book", "listings": 234, "listings_collected": 5, "since": "2026-09-21T12:03:13.315Z" } ], "items_note": "1 more, cut here for length"}GET /v2/instruments
Section titled “GET /v2/instruments”Every selected listing: how its venue names it, the rules it trades under, and what is collected for it.
This is where a bot learns the exchange’s own symbol for an instrument, its tick and lot size, and which layers exist for it. ?where= takes the same selection grammar as everything else. For 90 days after a listing’s instrument was renamed (1000PEPE-PERP became PEPE-PERP), ?renamed_from=1000PEPE-PERP finds the listings that carried the old name, and each of them says so in renamed_from; DQL has no alias, so the old name cannot be written in where.
No key. What exists is not a paid fact.
What it answers
Section titled “What it answers”| field | type | meaning |
|---|---|---|
evaluated_at |
Instant |
The instant the platform evaluated this answer at (UTC). |
served_at |
ServedAt |
The response’s own as-of instant (the same as evaluated_at, six fractional digits). Replay it with as_of. |
receipt_id |
ReceiptId |
Names this exact response. Log it next to the decision made from it. |
resolved_from |
ResolvedFrom |
|
trial |
Trial |
|
registry_revision |
string | Stable registry snapshot identity shared by all pages: the UTC Snapshot.ReadAt timestamp, a dot, and the lowercase SHA-256 digest of the effective registry row, … |
next_cursor |
string or null | Opaque continuation cursor for the next page. Null means this is the last page. Keep all other request options unchanged; a stale cursor or changed scope … |
as_of |
Instant |
The instant the answer describes: the moment of the request, or the as_of it asked for. |
catalogue |
string | The catalogue version the answer was built against. |
units |
published, base |
The unit mode applied. |
normalisation_version |
NormalisationVersion |
Present only with units: base: which conversion rules produced the figures, such as 2026-10-07. Keep it beside numbers you store. |
listings_as_of |
NullableInstant |
When the listing set itself was last known to change. Present when asking about the past. |
capabilities_as_of |
NullableInstant |
When what each venue publishes was last known to change. |
items |
array | The listings, one object each. |
An answer
Section titled “An answer”{ "evaluated_at": "2026-09-23T11:28:27.118Z", "registry_revision": "2026-09-23T11:28:27.118Z.bf96b16abe250df1069a531df3bbef48bf6c16a3fdfa8f266df63e26975c256c", "next_cursor": null, "as_of": "2026-09-23T11:28:27.118Z", "catalogue": "2026-09-22", "units": "published", "items": [ { "instrument": "BTC-PERP", "venue": "HYPERLIQUID", "venue_symbol": "BTC", "base": "BTC", "base_venue_alias": null, "quote": "USDC", "kind": "perpetual", "venue_kind": null, "pair": null, "status": "tradeable", "post_only": null, "contract_size": 1, "multiplier": 1, "tick_size": null, "lot_size": null, "min_qty": null, "min_notional": null, "price_decimals": null, "qty_decimals": 5, "units": { "tick_size": "quote", "lot_size": "base", "min_qty": "base", "min_notional": "quote" }, "funding_interval": "1h", "funding_interval_source": "venue", "funding_normalisation": { "venue_field": "funding", "transform": "identity" }, "rules_normalisation": { "funding_interval": { "venue_field": "fundingIntervalHours", "transform": "hours_to_duration" }, "qty_decimals": { "venue_field": "szDecimals", "transform": "identity" } }, "candles": { "base_timeframe": "1m", "price_types": [ "trade" ], "timeframes": [ "1m", "5m", "15m", "30m", "1h", "4h", "12h", "1d" ] }, "layers": { "ticker": { "policy": "on", "cadence": "live" }, "mark": { "policy": "on", "cadence": "live" }, "funding": { "policy": "on", "cadence": "live" }, "oi": { "policy": "on", "cadence": "live" }, "book": { "policy": "on", "cadence": "live" }, "stats": { "policy": "on", "cadence": "live" }, "candles": { "policy": "on", "cadence": "live" }, "trade": { "policy": "on", "cadence": "live" }, "book_bands": { "policy": "on", "cadence": "live" } }, "not_published": [ "change_24h", "index_close", "index_high", "index_low", "index_open", "index_volume", "mark_close", "mark_high", "mark_low", "mark_open", "mark_volume" ], "bands": [ "10bps", "25bps", "50bps", "100bps" ], "listed_at": null, "first_seen_at": "2026-09-21T20:05:09.829Z", "delisted_at": null, "venue_ts": null, "received_at": "2026-09-23T11:20:39.343Z", "age_ms": 467774 } ], "items_note": "1 more, cut here for length"}GET /v2/dql/catalogue
Section titled “GET /v2/dql/catalogue”Every field, source, function, code and limit a query may use.
Read this rather than hard-coding a list. It is generated from the registry and the policy the collectors run on, so it changes the moment the platform does.
No key. What exists is not a paid fact.
What it answers
Section titled “What it answers”| field | type | meaning |
|---|---|---|
dql |
string | The language version this catalogue describes. |
catalogue |
string | A version that changes whenever the catalogue’s content does. Cache against it. |
evaluated_at |
Instant |
The instant the platform evaluated this answer at (UTC). |
fields |
array | Every field. |
sources |
array | Every candle source. |
functions |
array | Every function. |
venues |
array | Every venue code a query may name. |
currencies |
array | Every quote currency. DQL never converts between them. |
assets |
array | Every base asset. |
instruments |
array | Every instrument code. |
timeframes |
array | Every period a series may be read at. |
bands |
array | Every price band the depth functions accept. |
freshness_defaults |
object | The default freshness bound per layer. A reading older than its bound is stale and compares as unknown. |
limits |
CatalogueLimits |
|
settle_after |
integer | Seconds after which an instant is settled: late arrivals can no longer change an answer about it. |
earliest_retained |
NullableInstant |
The earliest instant any query may ask about. |
units |
array | The unit modes a request may ask for. |
number_formats |
array | The number formats a request may ask for. |
An answer
Section titled “An answer”{ "dql": "1", "catalogue": "2026-09-22", "evaluated_at": "2026-09-23T11:28:26.994Z", "fields": [ { "name": "instrument", "type": "code", "scope": "instrument", "layer": "reference", "unit": "code", "description": "the market code, e.g. BTC-PERP", "sampleable": false, "additive": false, "not_published_on": [] }, { "name": "base", "type": "code", "scope": "instrument", "layer": "reference", "unit": "code", "description": "the base asset\u0027s registry code, e.g. BTC", "sampleable": false, "additive": false, "not_published_on": [] }, { "name": "venues_listed", "type": "number", "scope": "instrument", "layer": "reference", "unit": "count", "description": "number of (selected) listings at T", "sampleable": false, "additive": false, "not_published_on": [] }, { "name": "venues_answered", "type": "number", "scope": "instrument", "layer": "reference", "unit": "count", "description": "number of (selected) listings whose mark is present at T", "sampleable": false, "additive": false, "not_published_on": [] }, { "name": "venue", "type": "code", "scope": "venue", "layer": "reference", "unit": "code", "description": "the venue\u0027s public code", "sampleable": false, "additive": false, "not_published_on": [] }, { "name": "quote", "type": "code", "scope": "venue", "layer": "reference", "unit": "code", "description": "the listing\u0027s quote currency", "sampleable": false, "additive": false, "not_published_on": [] }, { "name": "tick_size", "type": "number", "scope": "venue", "layer": "reference", "unit": "quote", "description": "minimum price increment of the listing", "sampleable": false, "additive": false, "not_published_on": [] }, { "name": "lot_size", "type": "number", "scope": "venue", "layer": "reference", "unit": "quantity", "description": "minimum quantity increment", "sampleable": false, "additive": false, "not_published_on": [] }, { "name": "min_qty", "type": "number", "scope": "venue", "layer": "reference", "unit": "quantity", "description": "minimum order quantity", "sampleable": false, "additive": false, "not_published_on": [] }, { "name": "last", "type": "number", "scope": "venue", "layer": "ticker", "unit": "quote", "description": "last trade price", "sampleable": true, "additive": false, "not_published_on": [] }, { "name": "mark", "type": "number", "scope": "venue", "layer": "mark", "unit": "quote", "description": "venue mark price", "sampleable": true, "additive": false, "not_published_on": [] }, { "name": "index", "type": "number", "scope": "venue", "layer": "mark", "unit": "quote", "description": "venue index price", "sampleable": true, "additive": false, "not_published_on": [] }, { "name": "basis", "type": "number", "scope": "venue", "layer": "mark", "unit": "fraction", "description": "(mark \u2212 index) / index", "sampleable": true, "additive": false, "not_published_on": [] }, { "name": "funding", "type": "number", "scope": "venue", "layer": "funding", "unit": "fraction", "description": "published rate for the next settlement, per interval", "sampleable": true, "additive": false, "not_published_on": [] }, { "name": "funding_interval", "type": "duration", "scope": "venue", "layer": "funding", "unit": "ms", "description": "settlement interval as published", "sampleable": false, "additive": false, "not_published_on": [ "KRAKEN-FUTURES" ] }, { "name": "funding_8h", "type": "number", "scope": "venue", "layer": "funding", "unit": "fraction", "description": "funding \u00D7 8h / funding_interval", "sampleable": true, "additive": false, "not_published_on": [ "KRAKEN-FUTURES" ] }, { "name": "time_to_funding", "type": "duration", "scope": "venue", "layer": "funding", "unit": "ms", "description": "next_funding_at \u2212 T", "sampleable": false, "additive": false, "not_published_on": [] }, { "name": "oi", "type": "number", "scope": "venue", "layer": "oi", "unit": "quantity", "description": "open interest", "sampleable": true, "additive": true, "not_published_on": [] }, { "name": "bid", "type": "number", "scope": "venue", "layer": "book", "unit": "quote", "description": "best bid price", "sampleable": true, "additive": false, "not_published_on": [] }, { "name": "ask", "type": "number", "scope": "venue", "layer": "book", "unit": "quote", "description": "best ask price", "sampleable": true, "additive": false, "not_published_on": [] }, { "name": "mid", "type": "number", "scope": "venue", "layer": "book", "unit": "quote", "description": "(bid \u002B ask) / 2", "sampleable": true, "additive": false, "not_published_on": [] }, { "name": "spread", "type": "number", "scope": "venue", "layer": "book", "unit": "fraction", "description": "(ask \u2212 bid) / mid", "sampleable": true, "additive": false, "not_published_on": [] }, { "name": "bid_size", "type": "number", "scope": "venue", "layer": "book", "unit": "quantity", "description": "resting quantity at the best bid", "sampleable": true, "additive": true, "not_published_on": [] }, { "name": "ask_size", "type": "number", "scope": "venue", "layer": "book", "unit": "quantity", "description": "resting quantity at the best ask", "sampleable": true, "additive": true, "not_published_on": [] }, { "name": "volume_24h", "type": "number", "scope": "venue", "layer": "stats", "unit": "quantity", "description": "rolling 24h traded volume as published", "sampleable": true, "additive": true, "not_published_on": [] }, { "name": "turnover_24h", "type": "number", "scope": "venue", "layer": "stats", "unit": "quote", "description": "rolling 24h traded value as published", "sampleable": true, "additive": true, "not_published_on": [] }, { "name": "change_24h", "type": "number", "scope": "venue", "layer": "stats", "unit": "fraction", "description": "24h price change as published", "sampleable": true, "additive": false, "not_published_on": [ "HYPERLIQUID" ] } ], "sources": [ { "name": "open", "type": "series", "scope": "venue", "layer": "candles", "price_type": "trade", "unit": "quote", "description": "trade candle open", "not_published_on": [] }, { "name": "high", "type": "series", "scope": "venue", "layer": "candles", "price_type": "trade", "unit": "quote", "description": "trade candle high", "not_published_on": [] }, { "name": "low", "type": "series", "scope": "venue", "layer": "candles", "price_type": "trade", "unit": "quote", "description": "trade candle low", "not_published_on": [] }, { "name": "close", "type": "series", "scope": "venue", "layer": "candles", "price_type": "trade", "unit": "quote", "description": "trade candle close", "not_published_on": [] }, { "name": "volume", "type": "series", "scope": "venue", "layer": "candles", "price_type": "trade", "unit": "quantity", "description": "trade candle volume", "not_published_on": [] }, { "name": "mark_open", "type": "series", "scope": "venue", "layer": "candles", "price_type": "mark", "unit": "quote", "description": "mark-price candle open", "not_published_on": [ "HYPERLIQUID" ] }, { "name": "mark_high", "type": "series", "scope": "venue", "layer": "candles", "price_type": "mark", "unit": "quote", "description": "mark-price candle high", "not_published_on": [ "HYPERLIQUID" ] }, { "name": "mark_low", "type": "series", "scope": "venue", "layer": "candles", "price_type": "mark", "unit": "quote", "description": "mark-price candle low", "not_published_on": [ "HYPERLIQUID" ] }, { "name": "mark_close", "type": "series", "scope": "venue", "layer": "candles", "price_type": "mark", "unit": "quote", "description": "mark-price candle close", "not_published_on": [ "HYPERLIQUID" ] }, { "name": "mark_volume", "type": "series", "scope": "venue", "layer": "candles", "price_type": "mark", "unit": "quantity", "description": "mark-price candle volume as published", "not_published_on": [ "HYPERLIQUID" ] }, { "name": "index_open", "type": "series", "scope": "venue", "layer": "candles", "price_type": "index", "unit": "quote", "description": "index-price candle open", "not_published_on": [ "HYPERLIQUID" ] }, { "name": "index_high", "type": "series", "scope": "venue", "layer": "candles", "price_type": "index", "unit": "quote", "description": "index-price candle high", "not_published_on": [ "HYPERLIQUID" ] }, { "name": "index_low", "type": "series", "scope": "venue", "layer": "candles", "price_type": "index", "unit": "quote", "description": "index-price candle low", "not_published_on": [ "HYPERLIQUID" ] }, { "name": "index_close", "type": "series", "scope": "venue", "layer": "candles", "price_type": "index", "unit": "quote", "description": "index-price candle close", "not_published_on": [ "HYPERLIQUID" ] }, { "name": "index_volume", "type": "series", "scope": "venue", "layer": "candles", "price_type": "index", "unit": "quantity", "description": "index-price candle volume as published", "not_published_on": [ "HYPERLIQUID" ] } ], "functions": [ { "name": "prev", "signature": "prev(S, k)", "type": "series", "scope": "venue", "layer": "candles", "unit": "none", "description": "S[k]" }, { "name": "sma", "signature": "sma(S, n)", "type": "series", "scope": "venue", "layer": "candles", "unit": "none", "description": "simple moving average" }, { "name": "ema", "signature": "ema(S, n)", "type": "series", "scope": "venue", "layer": "candles", "unit": "none", "description": "exponential moving average over a fixed 4n window" }, { "name": "rsi", "signature": "rsi(S, n)", "type": "series", "scope": "venue", "layer": "candles", "unit": "none", "description": "relative strength index, Wilder smoothing over 4n" }, { "name": "atr", "signature": "atr(n)", "type": "series", "scope": "venue", "layer": "candles", "unit": "none", "description": "average true range of the trade candles" }, { "name": "stdev", "signature": "stdev(S, n)", "type": "series", "scope": "venue", "layer": "candles", "unit": "none", "description": "population standard deviation" }, { "name": "highest", "signature": "highest(S, n)", "type": "series", "scope": "venue", "layer": "candles", "unit": "none", "description": "max(S[0] \u2026 S[n\u22121])" }, { "name": "lowest", "signature": "lowest(S, n)", "type": "series", "scope": "venue", "layer": "candles", "unit": "none", "description": "min(S[0] \u2026 S[n\u22121])" }, { "name": "change", "signature": "change(S, n)", "type": "series", "scope": "venue", "layer": "candles", "unit": "none", "description": "S[0] \u2212 S[n]" }, { "name": "roc", "signature": "roc(S, n)", "type": "series", "scope": "venue", "layer": "candles", "unit": "none", "description": "(S[0] \u2212 S[n]) / S[n]" }, { "name": "crossover", "signature": "crossover(A, B)", "type": "boolean", "scope": "venue", "layer": "candles", "unit": "none", "description": "A[0] \u003E B[0] and A[1] \u2264 B[1]" }, { "name": "crossunder", "signature": "crossunder(A, B)", "type": "boolean", "scope": "venue", "layer": "candles", "unit": "none", "description": "A[0] \u003C B[0] and A[1] \u2265 B[1]" }, { "name": "gaps", "signature": "gaps(n)", "type": "number", "scope": "venue", "layer": "candles", "unit": "none", "description": "missing periods among the last n" }, { "name": "abs", "signature": "abs(x)", "type": "number", "scope": "venue", "layer": "", "unit": "none", "description": "|x|, element-wise for series" }, { "name": "rolling_sum", "signature": "rolling_sum(S, n)", "type": "series", "scope": "venue", "layer": "candles", "unit": "none", "description": "S[n\u22121] \u002B \u2026 \u002B S[0]" }, { "name": "percentile", "signature": "percentile(S, n, p, [method])", "type": "series", "scope": "venue", "layer": "candles", "unit": "none", "description": "nearest-rank (default) or linear percentile of S[0] \u2026 S[n\u22121]" }, { "name": "percentile_rank", "signature": "percentile_rank(S, n)", "type": "series", "scope": "venue", "layer": "candles", "unit": "none", "description": "share of S[0] \u2026 S[n\u22121] that are \u2264 S[0]" }, { "name": "age", "signature": "age(F)", "type": "duration", "scope": "venue", "layer": "", "unit": "none", "description": "T \u2212 received_at of the value used for F" }, { "name": "status", "signature": "status(F)", "type": "status", "scope": "venue", "layer": "", "unit": "none", "description": "state of F\u0027s layer at T" }, { "name": "depth_bid", "signature": "depth_bid(band)", "type": "number", "scope": "venue", "layer": "book", "unit": "quantity", "description": "bid quantity within band of mid", "not_published_on": [] }, { "name": "depth_ask", "signature": "depth_ask(band)", "type": "number", "scope": "venue", "layer": "book", "unit": "quantity", "description": "ask quantity within band of mid", "not_published_on": [] }, { "name": "depth_bid_value", "signature": "depth_bid_value(band)", "type": "number", "scope": "venue", "layer": "book", "unit": "quote", "description": "bid value (price \u00D7 size) within band of mid", "not_published_on": [] }, { "name": "depth_ask_value", "signature": "depth_ask_value(band)", "type": "number", "scope": "venue", "layer": "book", "unit": "quote", "description": "ask value (price \u00D7 size) within band of mid", "not_published_on": [] } ], "venues": [ "HYPERLIQUID", "KRAKEN-FUTURES" ], "currencies": [ "USD", "USDC" ], "assets": [ "", "BTC", "CYPH", "DOGE", "ETH", "GTLB", "KSTR", "MSTU", "OURA", "SOL", "XRP" ], "instruments": [ "-PERP" ], "timeframes": [ "1m", "5m", "15m", "30m", "1h", "4h", "12h", "1d" ], "bands": [ "10bps", "25bps", "50bps", "100bps" ], "freshness_defaults": { "ticker": "30s", "mark": "30s", "funding": "300s", "oi": "30s", "book": "30s", "stats": "120s" }, "limits": { "source_bytes": 8192, "nodes": 256, "depth": 24, "quantifiers_and_aggregates": 16, "series_calls": 32, "timeframes": 3, "window": 500, "bars_per_atom": 2000, "cost": 10000, "in_list": 32, "select": 16, "order_by": 4, "freshness_min": "1s", "freshness_max": "604800s", "screen_limit": 500, "endpoints": { "snapshots_listings": 500, "history_listings": 100, "history_rows_per_layer": 2000, "history_raw_rows": 100000, "candles_listings": 100, "candles_per_listing": 1500, "books_listings": 100, "book_depth": 25, "stream_listings": 500, "response_bytes": 8388608 } }, "settle_after": 120, "earliest_retained": "2026-09-14T00:00:00Z", "units": [ "published", "base" ], "number_formats": [ "json", "string" ], "instruments_note": "10 more, cut here for length"}POST /v2/dql/parse
Section titled “POST /v2/dql/parse”A query checked but not run: what it means, what it reads, what it costs.
It touches no market data and needs no key, which makes it the right thing for an editor to call on every keystroke — and the right way to see a query’s cost before spending it.
No key. What exists is not a paid fact.
What it takes
Section titled “What it takes”| field | type | required | meaning |
|---|---|---|---|
query |
string or object | yes | The query, as text or as the machine form of specification §3.1. |
dql |
string | — | The language version. Only 1 exists. |
context |
string | — | What the query is for. Only screen exists. |
What it answers
Section titled “What it answers”| field | type | meaning |
|---|---|---|
resolved_from |
ResolvedFrom |
|
trial |
Trial |
|
dql |
string | The language version. |
query |
object | The query in both forms, canonical. |
atoms |
object | What the query reads, by scope. Useful for showing a reader which data a query depends on. |
timeframes |
array | Every period the query reads. |
complexity |
object | What the query costs, against the catalogue’s limits. |
An answer
Section titled “An answer”{ "query": "any(venues where funding \u003E 0)"}{ "dql": "1", "query": { "string": "any(venues where funding \u003E 0)", "json": { "dql": "1", "condition": { "type": "any", "where": { "type": "cmp", "op": "\u003E", "left": { "type": "field", "name": "funding" }, "right": { "type": "number", "value": 0 } } } } }, "atoms": { "instrument": [], "venue": [ "funding" ] }, "timeframes": [], "complexity": { "nodes": 4, "bars": 0, "cost": 4 }}GET /v2/plans
Section titled “GET /v2/plans”Every self-serve plan and its limits, in the order of the Compare-plans table.
The plan table itself, so a client compares plans by the numbers the platform enforces rather than by a copy of the pricing page. A null limit is no limit: every venue, every instrument, no cap on how far back the plan reads; agent: null is a plan without Agent. A plan changed in the table shows here within a minute.
No key. What exists is not a paid fact.
What it answers
Section titled “What it answers”| field | type | meaning |
|---|---|---|
evaluated_at |
Instant |
The instant the platform evaluated this answer at (UTC). |
items |
array | The plans, in the order of the table. |
POST /v2/screen
Section titled “POST /v2/screen”Run a DQL query across venues and return what matched.
The endpoint the language exists for. Everything else on this page is a projection of it.
Needs a key. Refuses with 401 without one, 429 when the plan’s rate is used up.
What it takes
Section titled “What it takes”| field | type | required | meaning |
|---|---|---|---|
query |
string | — | The query in DQL. |
query_object |
object | — | The same query in the machine form of specification §3.1. |
limit |
integer | — | How many instruments to return in one page. The catalogue states the ceiling your plan allows. |
cursor |
string | — | A cursor from a previous answer’s page.next_cursor. It pins the instant, so page two sees the world page one saw. |
include_unknown |
boolean | — | Also return the instruments the data could not decide, with result: unknown, instead of dropping them. Ask for this whenever coverage matters. |
include_atoms |
boolean | — | Also return, for every value the platform computed, the values it was computed from — each with its own venue, receipt time, age and status. derived: true … |
units |
published, base |
— | What quantities are expressed in. published leaves each venue’s own unit alone; base converts to the base asset, and gives null with unit_unknown where a … |
number_format |
json, string |
— | string returns every number as a string with the same digits, for a client whose JSON parser would round them. |
allow_stale |
boolean | — | ADR-025: return a stale value under withheld — never in the value field. Off by default: a stale value is not in the answer at all, only its status, reason … |
What it answers
Section titled “What it answers”| field | type | meaning |
|---|---|---|
dql |
string | The query in canonical form — what the platform understood, which may differ in spacing and clause order from what was sent. |
query |
object | The query echoed in both forms, so a client that sent text can keep the machine form and a client that sent the machine form can show the text. |
evaluated_at |
Instant |
The instant the platform evaluated this answer at (UTC). |
served_at |
ServedAt |
The response’s own as-of instant (the same as evaluated_at, six fractional digits). Replay it with as_of. |
receipt_id |
ReceiptId |
Names this exact response. Log it next to the decision made from it. |
resolved_from |
ResolvedFrom |
|
trial |
Trial |
|
as_of |
NullableInstant |
|
settled |
boolean | Whether the instant is far enough in the past that late arrivals can no longer change the answer. A false here means the same query may answer differently in … |
timeframe |
string | The period the query’s series were read at, when it asked for one. |
normalisation_version |
NormalisationVersion |
Present only with units: base: which conversion rules produced the figures, such as 2026-10-07. Keep it beside numbers you store. |
freshness |
object | ADR-025: the query’s own freshness bound per layer, or null where it sets none — every value then has only its own horizon (valid_until). The bound only … |
listings_as_of |
NullableInstant |
When the set of listings was last known to change. Present when asking about the past. |
capabilities_as_of |
NullableInstant |
When what each venue publishes was last known to change. |
instruments |
array | The instruments that matched, each with the venues it was read on. With include_unknown, also those the data could not decide. |
page |
Page |
The page that was returned and the cursor for the next. |
An answer
Section titled “An answer”{ "query": "any(venues where funding \u003E 0)", "limit": 2}{ "dql": "1", "query": { "string": "any(venues where funding \u003E 0)", "json": { "dql": "1", "condition": { "type": "any", "where": { "type": "cmp", "op": "\u003E", "left": { "type": "field", "name": "funding" }, "right": { "type": "number", "value": 0 } } } } }, "evaluated_at": "2026-09-23T12:00:05Z", "as_of": null, "settled": false, "normalisation_version": "2026-10-12", "freshness": { "ticker": null, "mark": null, "oi": null, "book": null, "stats": null, "funding": null }, "instruments": [ { "instrument": "BTC-PERP", "result": "true", "values": {}, "scopes": { "any(venues where funding \u003E 0)": { "venues_listed": 4, "venues_in_scope": 4, "excluded": [] } }, "venues": [ { "venue": "BYBIT-PERP", "symbol": "BTCUSDT", "quote": "USDT", "values": { "funding": { "value": null, "unit": "fraction", "venue": "BYBIT-PERP", "layer": "funding", "venue_ts": null, "received_at": "2026-09-23T11:52:00Z", "age_ms": 485000, "venue_age_ms": null, "valid_until": "2026-09-23T11:57:00Z", "horizon_source": "assumed", "anchor": "receipt", "status": "stale", "reason": "horizon_passed" } } }, { "venue": "HYPERLIQUID", "symbol": "BTC", "quote": "USDC", "values": { "funding": { "value": 0.000013, "unit": "fraction", "venue": "HYPERLIQUID", "layer": "funding", "venue_ts": null, "received_at": "2026-09-23T12:00:04Z", "age_ms": 1000, "venue_age_ms": null, "valid_until": "2026-09-23T12:05:04Z", "horizon_source": "assumed", "anchor": "receipt", "status": "present" } } }, { "venue": "KRAKEN-FUTURES", "symbol": "PF_XBTUSD", "quote": "USD", "values": { "funding": { "value": 0.00001, "unit": "fraction", "venue": "KRAKEN-FUTURES", "layer": "funding", "venue_ts": null, "received_at": "2026-09-23T12:00:04Z", "age_ms": 1000, "venue_age_ms": null, "valid_until": "2026-09-23T12:05:04Z", "horizon_source": "assumed", "anchor": "receipt", "status": "present" } } }, { "venue": "OKX-PERP", "symbol": "BTC-USDT-SWAP", "quote": "USDT", "values": { "funding": { "value": 0.000054, "unit": "fraction", "venue": "OKX-PERP", "layer": "funding", "venue_ts": null, "received_at": "2026-09-23T12:00:04Z", "age_ms": 1000, "venue_age_ms": null, "valid_until": "2026-09-23T12:05:04Z", "horizon_source": "assumed", "anchor": "receipt", "status": "present" } } } ] } ], "page": { "limit": 2, "returned": 2, "next_cursor": "eyJ0IjoiMjAyNi0wOS0yM1QxMjowMDowNVoiLCJhZnRlciI6IkVUSC1QRVJQIiwicSI6IjExZDhjM2VmZWNkZGNjNTYifQ" }, "instruments_note": "1 more, cut here for length"}POST /v2/snapshots
Section titled “POST /v2/snapshots”The latest reading of each layer for the selected listings.
When you want the state of things rather than an answer to a question. It also returns the instrument-venue pairs you asked for that do not exist, rather than leaving you to infer them from a short answer.
Needs a key. Refuses with 401 without one, 429 when the plan’s rate is used up.
What it takes
Section titled “What it takes”| field | type | required | meaning |
|---|---|---|---|
where |
Selection |
— | |
kind |
perpetual, spot, all |
— | Market kind to select. Defaults to perpetual, preserving the prior V2 selection. all includes spot and perpetual listings. |
units |
published, base |
— | What quantities are expressed in. |
number_format |
json, string |
— | string returns every number as a string with the same digits. |
include_synthetic |
boolean | — | Include venues that exist in the registry but are not published. For the platform’s own use; a public key sees nothing extra. |
layers |
array | — | Which layers to read. Every layer when omitted. |
include_raw |
boolean | — | Also return each layer’s message as the venue sent it. |
allow_stale |
boolean | — | ADR-025: return a stale value under withheld — never in the value field. Off by default: a stale value is not in the answer at all, only its status, reason … |
What it answers
Section titled “What it answers”| field | type | meaning |
|---|---|---|
evaluated_at |
Instant |
The instant the platform evaluated this answer at (UTC). |
served_at |
ServedAt |
The response’s own as-of instant (the same as evaluated_at, six fractional digits). Replay it with as_of. |
receipt_id |
ReceiptId |
Names this exact response. Log it next to the decision made from it. |
resolved_from |
ResolvedFrom |
|
trial |
Trial |
|
units |
published, base |
The unit mode applied. |
normalisation_version |
NormalisationVersion |
Present only with units: base: which conversion rules produced the figures, such as 2026-10-07. Keep it beside numbers you store. |
freshness |
object | ADR-025: the request’s own bound per layer, or null where none was set — every value has its own horizon (valid_until) either way, and a bound only tightens … |
items |
array | One object per listing. |
missing |
array | The instrument-venue pairs that do not exist. |
POST /v2/snapshots/history
Section titled “POST /v2/snapshots/history”The same snapshot as it stood in the past: one row per period, per named instant, or per message as it arrived.
Three different questions, and the endpoint makes you say which. raw is every row as received — the thing to use when you are checking the platform rather than the market. interval and raw take from and to; at takes only the instants, and refuses both. A raw layer lists under gaps what the range missed (a hole the platform recorded, with its cause, or the time before retention_from); interval shows the same holes as gap rows. summary: true with interval answers a layer with its min, max, first and last per field and the number of readings instead of the rows, a few hundred characters per listing instead of a series; its extremes are the highest and lowest value observed at the interval’s samples, not a settled amount. An at row is what history had recorded as of the instant, in a snapshot’s words; a live answer can be one reading newer, until that reading’s window closes (see Receipts and replay).
Needs a key. Refuses with 401 without one, 429 when the plan’s rate is used up.
What it takes
Section titled “What it takes”| field | type | required | meaning |
|---|---|---|---|
where |
Selection |
— | |
kind |
perpetual, spot, all |
— | Market kind to select. Defaults to perpetual, preserving the prior V2 selection. all includes spot and perpetual listings. |
units |
published, base |
— | What quantities are expressed in. |
number_format |
json, string |
— | string returns every number as a string with the same digits. |
include_synthetic |
boolean | — | Include venues that exist in the registry but are not published. For the platform’s own use; a public key sees nothing extra. |
layers |
array | — | Which layers to read. |
interval |
string | — | One row per period of this length, each holding the last reading in it. |
at |
array | — | One row per instant, strictly ascending: what history had recorded as of it — the last stored reading visible then (a sampled reading counts from the end of its … |
raw |
boolean | — | Every row as it arrived, unsampled. |
from |
Instant |
with interval/raw |
Start of the window. Required with interval and raw; refused with at. |
to |
Instant |
with interval/raw |
End of the window. Required with interval and raw; refused with at. |
include_gaps |
boolean | — | Keep the rows that have no reading. Keeping them is the default because dropping them turns a gap into a shorter series. |
summary |
boolean | — | With interval: answer one object per layer of each listing instead of its rows: the number of readings and, per numeric field, the min, max, first and last … |
fields |
array | — | With summary: true: only these fields of the layers asked for (default: every numeric field). ["funding_8h"] is the one to compare venues’ funding by: it … |
freshness |
string | — | Override the freshness bound for every layer asked for. |
allow_stale |
boolean | — | ADR-025: return a stale value under withheld — never in the value field. Off by default: a stale value is not in the answer at all, only its status, reason … |
What it answers
Section titled “What it answers”| field | type | meaning |
|---|---|---|
evaluated_at |
Instant |
The instant the platform evaluated this answer at (UTC). |
served_at |
ServedAt |
The response’s own as-of instant (the same as evaluated_at, six fractional digits). Replay it with as_of. |
receipt_id |
ReceiptId |
Names this exact response. Log it next to the decision made from it. |
resolved_from |
ResolvedFrom |
|
trial |
Trial |
|
settled |
boolean | Whether the window is far enough in the past that a late arrival can no longer change it. |
items_sha256 |
string | SHA-256 of items as serialised. |
mode |
interval, at, raw, summary |
Which question was asked. |
interval |
string | The period, in interval mode. |
from |
NullableInstant |
The window, in interval and raw modes. Absent in at mode. |
to |
NullableInstant |
|
units |
published, base |
The unit mode applied. |
normalisation_version |
NormalisationVersion |
Present only with units: base: which conversion rules produced the figures, such as 2026-10-07. Keep it beside numbers you store. |
field_units |
object | In summary mode: what each field counts. |
freshness |
object | ADR-025: the request’s own bound per layer, or null where none was set — every value has its own horizon (valid_until) either way, and a bound only tightens … |
listings_as_of |
NullableInstant |
When the set of listings was last known to change. Present when asking about the past. |
capabilities_as_of |
NullableInstant |
When what each venue publishes was last known to change. |
items |
array | One object per listing. |
POST /v2/candles
Section titled “POST /v2/candles”Completed candles, in any stored period and price type.
One-minute candles are the venue’s own klines; every longer period is rolled up from them. A period with every base minute is a complete bar; a closed period with only some of them (a venue drop inside it) is a bar too, marked "partial": true, and DQL indicators use it; a period with no base minute at all is a gap. A partial bar becomes complete when the missing minutes are backfilled. Gaps are rows, not holes. A 1h, 4h or 1d bar from before the platform began collecting a listing is the venue’s own kline, fetched afterwards (issue 576), and says so: "origin": "backfill" on the bar; a bar the platform observed itself has no origin. A backfilled bar is the venue’s word, it is not part of any anchored day’s root, and a plan’s reach (retention and, on Free, Mini and Standard, the depth of the bar’s timeframe: Free 1m 48 hours up to 4h and 1d 90 days, Mini 1m 7 days up to 4h and 1d 180 days, Standard a year) applies to it as to every other bar.
Needs a key. Refuses with 401 without one, 429 when the plan’s rate is used up.
What it takes
Section titled “What it takes”| field | type | required | meaning |
|---|---|---|---|
where |
Selection |
— | |
kind |
perpetual, spot, all |
— | Market kind to select. Defaults to perpetual, preserving the prior V2 selection. all includes spot and perpetual listings. |
units |
published, base |
— | What quantities are expressed in. |
number_format |
json, string |
— | string returns every number as a string with the same digits. |
include_synthetic |
boolean | — | Include venues that exist in the registry but are not published. For the platform’s own use; a public key sees nothing extra. |
timeframe |
string | yes | The period. 1m comes from the venue’s own klines; every longer period is rolled up from them. |
price_type |
trade, mark, index |
— | Which price. |
from |
Instant |
yes | |
to |
Instant |
yes | |
include_gaps |
boolean | — | Keep the periods with no candle, as gap rows. |
closed_only |
boolean | — | Accepted and has no effect: only closed minutes are stored, so there is never a forming candle to return. |
trade |
boolean | — | Reserved. |
as_of |
Instant |
— | Receipt-time availability cutoff. to bounds candle closes; as_of bounds when their input was available. Defaults to now. |
What it answers
Section titled “What it answers”| field | type | meaning |
|---|---|---|
evaluated_at |
Instant |
The instant the platform evaluated this answer at (UTC). |
served_at |
ServedAt |
The response’s own as-of instant (the same as evaluated_at, six fractional digits). Replay it with as_of. |
receipt_id |
ReceiptId |
Names this exact response. Log it next to the decision made from it. |
resolved_from |
ResolvedFrom |
|
trial |
Trial |
|
settled |
boolean | Whether the window is far enough in the past that a late arrival can no longer change it. |
items_sha256 |
string | SHA-256 of items as serialised. Two answers with the same hash are the same answer, which is how a client can skip work rather than re-parse. |
timeframe |
string | The period returned. |
price_type |
trade, mark, index |
Which price the candles are of. |
from |
Instant |
|
to |
Instant |
|
units |
published, base |
The unit mode applied. |
normalisation_version |
NormalisationVersion |
Present only with units: base: which conversion rules produced the figures, such as 2026-10-07. Keep it beside numbers you store. |
listings_as_of |
NullableInstant |
When the set of listings was last known to change. Present when asking about the past. |
capabilities_as_of |
NullableInstant |
When what each venue publishes was last known to change. |
items |
array | One object per listing. |
data_as_of |
Instant |
POST /v2/liquidations
Section titled “POST /v2/liquidations”Liquidations, one by one, in a window of up to a week.
A liquidation is an event, so this is a list and not a series: the events of (from, to] in time order, each once, the venue’s own word for the side of the forced order (buy closes a short, sell closes a long) and the digits as stored. A window with no event is an empty list under status: present; where the list is known to be incomplete — older than what is kept, or a hole the platform recorded — gaps says so, with the cause, so a quiet stretch is never read as a quiet market. limit keeps the newest events of a listing and truncated says there were more. The totals over the same window are liquidation_count, liquidation_volume and liquidation_value (and their _long_ and _short_ forms) in a query. One limit of what an empty list proves: the platform does not record when it began collecting the layer for a venue, so retention_from is the oldest week the retention class holds, not the day collection started, and a venue whose collector has not run yet answers an empty list under present.
Needs a key. Refuses with 401 without one, 429 when the plan’s rate is used up.
What it takes
Section titled “What it takes”| field | type | required | meaning |
|---|---|---|---|
where |
Selection |
— | |
units |
published, base |
— | What quantities are expressed in. |
number_format |
json, string |
— | string returns every number as a string with the same digits. |
include_synthetic |
boolean | — | Include venues that exist in the registry but are not published. For the platform’s own use; a public key sees nothing extra. |
from |
Instant |
— | The start of the window, exclusive. Without it: an hour before to, or as far back as the key’s plan reads when that is less. At most a week before to. |
to |
Instant |
— | The end of the event window, inclusive. Without it, or later than the availability cutoff: the cutoff (as_of, or now). |
limit |
integer | — | The newest events of each listing to return. When there were more in the window, truncated is true on its item and the events shown are the newest. |
include_gaps |
boolean | — | Write out, per listing, where the feed is known to be incomplete (gaps). |
as_of |
Instant |
— | Receipt-time availability cutoff. from/to bound event times; as_of bounds when events were received. Defaults to now; future cutoffs are refused. |
What it answers
Section titled “What it answers”| field | type | meaning |
|---|---|---|
evaluated_at |
Instant |
The instant the platform evaluated this answer at (UTC). |
served_at |
ServedAt |
The response’s own as-of instant (the same as evaluated_at, six fractional digits). Replay it with to. |
receipt_id |
ReceiptId |
Names this exact response. Log it next to the decision made from it. |
resolved_from |
ResolvedFrom |
|
trial |
Trial |
|
settled |
boolean | Whether the window is far enough in the past, and written far enough, that a late arrival can no longer change it. |
items_sha256 |
string | SHA-256 of items as serialised. Two answers with the same hash are the same answer, which is how a client can skip work rather than re-parse. |
from |
Instant |
The start of the window actually read (exclusive). |
to |
Instant |
The end of the window actually read (inclusive). |
units |
published, base |
The unit mode applied. |
normalisation_version |
NormalisationVersion |
Present only with units: base: which conversion rules produced the figures, such as 2026-10-07. Keep it beside numbers you store. |
listings_as_of |
NullableInstant |
When the set of listings was last known to change. Present when asking about the past. |
capabilities_as_of |
NullableInstant |
When what each venue publishes was last known to change. |
items |
array | One object per listing. |
data_as_of |
Instant |
The explicit receipt-time availability cutoff; present when as_of was requested. |
GET /v2/funding/settlements
Section titled “GET /v2/funding/settlements”Funding settlement prints, one row per print of a listing: the rate as published, the interval in force, the origin, the cap and floor.
Funding as events rather than a sampled layer: the rows are the settlements themselves, each with the instant the venue states, rate and rate_8h, and the interval in force at that print. interval_check compares that interval, derived from the gap to the previous print, with the one the venue publishes; a mismatch is flagged on the row and never corrected. origin is live for a print recorded as it settled and backfill for one read afterwards from the venue’s own history (Binance, Bybit, OKX, Kraken Futures and Hyperliquid, 90 days); neither is part of an anchored day. cap, floor and at_cap are as the venue’s API published them at the print. A venue of the selection with no prints is named under not_recorded with the reason. The window is (from, to], a week by default, and depth is the plan’s history as for POST /v2/snapshots/history (PLAN_LIMIT with earliest_from and retry_with). Page with next_cursor.
Needs a key. Refuses with 401 without one, 429 when the plan’s rate is used up.
What it answers
Section titled “What it answers”| field | type | meaning |
|---|---|---|
evaluated_at |
Instant |
The instant the platform evaluated this answer at (UTC). |
served_at |
ServedAt |
The response’s own as-of instant (the same as evaluated_at, six fractional digits). |
receipt_id |
ReceiptId |
Names this exact response. Log it next to the decision made from it. |
resolved_from |
ResolvedFrom |
|
trial |
Trial |
|
from |
Instant |
The start of the window actually read (exclusive). Pinned by the first page and the same on every page of a cursor. |
to |
Instant |
The end of the window actually read (inclusive). |
order |
asc, desc |
The order of items by time (then instrument). |
listings |
integer | How many listings the selection named. |
items_sha256 |
string | SHA-256 of items as serialised. |
not_recorded |
array | The venues of the selection the platform holds no settlement prints for, each with why. An empty page of such a venue is not a quiet venue. |
items |
array | The prints. |
next_cursor |
string or null | Opaque continuation cursor. Null means this is the last page. Keep the other options unchanged; a stale or foreign cursor returns DQL_CURSOR and the read … |
POST /v2/books
Section titled “POST /v2/books”Order books to the depth the plan allows, with the depth resting in each band around the mid.
Prices and sizes are strings, always. A book is where a rounded digit becomes a wrong order.
Needs a key. Refuses with 401 without one, 429 when the plan’s rate is used up.
What it takes
Section titled “What it takes”| field | type | required | meaning |
|---|---|---|---|
where |
Selection |
— | |
kind |
perpetual, spot, all |
— | Market kind to select. Defaults to perpetual, preserving the prior V2 selection. all includes spot and perpetual listings. |
units |
published, base |
— | What quantities are expressed in. |
number_format |
json, string |
— | string returns every number as a string with the same digits. |
include_synthetic |
boolean | — | Include venues that exist in the registry but are not published. For the platform’s own use; a public key sees nothing extra. |
depth |
integer | — | Levels per side. Clamped to what the plan allows; the answer states what was applied. |
allow_stale |
boolean | — | ADR-025: return a stale value under withheld — never in the value field. Off by default: a stale value is not in the answer at all, only its status, reason … |
What it answers
Section titled “What it answers”| field | type | meaning |
|---|---|---|
evaluated_at |
Instant |
The instant the platform evaluated this answer at (UTC). |
served_at |
ServedAt |
The response’s own as-of instant (the same as evaluated_at, six fractional digits). Replay it with as_of. |
receipt_id |
ReceiptId |
Names this exact response. Log it next to the decision made from it. |
resolved_from |
ResolvedFrom |
|
trial |
Trial |
|
units |
published, base |
The unit mode applied. |
normalisation_version |
NormalisationVersion |
Present only with units: base: which conversion rules produced the figures, such as 2026-10-07. Keep it beside numbers you store. |
depth |
integer | How many levels per side were returned, after the plan’s ceiling was applied. |
liquidity_note |
string | How the depth figures relate to the levels shown, in one sentence. |
items |
array | One object per listing. |
Which venues carry a book sequence
Section titled “Which venues carry a book sequence”sequence is the venue’s own number of the book update the levels are of, exactly as the venue sent it, and
sequence_kind says what that number counts. They travel together: both are set, or both are null.
venue_sequence— the exchange’s own update id of its book feed.engine_sequence— the counter of an off-chain matching engine. It orders that engine’s messages and is not a block height.block— reserved for a chain’s block height. No venue we collect publishes its book at one, so nothing carries it today.
The number is in the venue’s units and is not normalised: one venue counts every message, another only the updates of one book, another the versions of a snapshot it serves on request. Use it to tell whether two answers are the same book update and which of them is later, not to count updates between them.
A venue without a book sequence answers null, and that is a fact about the venue, not a gap in our data.
The platform does not make a number up where the venue sends none: a counter of ours would let you believe
you were watching the venue’s feed when you were watching ours. The same goes for a venue whose only number
is not one — null there is deliberate.
| venue | book sequence |
sequence_kind |
what it is, or why there is none |
|---|---|---|---|
ASTER-PERP |
number | venue_sequence |
u, the final update id of the depth stream (the same feed as Binance USD-M). |
BINANCE-USDM |
number | venue_sequence |
u, the final update id of the depth stream. |
BITGET-PERP |
number | venue_sequence |
The depth response carries no number. |
BYBIT-PERP |
number | venue_sequence |
u, the update id of the order book stream. |
DERIBIT-PERP |
number | venue_sequence |
change_id, the venue’s book update id on a complete top-10 snapshot. It may jump; it does not count intervening updates or link deltas. |
EDGEX-PERP |
number | engine_sequence |
endVersion of the matching engine; startVersion links a delta to the previous update. |
GATE-PERP |
number | venue_sequence |
The depth response the platform reads carries times and no number. |
KRAKEN-FUTURES |
number | venue_sequence |
seq of the book feed, one counter per product, +1 on every message. |
LIGHTER-PERP |
number | engine_sequence |
nonce of the matching engine; begin_nonce links a delta to the previous update. |
MEXC-PERP |
number | venue_sequence |
version of the depth response. |
OKX-PERP |
number | venue_sequence |
seqId of the books channel. |
SYNTHETIX-PERP |
number | engine_sequence |
meseq, the counter of Synthetix’s off-chain matching engine. Not a block: it says nothing about the chain. |
WEEX-FUTURES |
number | venue_sequence |
u, the final update id of the depth stream. |
AVANTIS-PERP |
null | null | No order book: an oracle-priced venue. |
COINBASE-INTX |
null | null | No order book is collected (its WebSocket needs a key), so the book is not served at all. |
DYDX-PERP |
null | null | The indexer’s only counter, message_id, counts messages of one connection and restarts on every reconnect. It orders nothing about the book, so it is not shown. |
GMX-PERP |
null | null | No order book: an oracle-priced venue. |
HYPERLIQUID |
null | null | The book stream carries a time and no number. |
NADO-PERP |
null | null | The book stream’s chain fields are nanosecond timestamps (about 1.8e18), too large for a JSON number in most clients. They are not shown as a sequence. |
Only the latest number is served, with the levels it belongs to. Book sequences are not stored: not in the
history behind POST /v2/snapshots/history (order books have none), and not per update on GET /v2/stream.
Keeping them in history is a separate piece of work that has not been done.
The number is per listing and per feed. Never compare it across venues, or across two listings of one venue. A venue may restart its numbering, after its own maintenance for one; a smaller number than before is that, not time running backwards.
GET /v2/account
Section titled “GET /v2/account”What this key sees and what is left of it today: the plan, the platform’s venues, layers and limits, and today’s counters.
Free: the call is not counted against the day’s requests (it takes a token of the per-second limit), and it needs a key. venues.included lists the platform’s venues; all plans can query every listed venue and instrument. today.requests.remaining is what requests_per_day has left; today.dql.tokens_remaining is the bucket of /v2/screen and /v2/dql/parse now. Read it before a long job.
Needs a key. Refuses with 401 without one, 429 when the plan’s rate is used up.
What it answers
Section titled “What it answers”| field | type | meaning |
|---|---|---|
evaluated_at |
Instant |
The instant the platform evaluated this answer at (UTC). |
plan |
object | The key’s plan. |
venues |
object | Every venue available to this key, by public code. Every plan can read every venue on the platform. |
instruments |
object | How the plan picks its instruments. |
layers |
array | The snapshot layers a request may name. No plan gates a layer; instruments says per listing which a venue publishes. |
limits |
object | What the account is allowed: its plan’s limits, or its own where custom names one. |
today |
object | Today’s counters (UTC) against those limits. |
plans |
string | Where the plans and their prices are. |
GET /v2/agent/state
Section titled “GET /v2/agent/state”The state of the account’s Agent rules, polled: true, false or unknown, and what this key was told last time.
For a bot that would rather ask than be told. previous_state is what this key was given the last time it asked about the rule, one row per key and rule, so a poll sees the change since its own previous poll whatever other keys asked. A plan with push (a Runner) gets the rule’s last scheduled evaluation and its evaluated_at, free; fresh=true evaluates now and is charged against the plan’s evaluations a day. A rule is never checked faster than its instruments are collected: effective_interval is the largest of the plan’s interval, the rule’s own cadence and the cadence of its instruments. Without a key the call can be paid per rule with x402 (rule_id, one to 100). Poll at the interval a rule is checked at, not faster: between two checks nothing changes.
Needs a key. Refuses with 401 without one, 429 when the plan’s rate is used up.
What it answers
Section titled “What it answers”| field | type | meaning |
|---|---|---|
evaluated_at |
Instant |
The instant the platform evaluated this answer at (UTC). |
served_at |
ServedAt |
The response’s own as-of instant (the same as evaluated_at, six fractional digits). Replay it with as_of. |
receipt_id |
ReceiptId |
Names this exact response. Log it next to the decision made from it. |
evaluations |
AgentStateEvaluations |
Absent on a call paid with x402 and no key: it paid for what it asked, and has no budget. |
agent |
on, stopped |
Whether Agent runs on the account: stopped when the user switched it off, and then no rule is checked. With a key only, and only when Agent answered in time. |
items |
array | One per rule, oldest first. |
GET /v2/agent/result
Section titled “GET /v2/agent/result”A persisted live candle decision for one rule, instrument and UTC candle close.
Requires the account’s user key and rule_id, instrument, bar_end query parameters. Returns true, false or unknown with a reason, final, rule version, attempt, data_as_of, actual calculation times and receipt. No new evaluation is performed. Results are retained seven days; an absent row is unknown / not_measured, never false. Foreign rules return 404. Counts as an ordinary API reference request; Agent keys and x402 are refused. See the #300 temporal contract for retries and replay limits.
Needs a key. Refuses with 401 without one, 429 when the plan’s rate is used up.
What it answers
Section titled “What it answers”| field | type | meaning |
|---|---|---|
rule_id |
string | The rule the decision belongs to. |
instrument |
string | The instrument the decision is for. |
bar_end |
AgentResultInstant |
|
verdict |
true, false, unknown |
true, false or unknown. unknown is its own answer: the data needed to decide was missing or not current, and it is never written as false. |
reason |
string or null | Why the verdict is unknown; null otherwise. |
final |
boolean | Whether the decision is final for its bar. |
version |
string | The version of the rule the decision was made under. |
nominal_t |
AgentResultInstant |
|
data_as_of |
AgentResultInstant |
|
started_at |
AgentResultInstant |
|
finished_at |
AgentResultInstant |
|
attempt |
integer | Which attempt at the bar produced this decision. |
receipt_id |
string or null | The receipt of the evaluation; null when none was recorded. |
GET /v2/archive
Section titled “GET /v2/archive”The files of the archive for one listing: the day, the rows, the size, the sha256, how many gaps the day has, and where to fetch it.
The tick-level history of the core and top-100 groups — trades, ticker, mark and the book’s derived figures — as one Parquet file per listing, layer and UTC day, for the days Postgres no longer holds the raw rows and for the days it still does. ?listing=BINANCE:BTCUSDT is required (the venue’s code, a colon, the venue’s symbol); layer (default: all four), from and to (days, default the last thirty) narrow it. Free with any key and counted against nothing: the list is how you find what to ask for. Only files that were read back from storage and checked are listed. A day on which nothing was observed is listed with available: false and the gaps that say why. anchored is false until the files are anchored.
Needs a key. Refuses with 401 without one, 429 when the plan’s rate is used up.
What it answers
Section titled “What it answers”| field | type | meaning |
|---|---|---|
evaluated_at |
Instant |
The instant the platform evaluated this answer at (UTC). |
served_at |
ServedAt |
The response’s own as-of instant (the same as evaluated_at, six fractional digits). Replay it with as_of. |
receipt_id |
ReceiptId |
Names this exact response. Log it next to the decision made from it. |
listing |
string | The listing, as VENUE:SYMBOL, the venue by the code the platform publishes. |
from |
string | The first UTC day of the span. |
to |
string | The last UTC day of the span. |
truncated |
boolean | More days exist inside the span than the 400 returned; ask for a shorter span. |
items |
array | Oldest first, a day’s layers in alphabetical order. |
GET /v2/archive/{listing}/{layer}/{day}
Section titled “GET /v2/archive/{listing}/{layer}/{day}”One file of the archive, as a 302 to a link that works for fifteen minutes.
{listing} is VENUE:SYMBOL as one path segment (the colon as %3A, a slash in the symbol as %2F); the download of the list is exactly this path. The answer is a redirect: follow it to download. X-Debyko-Sha256 carries the file’s hash and Link points at the day’s entry in the list; the body, for a client that does not follow redirects, says the same and holds the link. A key spends one of its plan’s files for the month (Free and Mini none, Standard 100, Pro 1 000, Pro Plus 10 000; a calendar month, UTC): past them the answer is 402 with the price of this file, X-Debyko-Archive-Remaining says what is left. Without a key, when x402 is on, a file costs 0.10 USDC (core) or 0.05 (top-100), one payment, one file. The link reads this one file and nothing else. The contents are never paged through the API.
Needs a key. Refuses with 401 without one, 429 when the plan’s rate is used up.
GET /v2/stream
Section titled “GET /v2/stream”A live stream of the selected listings, as server-sent events.
One snapshot per listing and layer, then an update for every change — including a change of status with no new value, because a listing going stale is news: the update says stale and why, and carries no value (allow_stale=true puts it under withheld). A heartbeat every fifteen seconds means silence is a broken connection, not a quiet market.
Needs a key. Refuses with 401 without one, 429 when the plan’s rate is used up.
What it answers
Section titled “What it answers”| field | type | meaning |
|---|