Errors
Every error has the same shape:
{
"error": {
"code": "insufficient_balance",
"class": "client",
"retriable": false,
"message": "the balance does not cover this; nothing was moved",
"detail": {"available": "12.5", "requested": "20"}
}
}
Branch on code, never on the HTTP status. The same status can carry different codes: a 403 is forbidden_scope for your key and not_authorized_for_operation for the person named in the request.
A malformed field or query answers 422 validation_failed in the same envelope, with detail.fields naming each field and why.
Classes
class | Meaning | What to do |
|---|---|---|
client | The request was wrong | Do not retry it unchanged, except where retriable is true (rate_limited, signature_expired) |
server | We failed, or our side is not ready | Retry with backoff. Some of these need us to act first; the code says which |
unresolved | We do not know whether it happened | Do not retry. Read the resource, or wait for the event |
unresolved exists because "not sent" and "maybe sent" are different states. Treating the second as the first is how a payment goes out twice.
Codes
| Code | HTTP | Class | Retriable | Message |
|---|---|---|---|---|
idempotency_key_required | 400 | client | no | Idempotency-Key is required on every POST |
idempotency_key_too_long | 400 | client | no | Idempotency-Key is longer than we can store |
idempotency_key_reused | 422 | client | no | this Idempotency-Key was used with a different request body |
validation_failed | 422 | client | no | the request is invalid |
unauthorized | 401 | client | no | unknown or revoked key |
forbidden_scope | 403 | client | no | this key does not carry the required scope |
not_found | 404 | client | no | no such resource |
no_operation_for_key | 404 | client | no | no committed record under this key |
key_endpoint_unreadable | 403 | client | no | keys for this endpoint cannot be read here |
signature_invalid | 401 | client | no | the request signature is not valid; nothing was done |
signature_expired | 401 | client | yes | the request signature is too old or too new; sign it again |
not_available_yet | 501 | client | no | this capability is not open yet |
not_authorized_for_operation | 403 | client | no | the customer is not permitted to do this |
held_for_review | 409 | client | no | the customer is under review; nothing was submitted |
state_conflict | 409 | client | no | the resource is not in a state that permits this |
tenant_mismatch | 403 | client | no | the request names a tenant other than this key's; nothing was recorded |
rate_stale | 503 | server | yes | we have no current price for this pair right now |
temporarily_halted | 503 | server | yes | money is not moving right now while a discrepancy is looked at |
insufficient_balance | 422 | client | no | the balance does not cover this; nothing was moved |
no_verified_destination | 422 | client | no | there is no verified address to send this currency to; nothing was moved |
daily_limit_exceeded | 422 | client | no | this would pass the daily withdrawal limit; nothing was moved |
destination_not_allowed | 422 | client | no | this destination cannot be paid; nothing was moved |
amount_above_limit | 422 | client | no | this amount is above the per-payout limit; nothing was moved |
private_key_refused | 422 | client | no | a private key is never accepted; nothing was stored |
invalid_xpub | 422 | client | no | not an account-level extended public key for this network |
xpub_exists | 409 | client | no | a live key already derives on this network; retire it first |
xpub_unavailable | 409 | client | no | this key cannot be used |
xpub_range_overlap | 409 | client | no | the range overlaps a live key's range or indices already derived from this key |
xpub_range_exhausted | 409 | client | no | the key's range has fewer addresses left than requested; nothing was derived |
derived_address_unavailable | 409 | client | no | a derived address cannot be registered; nothing was derived |
issuance_not_enabled | 409 | client | no | the Core is not issuing addresses on this network; nothing was issued |
network_not_watched | 409 | client | no | the Core reads no asset on this network; nothing was issued |
seed_not_verified | 409 | client | no | the Core's seed for this network has not been checked; nothing was issued |
seed_range_exhausted | 409 | client | no | the seed's range has fewer addresses left than requested; nothing was issued |
issuance_blocked | 409 | client | no | too many indices of the Core's seed are already taken; nothing was issued |
issuance_cap_reached | 429 | client | yes | this tenant has issued as many Core-held addresses today as the cap allows |
issuance_failed | 409 | client | no | an address the seed derived could not be written; nothing was issued |
rate_limited | 429 | client | yes | too many requests |
internal_error | 500 | server | yes | something failed on our side |
provider_unavailable | 503 | server | yes | the downstream provider is unreachable |
network_not_enabled | 503 | server | yes | chain payouts on this network are not enabled right now; nothing was moved |
wallet_short | 503 | server | yes | your funds in the payout wallet do not cover this yet; nothing was moved |
provider_not_configured | 503 | server | yes | this provider is not configured on our side |
idempotency_key_in_progress | 409 | unresolved | no | a request with this key is still running; poll the resource, do not retry |
outcome_unknown | 502 | unresolved | no | the request reached the provider and the outcome is not yet known; reconcile by reference, do not retry |
Inside a batch of addresses, each refused item carries its own code: unsupported_network, invalid_address, invalid_reference, invalid_watch_from, address_registered, address_unavailable. See Deposit addresses.