Skip to main content
Every failed request returns success: false and an error object. Branch your logic on the stable error.code — never on the HTTP status alone or the human-readable message (which may change).
Stable machine-readable identifier. Match on this.
Human-readable description. For logs and debugging; do not parse.
Optional context. Present on some errors (e.g. the conflicting external_id, or the field map on validation errors).

Validation errors

A malformed request body or query returns 422 VALIDATION_ERROR with details as a map of field → [messages]:

Authentication & account

Returned on any endpoint.

Invoices

POST /external/invoices, GET /external/invoices, GET /external/invoices/{ident}.
INVOICE_ALREADY_EXISTS is idempotency working as intended — the details carry the existing invoice’s status, so you can reconcile without creating a duplicate.

Webhooks

GET /external/invoices/{ident}/webhooks, POST /external/invoices/{ident}/resend-webhook.

Withdrawals

GET /external/withdrawals, GET /external/withdrawals/{withdrawal_uuid}.

Rates

GET /external/rates.

Rate limiting

Returned on any endpoint when limits are exceeded.

Server-side

Handling strategy

Client error — fix the request. Do not blind-retry; the same call fails again.
Back off and retry with exponential backoff.
Transient — retry idempotent calls with backoff. Invoice creation is safe to retry thanks to external_id idempotency.