Error Code Reference
All API errors follow the standard envelope format:
{
"success": false,
"data": null,
"error": {
"code": "ERROR_CODE",
"message": "Human-readable description.",
"details": {}
}
}The details field contains field-level validation errors when code = VALIDATION_ERROR.
Error codes
| Code | HTTP Status | Description |
|---|---|---|
UNAUTHORIZED | 401 | Missing or invalid credential |
FORBIDDEN | 403 | Authenticated but not permitted to perform this action |
KYC_REQUIRED | 403 | KYC level insufficient; upgrade in Dashboard → Identity Verification |
NOT_FOUND | 404 | Resource does not exist or does not belong to the authenticated user |
CONFLICT | 409 | State conflict (e.g. invalid state transition, duplicate withdrawal approval token, export job already complete) |
VALIDATION_ERROR | 422 | Request body failed validation; see details for per-field errors |
RATE_LIMIT_EXCEEDED | 429 | API rate limit hit; check Retry-After response header |
INSUFFICIENT_FUNDS | 422 | Account balance is too low for the requested withdrawal |
RATE_STALE | 422 | Exchange rate for the selected token is older than the staleness threshold (30 s) |
MAINTENANCE | 503 | Platform is under maintenance; try again shortly |
INTERNAL_ERROR | 500 | Unexpected server error; contact support if it persists |
On
429, the API returnsRetry-After: 1(per-key rate limiting uses a 1-second window). Limit-related business rules — such as the basic-KYC rolling 24-hour withdrawal cap — surface asVALIDATION_ERRORwith a descriptive message rather than a dedicated code.
Handling specific errors
RATE_LIMIT_EXCEEDED (429)
Read the Retry-After header for the wait time in seconds before retrying.
if response.status_code == 429:
retry_after = int(response.headers.get("Retry-After", 5))
time.sleep(retry_after)VALIDATION_ERROR (422)
Inspect error.details for field-level messages:
{
"error": {
"code": "VALIDATION_ERROR",
"message": "Request validation failed.",
"details": {
"amount_usd": ["Value error, amount_usd must be greater than 0."],
"redirect_url": ["Value error, redirect_url must use HTTPS."]
}
}
}RATE_STALE (422)
The rate worker has not produced a fresh rate for the selected token. This is a transient condition. Wait a few seconds and retry, or have the payer select a different token.
MAINTENANCE (503)
The platform is temporarily under maintenance. The response body contains the maintenance message:
{
"error": {
"code": "MAINTENANCE",
"message": "We are performing scheduled maintenance. Back online at 14:00 UTC.",
"details": {}
}
}The /health endpoint, GET /v1/brand, and admin/auth routes are exempt from maintenance mode. Maintenance can also be scoped to only deposit routes (/v1/pay*, /v1/payments*) or only withdrawal routes (/v1/withdrawals*).

