Endpoints
Ten endpoints. Four 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. |
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/books |
yes | Order books to the depth the plan allows, with the depth resting in each band around the mid. |
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.
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 |
|
items |
array | The venues, by public code. |
An answer
Section titled “An answer”{ "evaluated_at": "2026-09-23T11:28:26.904Z", "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.
No key. What exists is not a paid fact.
What it answers
Section titled “What it answers”| field | type | meaning |
|---|---|---|
evaluated_at |
Instant |
|
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, quote |
The unit mode applied. |
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", "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", "2m", "3m", "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" }, "trades": { "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 |
|
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", "2m", "3m", "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 |
|---|---|---|
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 }}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. |
units |
published, base, quote |
— | What quantities are expressed in. published leaves each venue’s own unit alone; base and quote convert, and give null with unit_unknown where a contract … |
number_format |
json, string |
— | string returns every number as a string with the same digits, for a client whose JSON parser would round them. |
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 |
|
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. |
freshness |
object | The bound applied to each layer: a reading older than this is stale and compares as unknown. Stated per answer because a request may override it. |
listings_as_of |
NullableInstant |
|
capabilities_as_of |
NullableInstant |
|
instruments |
array | |
page |
Page |
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, "freshness": { "ticker": "30s", "mark": "30s", "oi": "30s", "book": "30s", "stats": "120s", "funding": "300s" }, "instruments": [ { "instrument": "BTC-PERP", "result": "true", "values": {}, "venues": [ { "venue": "BYBIT-PERP", "symbol": "BTCUSDT", "quote": "USDT", "values": { "funding": { "value": 0.00002, "unit": "fraction", "venue": "BYBIT-PERP", "layer": "funding", "venue_ts": null, "received_at": "2026-09-23T11:52:00Z", "age_ms": 485000, "status": "stale" } } }, { "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, "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, "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, "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 |
— | |
units |
published, base, quote |
— | 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. |
What it answers
Section titled “What it answers”| field | type | meaning |
|---|---|---|
evaluated_at |
Instant |
|
units |
published, base, quote |
The unit mode applied. |
freshness |
object | The bound applied to each layer. |
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.
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, quote |
— | 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. from and to do not apply here — the instants are the rows. |
raw |
boolean | — | Every row as it arrived, unsampled. |
from |
Instant |
yes | Start of the window. Required for interval and raw. |
to |
Instant |
yes | End of the window. Required for interval and raw. |
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. |
freshness |
string | — | Override the freshness bound for every layer asked for. |
What it answers
Section titled “What it answers”| field | type | meaning |
|---|---|---|
evaluated_at |
Instant |
|
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 |
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, quote |
The unit mode applied. |
freshness |
object | The bound applied per layer. |
listings_as_of |
NullableInstant |
|
capabilities_as_of |
NullableInstant |
|
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, and exists only when every base minute exists. Gaps are rows, not holes.
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, quote |
— | 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. |
What it answers
Section titled “What it answers”| field | type | meaning |
|---|---|---|
evaluated_at |
Instant |
|
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, quote |
The unit mode applied. |
listings_as_of |
NullableInstant |
|
capabilities_as_of |
NullableInstant |
|
items |
array | One object per listing. |
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 |
— | |
units |
published, base, quote |
— | 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. |
What it answers
Section titled “What it answers”| field | type | meaning |
|---|---|---|
evaluated_at |
Instant |
|
units |
published, base, quote |
The unit mode applied. |
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. |
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. 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 |
|---|