Errors
A failed request answers in one of three shapes. Most of this page is about the first, because that is where the numeric codes live — but a handler has to recognise all three.
A business error — the request was understood and refused:
{
"code": 2002,
"message": "Failed to create order. \nError: Not enough money"
}
A missing or empty token — no numeric code at all:
{
"statusCode": 401,
"message": "Missing or empty Api-Token header",
"error": "Unauthorized"
}
Request validation — a parameter is missing or malformed. Here message is an
array of strings, one per rule that failed:
{
"statusCode": 400,
"message": ["member_id must be an integer number"],
"error": "Bad Request"
}
Branch on code when it is there, and on statusCode when it is not. Messages
are written for humans, and several of them are filled in at runtime — Failed to create order. Error: <reason> puts the underlying reason into the text, and a few
codes carry a message composed entirely at runtime. Matching on message text will
break.
Shared errors
Every authenticated endpoint can answer with these three, so handle them once rather than per call:
| Code | HTTP | Meaning |
|---|---|---|
| — | 401 | The Api-Token header is missing or empty. No code is returned. |
2008 | 401 | The token does not match any account |
2029 | 400 | Internal error. The message asks you to contact support |
Note that an internal error arrives as 400, not 500.
Validation and lookups
1001 is the general "this value is not acceptable" code, and the message names
the field: member_id does not have a valid value,
dchain_id does not have a valid value, and so on. It covers both a malformed
value and an object that does not exist for your account — the two are not
distinguished.
| Code | HTTP | Meaning |
|---|---|---|
1001 | 400 | A field or path id is invalid, or the object it points at was not found for your account |
1002 | 400 | Not enough money |
1003 | 400 | A withdrawal failed validation on amount, balance or address. The message carries the detail |
2058 | 400 | On a transfer: the amount is not positive, or the sender or recipient has no account for that asset. The message is composed at runtime |
1001 also covers two uniqueness rules: client_order_id is not unique for owner
and client_withdrawal_id is not unique for owner.
Refused operations
| Code | HTTP | Meaning | Where |
|---|---|---|---|
2002 | 400 | The trading core refused the operation. The reason is in the message | orders, withdrawals |
2005 | 400 | The order could not be cancelled — it is a market order, it is no longer open, or the core refused | cancel order |
2020 | 400 | Deposit-address limit reached for this member | create deposit address, create auto-conversion |
2024 | 400 | Market not found, or inactive | orders, auto-conversions |
2066 | 400 | This network needs a destination tag as well as an address | create withdrawal |
Temporarily unavailable
These say "try later" and are not caused by your request:
| Code | HTTP | Meaning |
|---|---|---|
2070 | 400 | Withdrawals are switched off for the moment |
3009 | 400 | The trading core is in maintenance |
3036 | 400 | Address creation is temporarily switched off for one network. The message names it |
2070, 3009 and 3036 are the codes worth retrying, with a backoff. Everything
else is either a bad request or an internal error, and repeating it produces the
same answer — or, on a create call, a duplicate operation.
The health endpoint is different
Health Check does not use this format and does not use HTTP
status to report trouble — it answers 200 either way, with the outcome in the
body. See that page.