Errors
One shape, a stable status vocabulary, and the cases where a 404 is deliberate.
Every error is the same shape, and the message is written for the person reading it rather than being a stack trace.
{ "error": "Say a little more about what you want." }Status vocabulary
| Status | Meaning |
|---|---|
| 400 | The request was malformed. Fix and retry. |
| 401 | Not signed in, or no valid key. |
| 403 | Authenticated, but the key does not carry the scope this route needs. |
| 404 | Not found — also returned instead of 403 where probing should reveal nothing. |
| 409 | The action conflicts with current state. |
| 413 | Payload above the documented cap. |
| 422 | Valid, but could not be fulfilled. |
| 429 | Rate or spend limit reached for the window. |
| 502 | An upstream provider failed. |
| 503 | A dependency is unavailable. |
404 is sometimes the answer to a permission question
Reading or revoking something that is not yours answers the same way as reading something that does not exist. That is deliberate: distinguishing the two would let a caller enumerate what other people have by watching which error comes back.
Rate limiting
A spend cap is real and returns 429 with a reason in the body. Its thresholds are not a published contract and are not documented here — writing a number down would create a guarantee that does not exist. Read the reason in the response rather than assuming a limit.