API reference/Errors

Get started

Errors

Every error response has the same shape. The code is stable and safe to switch on; the message is human-readable and may change.

Error bodyjson
{
  "error": {
    "code": "invalid_state_transition",
    "message": "Invalid B2B transition: released → cancelled",
    "current_state": "released",
    "allowed_next_states": []
  }
}

HTTP status policy

StatusMeaning
400Request shape invalid (validation, unknown cursor, etc.)
401Authentication missing or invalid (raw key, session JWT, access token)
403Authenticated but lacks scope / permission / account suspended
404Resource not found OR not owned by the caller (cross-tenant denial)
409State-machine conflict — includes current_state + allowed_next_states
429Rate limit exceeded — Retry-After header supplied
500Unexpected error; correlate via server logs
502Downstream (Stripe) error — safe to retry idempotent calls

Tenancy semantics

Cross-tenant access returns 404, not 403. The API never discloses the existence of resources the caller does not own. Only the owning account sees a 404 for genuinely deleted resources; everyone else sees the same 404 they'd get for a resource that never existed.

Retry guidance

Safe to retry: any 502 (downstream Stripe), any 5XX, any 429 after the Retry-After header. Mutating endpoints (create, cancel, release) are idempotent either by external_reference (create) or by terminal-state absorption (cancel/release), so retries don't duplicate work.

Do not retry: 400, 401, 403, 404, 409. The request will fail the same way every time until you fix the call site or the underlying resource state.