Error Code Reference
All API errors follow the standard envelope format:
json
{
"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 (API key or session token) |
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 | Resource already exists (e.g. duplicate email on registration) |
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 |
DAILY_LIMIT_EXCEEDED | 422 | Daily withdrawal limit reached for your KYC tier |
WALLET_COOLING_PERIOD | 422 | Withdrawal wallet was added less than 24 hours ago |
RATE_STALE | 422 | Exchange rate for the selected token is older than the staleness threshold |
MAINTENANCE | 503 | Platform is under maintenance; try again shortly |
INTERNAL_ERROR | 500 | Unexpected server error; contact support if it persists |
Handling specific errors
RATE_LIMIT_EXCEEDED (429)
Read the Retry-After header for the wait time in seconds before retrying.
python
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:
json
{
"error": {
"code": "VALIDATION_ERROR",
"message": "Request validation failed.",
"details": {
"amount_usd": ["amount_usd must be at least $1.00."],
"redirect_url": ["redirect_url must start with 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:
json
{
"error": {
"code": "MAINTENANCE",
"message": "We are performing scheduled maintenance. Back online at 14:00 UTC.",
"details": {}
}
}The /health endpoint and payment status polling (GET /v1/pay/{id}/status) are exempt from maintenance mode.

