Conventions
Rules that hold across the entire API. Learn these once; every endpoint obeys them.
Response envelope
Every JSON response — success or error — uses the same outer envelope:
{
"data": { "...": "operation-specific payload" },
"correlation_id": "8c2c0e9a-3fab-4d8e-9b51-26c5f7e0c1aa"
}
{
"error": {
"code": "insufficient_funds",
"message": "available 200000, required 550000",
"details": { "asset_id": 1, "required": 550000, "available": 200000 }
},
"correlation_id": "8c2c0e9a-3fab-4d8e-9b51-26c5f7e0c1aa"
}
error.code is machine-readable — switch on it. error.message is for
operators and logs, not end users. The full code table is on the
Errors page.
Prices: integer pips
Prices are integer pips. Integer pricing keeps the matching engine,
ledger, and API free of floating-point drift. Each instrument's
contract spec defines its tick economics (tick_size_uusdc — the value
of one pip step per contract).
Cash: atomic units
USDC amounts are integer atomic units: 1 atomic = 10⁻⁶ USDC.
| Display amount | Wire value |
|---|---|
| $1.00 | 1000000 |
| $1,000 | 1000000000 |
| $1,000,000 | 1000000000000 |
Divide by 1,000,000 for display. Large values arrive as JSON numbers within int64 range — parse with 64-bit integers, not floats.
Contract counts
count / quantity fields are whole contract counts. No fractional
contracts exist anywhere on the venue.
Timestamps
- Fields named
*_at_nsare int64 Unix nanoseconds — the canonical internal timestamp. - Fields named
*_unix_secondsare int64 Unix seconds (candle bar windows only). - Two engine-clock fields carry millisecond precision in nanosecond
units:
ts_nson fills andsequencer_committed_at_nson order responses. Their reference pages flag it.
Correlation IDs
Two distinct correlation fields exist:
| Where | Type | Source |
|---|---|---|
Envelope: correlation_id | string | Per-request UUID v4 (or your X-Correlation-ID) |
Inside data: data.correlation_id | int64 | Engine-side correlation, echoed in WS push events |
Quote the string one in support requests; join HTTP responses to WS events with the int64 one.
Pagination
Collection endpoints take a limit query parameter (default 100, max
1000). GET /v1/instruments/{id}/trades additionally supports cursor
paging via an opaque next_cursor. Each reference page states what it
supports.
Request limits
Request bodies are capped at 64 KiB — over-limit requests receive
HTTP 413 (payload_too_large). JSON bodies with unknown fields are
rejected (invalid_request): the API is strict about its schemas.
Two views of an instrument
The surface deliberately exposes an instrument through two route families backed by two services — a design decision, not an accident:
/v1/instruments* — the engine's view | /v1/instrument/* — the instrument service's view | |
|---|---|---|
| Carries | Matching state, order books, candles, trade tape | Full metadata: lifecycle, resolution criterion, closes-at |
| State machine | Matching gate (trading vs not) | Listing lifecycle (LISTED → TRADING → PENDING → FINAL) |
| Use it for | "Can I trade this right now?" — books, candles, tape | "What is this contract?" — detail pages, resolution flows |
The two state machines can legitimately disagree for short windows during listing transitions. Trust the engine view for tradability and the instrument service view for contract identity.