Browse the docs

Guide

Errors

Errors are JSON with a stable machine-readable code and a human-readable message. Branch on the code; show the message to a person.

The envelope

404 · application/json
{
  "defined": true,
  "code": "NOT_FOUND",
  "status": 404,
  "message": "Account not found"
}
  • code — stable identifier, one of the values below. Safe to switch on.
  • status — the HTTP status, repeated in the body for clients that lose it.
  • message — for humans. Wording may change; do not parse it.
  • data — optional structured detail, documented per code below.
  • definedtrue when the error is one this operation documents in the reference. You can ignore it.

Codes

StatusCodeMeaning
400BAD_REQUESTThe request failed validation: a missing required field, a value out of range, an invalid IBAN, or a malformed cursor. `data.issues` lists the offending fields when validation produced them.
401UNAUTHORIZEDNo API key, or a key that is malformed, unknown, revoked or expired. The message says which.
403FORBIDDENThe key is valid but lacks a scope this operation requires. `data.requiredScopes` names it.
404NOT_FOUNDNo such resource in your workspace — including ids that exist in another workspace, which are indistinguishable from ids that do not exist at all. Also returned for a `companyId` filter that is not one of your companies, and for unknown routes.
409CONFLICTThe write collides with an existing row — for example a payee with the same IBAN already exists for that company.
429TOO_MANY_REQUESTSRate limit exceeded. Wait for the number of seconds in the `Retry-After` header before retrying.
500INTERNAL_SERVER_ERRORSomething failed on our side. The response is deliberately generic; the incident is recorded with a trace. Retry with backoff.

Retrying

Retry 429 after Retry-After seconds and 5xx with exponential backoff (start around one second, cap at a minute). Never retry 4xx other than 429 without changing the request — the answer will be the same. Reads are idempotent; the v1 write operations (payees) are safe to retry too because a duplicate create returns 409 rather than a second row.