Reference
Errors and limits
Offhook uses standard HTTP status codes. Error responses explain the problem in detail, and failed calls carry an error_code that never changes meaning.
{ "detail": "agent not found" } HTTP status codes
| Status | Meaning |
|---|---|
200, 201 | Success. |
204 | Success with no body, after a delete. |
401 | The API key is missing, wrong, expired or revoked. |
403 | The tenant is deactivated, or a carrier request failed its check. |
404 | Not found. You also get this for things that belong to another tenant. |
409 | Conflict: for example a duplicate name, a connection still in use, or an Idempotency-Key reused with a different body. |
422 | The request is invalid: a field is missing, has the wrong type, or refers to something that doesn't exist. |
429 | Too many requests, or a call quota is reached. Wait for Retry-After, then retry. |
Call error codes
When a call ends as failed, its error_code (on the call and on the call.failed event) is one of these:
| Code | Meaning |
|---|---|
carrier_unauthorized | The carrier rejected your telephony credentials. |
carrier_error | The carrier returned an error while dialing. |
busy | The line was busy. |
no_answer | Nobody answered before the call timed out. |
rejected | The call was rejected. |
invalid_number | The number doesn't exist or isn't in service. |
no_media | The carrier connected but no audio stream started, for example on a Twilio trial account when the callee didn't press a key. |
config_error | An agent connection was missing or invalid when the call was dialed. |
provider_timeout | A speech-to-text, text-to-speech or language model provider timed out. |
pipeline_error | The conversation pipeline failed during the call. |
unknown_error | Something failed that doesn't fit the codes above. The call's error field has the details. |
Rate limits
Each tenant can make a fixed number of requests per minute (120 by default). Over the
limit, the API returns 429 with a Retry-After header. Wait
that long, then retry.
Call quotas
POST /v1/calls also checks two quotas per tenant:
- Concurrent calls: how many calls can be queued, dialing or in progress at once (10 by default).
- Monthly cap: an optional limit on calls per calendar month.
Going over either returns 429, with the reason in detail.
Idempotency
Send an Idempotency-Key header with POST /v1/calls to make
retries safe. The first request is processed and its response saved. A retry with the
same key gets that saved response back instead of placing a second call.