Errors
One envelope for every error, with stable machine-readable types.
Every error response (auth failures, validation rejections, rate limits, server faults) carries the same JSON envelope:
type: a stable, machine-readable identifier. Branch on this, never onmessage.message: human-readable detail. Wording can change without notice.request_id: matches theX-Request-IDresponse header. Include it when contacting support; it lets us find the exact request.details: optional object of string values carrying the narrow, contract-level context a caller needs in order to act (for examplecurrent_versionon a409version conflict, or the reservation figures oninsufficient_credits). Absent when there is nothing actionable to add. Onvalidation_failedit maps each offending field to its message.
Adding a new type is a non-breaking change; renaming or removing one is
breaking and versioned. Treat an unrecognized type according to its HTTP
status class.
Status codes
Common error types
Embed sessions have their own type family. At mint time
(POST /api/embed/sessions): embed_scope_exceeds_key and
embed_scope_not_allowed, both 400, and embed_origin_not_allowed, 403, when
the mint request carries an Origin header that is outside the key’s allowed
origins. When a session token is used: invalid_embed_token,
embed_token_expired and embed_session_not_found (a revoked session), all
401, and embed_session_binding_mismatch, 403, when the token reaches a loan
or borrower it was not minted for. On the iframe handle exchange:
invalid_session_handle, session_handle_already_used and
session_handle_expired, all 401, and same_origin_required, 403. The
Embed flow describes when each arises.