Errors and limits
Error shape
Errors return a JSON body with a stable machine-readable code alongside the HTTP
status. Branch on the code, not on the message text - messages are written for
humans and are localised, so they change.
Status codes
| Status | Meaning |
|---|---|
400 | The request was malformed or a value was invalid. |
401 | Missing or invalid API key. |
403 | Authenticated, but not allowed to do this. |
404 | It does not exist, or it is not in this organization. |
409 | It conflicts with the current state - e.g. a session that already finished. |
422 | The request was understood but the content was not valid. |
429 | Rate limited. |
5xx | Something went wrong on our side. |
A resource in another organization returns 404, not 403. That is deliberate:
telling you something exists but is not yours is itself a disclosure.
Rate limits
Requests are rate limited per organization. On 429, back off and retry - exponential
backoff with jitter, not a tight loop.
Retrying
5xx and 429 are worth retrying. 4xx other than 429 will fail again the same
way, so fix the request instead.
Make retries safe: key on your own identifier so a retried call cannot become a second real phone call.