Reference data guide
The conventions every resource follows. The reference documents each resource; this page covers what they have in common.
Authentication
Every request carries a bearer token: Authorization: Bearer <token>. A missing, expired or
foreign token is 401 UNAUTHENTICATED, with a WWW-Authenticate header naming the problem.
Values
- Ids are opaque strings, named after their entity:
venueId,instrumentId. An id that does not exist is404 NOT_FOUND, whatever its shape. - Numbers — prices, quantities, amounts — are exact decimal strings such as
"0.0000001115". Parse them as decimals, never as floating point. The number of digits carries no meaning. - Times are epoch-nanosecond strings named
…AtNsor…TsNs. - Absent values are always present, as
null. - Enums are UPPER_SNAKE and only ever grow. Tolerate values you don’t know.
Lists
Every collection returns one page at a time:
limitsets the page size: 1 to 100, default 50. Larger values are reduced to 100, never refused.- To move, send
nextCursororprevCursorback ascursor, with the same filters and sort. A cursor is bound to the query it came from. - A cursor the API cannot use — edited, expired by a key rotation, or sent with a different
query — is
400 INVALID_CURSOR. Drop it and fetch the first page again. sorttakes comma-separated properties; a leading-sorts descending. The order is always complete: ties are broken by the id, and absent values sort last, in both directions. On instruments, a statistic is absent for an instrument that has never traded, a 24-hour one while its window is still warming, and any the projection cannot state, such as a turnover it has no price to value.includeopts into extras, comma-separated. Every collection offerstotal, the exact count of matching items (nullotherwise). Instruments also offerfacets(counts per venue, type, base asset and quote asset, each counted under your filters minus that dimension’s own, so a filter panel keeps showing its alternatives) andticker(each row’s latest statistics).- Filters are plain query parameters. Repeat a parameter, comma-separate its values, or both, for
“any of”:
venueId=300&venueId=301isvenueId=300,301. Different parameters narrow together:type=SPOT&venueId=300is the spot markets of venue 300. A parameter the resource does not accept is400 MALFORMED_REQUEST, so a misspelt filter never silently returns the unfiltered list. A filter value that matches nothing is an empty page: an unknown code or symbol, or an id that is not exactly one. A filter that takes an alias in place of an id (venue=okx,baseAsset=BTC) ignores case. An enum filter refuses a value it has never heard of (type=CRYPTO) with400 MALFORMED_REQUEST. It accepts every documented value and every value its rows carry, removed rows included, so a value you were served stays valid: enums only grow. - The
.notInsuffix excludes instead:venueId.notIn=10matches every venue but that one. Where a resource offers ranges it documents.gteand.ltethe same way. searchis case-insensitive and resource-specific. Instruments match word prefixes of the symbol’s tokens, the venue’s own symbol, the type and the id:btc usdtfindsOKX@BTC/USDT:USDT,perpfinds every perpetual swap. Venues match a substring of the code or display name; assets match a substring of the symbol.
Symbols
Every instrument has one canonical symbol, byte-identical to the symbol on the market-data
stream, in the grammar VENUE@BASE/QUOTE[:SETTLE[-DDMmmYY[-STRIKE-C|P]]]:
VENUE is the venue code upper-cased; SETTLE is the asset the contract settles in; the date
is the day, the month’s three-letter name and a two-digit year; STRIKE is the strike price.
A lookup by symbol is case-insensitive; the symbol served always uses this spelling.
GET /instruments?symbol=OKX@BTC/USDT&symbol=okx@btc/usdt:usdt-25JUN27 looks up to 100 symbols in
one request; send limit=100 to get a whole batch in one page. A symbol that names no instrument
is simply absent from the page. More than 100 is 400 MALFORMED_REQUEST, a symbol sent twice
counting twice: split a longer list into batches. The request line and headers may run to 16 KB,
room for a batch of the longest symbols and a bearer token.
A dated product’s maturity is DDMmmYY and nothing else. A name stored with the older
YYYYMMDD maturity, such as OKX@BTC/USDT:USDT-20270625 for OKX@BTC/USDT:USDT-25Jun27, finds
nothing: convert it before looking it up.
Freshness
Reads carry the position of the event stream they reflect: the X-Immix-As-Of-Seq-Ts header,
and asOfSeqTsNs in list pages. It is a sequencer timestamp in epoch nanoseconds, the same clock
as seqTs on stream frames: every stream message at or before it is reflected in the response,
so you can apply stream updates after it without gaps or repeats. A response built from several
sources reports the oldest: an instruments page, which joins the catalogue with the latest
statistics, reports the older of the two. When the position is unknown, the header is omitted and
asOfSeqTsNs is null.
Errors
Every error uses one envelope:
Branch on code, never on message. retryable says whether the same request may succeed
later. Quote requestId (also the X-Request-Id header) when you contact support.
Codes are append-only: new ones will appear, and existing ones never change meaning.