code field. Your integration should branch on code, not on human-readable message text.
Response shape
code is always one of the enum values below. details varies per code and carries the contextual info you need to act.
Categories
Balance errors (400)
INSUFFICIENT_BALANCE— spend > availableHOLD_EXCEEDS_BALANCE— a hold would exceed availableCURRENCY_MISMATCH— source and destination currencies don’t match (cross-border needs a quote)NEGATIVE_BALANCE_NOT_ALLOWED— operation would leave a negative balance
Validation (400, 422)
INVALID_AMOUNT,INVALID_CURRENCYINVALID_ACCOUNT_ID,INVALID_AGENT_ID,INVALID_TRANSFER_IDINVALID_PIX_KEY,INVALID_CLABE,INVALID_IBAN,INVALID_SWIFT_CODEINVALID_EMAIL,INVALID_PHONEINVALID_DATE_RANGE,INVALID_FLOW_RATEINVALID_MANDATE,INVALID_CHECKOUT_SESSIONMISSING_REQUIRED_FIELD,INVALID_REQUEST_FORMATAMOUNT_TOO_SMALL,AMOUNT_TOO_LARGE
Authentication (401)
INVALID_API_KEY— key not recognizedEXPIRED_API_KEY— key revokedINVALID_AGENT_TOKEN,INVALID_SESSION_TOKENSESSION_EXPIRED— re-run Ed25519 handshakeINVALID_JWT,EXPIRED_JWTMISSING_AUTH_HEADER,MALFORMED_AUTH_HEADERENVIRONMENT_MISMATCH— test key on prod URL (or vice versa)
Authorization (403)
FORBIDDEN— generic “not allowed”INSUFFICIENT_SCOPE— API key lacks required scopeKYA_LIMIT_EXCEEDED— agent KYA tier limit exceededKYC_LIMIT_EXCEEDED— account KYC tier limit exceededPOLICY_VIOLATION— wallet policy rule violationWALLET_FROZEN— wallet frozen, cannot spendAGENT_SUSPENDED— agent suspendedMERCHANT_BLOCKED— merchant blocked by policyVELOCITY_EXCEEDED— too many tx in windowTIME_RULE_VIOLATION— outside allowed hoursREQUIRES_APPROVAL— approval workflow triggered (not an error — next step is/v1/approvals)
Not found (404)
ACCOUNT_NOT_FOUND,AGENT_NOT_FOUND,WALLET_NOT_FOUND,TRANSFER_NOT_FOUNDSTREAM_NOT_FOUND,QUOTE_NOT_FOUND,MANDATE_NOT_FOUNDWEBHOOK_NOT_FOUND
Conflict (409)
IDEMPOTENCY_KEY_REUSED— same key with different parametersDUPLICATE_RESOURCE— resource with same unique key already existsSTATE_TRANSITION_INVALID— operation not allowed in current state (e.g. completing a cancelled transfer)
Quote / settlement (400, 402)
QUOTE_EXPIREDQUOTE_RATE_CHANGEDSETTLEMENT_RAIL_UNAVAILABLERAIL_DECLINED,RAIL_TIMEOUTX402_PAYMENT_REQUIRED—402returned by an x402-gated endpoint (includes payment quote)X402_PROOF_INVALID,X402_PROOF_EXPIRED
Rate limit (429)
RATE_LIMIT_EXCEEDED— honorRetry-After
Server (500, 502, 503, 504)
INTERNAL_ERROR— retry with backoffSERVICE_UNAVAILABLE— retry with backoffUPSTREAM_TIMEOUT— retry with backoffDATABASE_ERROR— retry; if persistent, open a support ticket
Compliance (400, 403)
SANCTIONS_HIT— counterparty on sanctions listKYC_REQUIRED,KYB_REQUIREDHIGH_RISK_TRANSACTION— manual review triggeredBLOCKED_COUNTRY,BLOCKED_ADDRESS
Suggested actions
The error object often includessuggested_action:
endpoint can be invoked directly to self-remediate.
Retriable vs. permanent
Retriable (with backoff):RATE_LIMIT_EXCEEDEDINTERNAL_ERROR,SERVICE_UNAVAILABLE,UPSTREAM_TIMEOUT,DATABASE_ERROR
Request ID
Every error response carriesrequest_id. Include this in support tickets; we can pull the full trace in seconds.