The contract
Refusals and HTTP codes
The HTTP code is chosen by the remedy, not by resemblance: who has to do something, and what.
Last updated
| reason | HTTP | meaning |
|---|---|---|
invalid_input | 400 | The payload does not match the contract. The only one on this list you can fix on your own. |
unauthorized | 401 | The credential is not valid. Nonexistent, revoked, expired or lacking the scope are not distinguished on purpose. |
grant_off | 403 | The workspace has not switched this capability on. Not a prohibition: a switch that belongs to its owner. |
origin_denied | 403 | This origin cannot exercise this action, and no switch changes that. |
not_autonomous | 409 | It needs an approval and this path cannot wait for it. |
stale | 409 | The world changed between the request and the act — or the request points at something that does not resolve. detail.why names it and detail.message says what to do. |
duplicate | 409 | It already happened. Carries the key and how the first attempt ended. |
in_flight | 409 | Another request with the same key is running right now. Carries Retry-After. |
not_exposed | 404 | That action is not open to the outside. It may exist inside the product; what does not exist is its door. |
version_retired | 410 | That version has been retired. Comes with a Sunset header and the dates inside. |
rate_limited | 429 | Per-key quota. Carries Retry-After. |
internal_error | 500 | A fault on our side. The only one on this list that is neither a decision nor a state. |
Reasons only reads give
Besides the general list, a read can answer with these. The ones a read declares are on its page and in the SDK types.
| reason | HTTP | meaning |
|---|---|---|
reads_need_a_person | 403 | The credential is an API key. A read is done on behalf of a person: connect with OAuth. |
role_forbidden | 403 | The person who authorized the app cannot see this on their own screen. The workspace owner or an admin can change their role. |
ambiguous | 409 | The name matches several clients. detail.candidates lists them: ask again with one. |
not_found | 409 | No client matches the name. detail.searched says what was looked for. |
Per-action reasons
Besides the general list, every action names its own reasons for stale — the candidates of an ambiguous name, the stages that do exist. They are listed on each action's page and in the SDK types.