Errors
Every error the partner API returns is a JSON object with a stable numeric code, the domain it belongs to and a human-readable message. Branch on the pair domain + code. Do not parse message: it is meant for logs and may gain detail over time.
{
"code": 10016,
"domain": 100,
"message": "invalid id format"
}
| Field | Type | Description |
|---|---|---|
code | number | Error identifier. Codes 10000–10018 belong to the common domain (100); every other area (token, node, fee, KYC, OTC, …) has its own domain and codes, listed on each endpoint's page. The same number can appear in several domains (for example 10001 is "not found" in many of them), so identify an error by the pair domain + code. |
domain | number | The area the error comes from. 100 is the common domain shared by every endpoint. |
message | string | Short English description. |
details | array | Only on validation failures, see below. |
Validation failures
A request that fails validation (a missing required field, a value out of range, a malformed amount) is answered with HTTP 400 and code 10015. details names every field to correct, using the name the request sends (the JSON key, query or path parameter):
{
"code": 10015,
"domain": 100,
"message": "invalid request payload: wallet_id: Validation failed on the 'required' tag",
"details": [
{ "field": "wallet_id", "message": "Validation failed on the 'required' tag" }
]
}
Some handlers refuse a value only they can check (one that needs the stored record) with the same shape. A few domain errors reuse the number 10015 in their own domain without details (for example domain 1, "wallet does not belong to this user on this network"), which is why domain matters. Amount and percentage rules are on Amounts and Percentages.
HTTP status
| Status | When |
|---|---|
400 | The request was refused: validation (10015), a malformed id (10016) or a domain rule (the endpoint's own codes). Most domain errors, including most "not found" errors, answer 400; each endpoint page lists its codes and statuses. |
401 | Authentication failed: missing, malformed or expired access token, an unknown client, an IP outside the client's allow-list, or a certificate that does not match the client. The body is the generic {"code": -1, "domain": 100, "message": "unexpected error"}; the status is the signal. |
403 | The token is valid but lacks the permission the endpoint requires (refused at the gateway). |
404 | The route does not exist (refused at the gateway). A few endpoints also answer 404 for a missing record; their pages say so. |
409 | The operation conflicts with the record's current state (for example a deploy already in progress), where the endpoint says so. |
429 | Rate limit (10011) or monthly usage limit (10012) exceeded. See Usages / Score. |
500 | Unexpected server-side failure (10000). Safe to retry idempotent reads; for writes, check the resource or its transaction before retrying. |
Common codes
| Code | Status | Message | Meaning |
|---|---|---|---|
-1 | 401 / 404 / 405 | unexpected error | Framework-level refusal: authentication failed, the route or method does not exist. |
10000 | 500 (sometimes 400) | unexpected error | An unexpected failure, usually a store or transport failure. The cause stays server-side. |
10001 | 401 | token expired | The access token expired. Refresh it with the refresh_token grant. |
10011 | 429 | rate limit exceeded | Per-second / minute / hour limit hit. Wait for Retry-After. |
10012 | 429 | monthly usage limit exceeded | The client's monthly score quota is used up. |
10013 | 500 | missing client id | The token carries no client id. Request a new token. |
10015 | 400 | invalid request payload | Validation failure, see above. |
10016 | 400 | invalid id format | A path or body id is not a valid 24-character hex id. |
10017 | — | transaction failed | Recorded on a transaction that custody or the chain reported as failed; read it from the transaction's error field. |
10018 | — | transaction is already settled | A second status update reached a transaction that was already done or error. |
Asynchronous operations
On-chain operations (deploy, mint, burn, rent, OTC accept, withdraw, …) are accepted with 200 and settle later. A failure after acceptance does not turn into an HTTP error: the operation's transaction ends in status 4 (error) with the reason in its error field; success is status 3 (done). Statuses 1 (started), 2 (in progress) and 5 (pending receipt) are intermediate. Each async endpoint names the transaction read to poll.