API Conventions
These rules hold across the API and are not repeated on the endpoint pages.
These rules hold across every endpoint, so they are stated once here rather than repeated on each page. The API is also browsable as a Swagger UI if you want to try a call.
Base URL and paths
All requests go to https://api.example.com, and every public path carries the /api
prefix:
https://api.example.com/api/withdrawals
Authentication
Every request carries the merchant's token in the Api-Token header:
Api-Token: YOUR_API_TOKEN
One endpoint is public and needs no token: GET /api/health. Everything else
requires it. See Authentication.
Status codes
| Method | Success status |
|---|---|
GET | 200 |
POST | 201 |
DELETE | 200 |
A create therefore answers 201, not 200 — branch accordingly.
Content type
Request bodies are JSON and must be sent with
Content-Type: application/json.
Lists and pagination
Every list endpoint is paginated through two query parameters:
| Parameter | Default | Range |
|---|---|---|
page | 1 | from 1 |
per_page | 20 | 1 – 1000 |
A list does not return a bare array. It returns an envelope with the page metadata beside the rows:
{
"total_count": 137,
"per_page": 20,
"total_pages": 7,
"page": 1,
"prev_page": null,
"next_page": 2,
"items": []
}
prev_page and next_page are null at the ends of the range. Read the rows
from items.
Paginated endpoints are the eleven collection routes: assets, markets, members, deposit addresses, orders, trades, deposits, withdrawals, auto-conversions, transfers and webhooks.
Two kinds of response are not paginated and come back as plain values:
- single-object reads —
GET /api/…/{id}; GET /api/members/{id}/accounts, which returns a bare array of accounts.
No list endpoint applies an explicit sort. Row order is not guaranteed — not by
id, not by created_at, not between two identical requests. sort and sort_by
are not supported and are silently ignored.
Because the underlying selection is unordered, paging through it can return the same row twice and skip others entirely. Page 2 is not "the rows after page 1".
What to do instead:
- For a bounded set, ask for it in one page —
per_pagegoes up to1000— and sort it yourself. - For anything larger, page through it, deduplicate by
id, and accept that a single pass may be incomplete; repeat until the set stops changing. - Never build "the newest N" by reading page 1.
Data types
| Value | Wire format | Notes |
|---|---|---|
| Identifiers | JSON number | 90210. Used in paths and in query filters. |
| Client-supplied ids | JSON string | client_order_id and client_withdrawal_id are strings, not numbers. |
| Amounts, in a response | JSON string | min_withdrawal, min_deposit and every fee field come back as decimal strings such as "1.000000". |
| Amounts, in a request | string or number | amount, price and volume accept either. Sending a string avoids float rounding. |
| Booleans | real JSON boolean | active_deposit, active_withdrawal, aml_active. |
precision | JSON number | Decimal places of a network's asset. |
| Timestamps | ISO 8601 string, UTC, milliseconds | 2026-08-28T13:25:11.098Z. Same format on the way in — expired_at is sent this way. |
Every amount field accepts a string, and every amount comes back as a string.
Keeping money in strings end to end removes the whole class of float-rounding
bugs — "0.1" stays "0.1".
Idempotency
No endpoint enforces an idempotency key. client_withdrawal_id on a payout
and client_order_id on an order are optional, and the transfer body has no
client-id field at all.
Because nothing is enforced, a payout or a transfer sent twice — a timeout, a
retry, a double click — may move the money twice. Guard against it on your side:
create the operation once, record the id you get back, and use the list filters
(client_withdrawal_id on payouts, client_order_id on orders) to check whether
a request landed before retrying it.
Whether the service deduplicates internally when the same client_withdrawal_id
is reused is not documented — do not rely on it either way until confirmed.
Field naming
The same value can be spelled differently on the way in and on the way out. Two cases to know:
| Operation | In the request | In the response |
|---|---|---|
| Transfer | asset | asset_id |
| Auto-conversion | dchain_from, asset_to | dchain_from_id, asset_to_id, plus asset_from_id |
Inside an object an identifier is plain id — a member is id, not member_id,
and an account is id, not account_id. The member_id and account_id
spellings appear only where one object points at another.
Permissions
There is no scope or permission concept: one token does everything. See Authentication.
Errors
A failure answers with a numeric code and a message. Branch on the code; the
messages are for humans and some are composed at runtime. The full catalogue is in
Errors.