Skip to main content
These rules hold on every endpoint, so a client can implement them once. The examples come from one script, samples/http/conventions.sh, which reads them from live answers and stops if one is broken. It only lists assets and asks for one quote: nothing is ordered.
The API may change until launch. Every change is listed in the Changelog.

Requests

Values

Output on test networks

Paging

A list that pages takes limit and answers nextCursor. Send it back as cursor until nextCursor is absent. A cursor is valid while the list it came from is unchanged: after a change it answers 409 CURSOR_STALE, and you start again from the first page. GET /api/v1/assets pages this way, from 1 to 200 assets a page, and GET /api/v1/orders, up to 20 orders a page. An order page can hold fewer than limit orders, even none, while more follow: stop only when nextCursor is absent or null.
Output on test networks

Errors

Every refusal is one JSON body with the same fields: error, message, requestId, timestamp, docUrl, and next and details when they apply. Each code has one HTTP status, and docUrl links its entry in the error-code reference. Match on error, never on message. Errors and refusals shows how to read one, and the error-code reference lists every code.

Request ids

Every response carries an X-Request-Id header, and every refusal carries the same value as requestId. Quote it to support. You can send your own X-Request-Id, up to 64 letters, digits, - and _, to find a request in your logs and ours. The response echoes it. A value outside that form is replaced with a generated UUID, and the response carries that instead.
Output on test networks

Rate limits

You may send one live quote request every 3 seconds per API key; a requote counts as one. A request answered entirely from cached prices does not count. A request over a limit answers 429 with a Retry-After header in whole seconds and the same wait in details.retryAfter, for example PT2S. Wait that long, then send it once more. Errors and refusals shows a retry. When your key has a per-minute limit, every answer to it, successes and refusals alike, carries three headers: Without a per-key limit, as in the output above, the headers are absent; X-RateLimit-Remaining alone can still appear when a limit on your address counted the request. Treat an absent header as “no count”, never as zero.

Idempotency

Send an Idempotency-Key with every POST /api/v1/orders. A retry with the same key and body returns the first answer, with the header Idempotent-Replayed: true. The same key with a different body is refused. Idempotency covers replays, conflicts and recovering an order.

Versioning

The API is versioned in its path, /api/v1. After launch, changes within a version are additive: new operations, optional fields, headers, enumeration values and error codes. A removal is announced in the changelog at least 6 months ahead. Until it happens, every answer of the affected operation, successes and refusals alike, carries three headers: No operation is deprecated today, so no answer carries them yet. Log any answer that does. Before launch, a change can still remove or rename something. Compatibility is the full policy. The Changelog lists every change a client can see, with what to do about it.