Skip to main content

Response envelopes

Successful responses always open with status, message and success: true, in that order. Most endpoints then nest the payload under data, but some return it at the top level beside success — each endpoint’s reference page shows which:
Error responses carry the HTTP code in status and a human-readable message — note there is no success field on errors:
Branch on the HTTP status code (or success === true), not on the presence of status — it is present on both success and error responses, as a number.

HTTP status codes

Validation errors

Requests that fail schema validation return 400 with "message": "Validation failed" and an errors array carrying one entry per offending field. Each entry has a code, a message and a path (an array, because the field may be nested), and the field’s own name is prefixed onto message so a single string is enough to show a user:
Not every 400 carries an errors array. Rejections that come from a domain rule rather than the schema — insufficient balance, an unsupported currency, a duplicate account number — return a descriptive message and nothing else.

Error codes

Some errors additionally carry a machine-readable code at the top level of the body: Errors without a code are identified by their HTTP status and message. Most 403s carry no code — a key that isn’t a white-label tenant calling /accounts or List Transactions Across Accounts, or a request from an IP that isn’t allowlisted, are refused by message alone.

Handling failures in money movement

A payout that fails after being created doesn’t come back as an HTTP error — the transaction moves to failed or rejected and the funds return to your wallet. Listen for transaction.failed webhooks rather than relying on the initial response alone, and see Idempotency & Retries for safely retrying ambiguous requests.