Skip to main content
Every accounts error returns the same five-key envelope, so you only need one parser. Branch on errors[0].code, not on the message text — the codes are frozen and will never be renumbered or reused, while messages may be reworded.
Errors are wrapped; successes are not. A successful accounts response is the bare object — there is no data key to unwrap. Only the error path uses this envelope. See Errors and the response envelope.
When the failure is about one specific input, errors[0].field names it, so you can bind the message straight to a form field. When it is not about an input — authentication, rate limits, a provider outage — it is null rather than filled with prose.

What to do about each status

Every code

Two codes cover “you cannot open another account in this currency”. ERRACC_1018 is the ceiling — 10 per currency, active and pending combined. ERRACC_1006 reports that an account already exists for the currency. Match on errors[0].code and handle both, rather than assuming only one of them can reach you.
A 405 and a 415 both carry ERRCORE_1001 — the validation code — rather than a method- or media-specific one. Key off the HTTP status for those two.
A malformed id is a 400, not a 404. ERRREF_1000 means the reference did not parse as an acct_… or wlt_… id at all. ERRREF_1001 means it parsed correctly but resolves to nothing. Different fixes, so they are different codes.

Worked examples

400 · validation

One entry per failed constraint. The envelope message is always the literal Validation Failed, and field names the real property.
400

400 · business rule

A domain error carries its own ERRACC_* code and names the offending parameter.
400

400 · bad reference

A malformed id is a 400, not a 404. A well-formed id that resolves to nothing is the 404.
400

401 · auth

Raised before routing. field is always null on a 401.
401

403 · permission

Either the key lacks the accounts permission, or the customer belongs to another partner. field is always null.
403

404 · not found

Customer and account both report through this shape, distinguished by field.
404

409 · conflict

Three distinct causes: a duplicate account on open, a deactivated account on get, and an operation the provider does not support.
409

429 · rate limit

Read X-RateLimit-Limit and X-RateLimit-Remaining from the response headers. The window is one minute and rejection is immediate — back off rather than retrying tightly.
429

500 · server error

Quote the X-Request-ID response header when you report one.
500

502 / 503 · retryable

Both are safe to retry with backoff — no state was changed.
502 / 503

Retrying safely

The full cross-service catalogue, including the other ERR modules, is on Error codes.