Two envelopes exist, one per surface, and both are stable vocabulary: match
on code, never on detail.
The identity surface
{ "code": "stale_generation", "retryable": false }detail is omitted except for backend_unavailable, which carries
"try again later" and is the only retryable identity code. The rest:
| Status | Codes |
|---|---|
| 400 | invalid_input, request_expired, unsupported_owner_authenticator, malformed_owner_authenticator, agent_id_allocation_mismatch |
| 401 | invalid_owner_signature |
| 403 | owner_authenticator_address_mismatch, registered_owner_mismatch |
| 404 | unknown_agent, unknown_key_generation |
| 409 | agent_id_conflict, stale_generation, agent_key_history_capacity_reached |
| 410 | registration_expired, agent_revoked |
| 413 | invalid_input — only when the declared Content-Length exceeds 65536; an undeclared overrun answers 400 |
| 503 | backend_unavailable — not ready, shutting down, body-read timeout, or the 10-second request deadline |
The playground surface (Preview)
Same shape, its own codes. Retryable: retryable (backend) and
authority_unavailable — the authority did not answer and nothing
moved, so asking again is safe. Notable non-retryables:
offer_not_open (the state refuses the move), offer_expired (410),
duplicate_acceptance_conflict (a different acceptance already holds the
seat — a byte-identical resubmission would instead have answered 200),
agent_declined, seat_mismatch, wrong_key_generation,
invalid_acceptance_signature. Oversized bodies on this surface answer
400 bad_request, not 413.
One caveat for clients
Was this helpful?