Get started

Docs · Concepts

Errors

One envelope for every non-2xx response, and a stable machine-readable code inside it.

The error envelope

Any non-2xx response
{ "error": { "code": "session_not_found", "message": "Verification not found" } }

code is stable and machine-readable. message is human-readable and its wording may change between versions.

Codes

HTTPCodeMeans
400invalid_requestSchema validation failed, or neither/both of template and query were given.
400invalid_idempotency_keyThe Idempotency-Key header isn't 1–255 printable ASCII characters with no spaces.
401invalid_api_keyMissing, malformed, revoked or unknown key. Deliberately indistinguishable.
401api_key_expiredThe key was valid and its deadline has passed. Rotate it.
403insufficient_scopeThe key authenticated but lacks the scope this route needs. The message names it.
404session_not_foundUnknown id, another organisation's id, or an id already erased.
404invalid_response_codeWrong code, already-redeemed code, or unknown session.
409session_already_respondedA wallet response arrived for a session that already had one.
409idempotency_key_in_flightA request with this Idempotency-Key is still being processed. Retry-After carries the lease.
410session_expiredThe session passed expires_at.
422unknown_templateNot a built-in, and no template of yours matches the key.
422invalid_webhook_urlThe URL is refused by the egress policy — private, loopback or link-local.
422idempotency_key_reusedThe same Idempotency-Key was sent with a different request body.
429rate_limit_exceededA per-key, per-IP or per-session budget was exceeded. Back off; the same request will work shortly.
429quota_exceededThe day's verification creations are all spent. Retry-After carries the seconds until midnight UTC; retrying sooner cannot succeed.
500internal_errorOurs. Retry, and tell us if it persists.

Why some errors look unhelpful

Several distinctions are collapsed on purpose. A revoked key and a key that never existed both return invalid_api_key. Another organisation's session id and a nonexistent one both return session_not_found. A wrong response code and a spent one are the same 404.

Each of those pairs, if distinguished, would let anyone with a key probe for what exists outside their own organisation. The cost is that a genuinely confusing 404 stays confusing — check the id against GET /v1/verifications, which only ever lists your own.