Errors
Every error uses one envelope:
{"status": "error", "message": "Provide exactly one of 'task' or 'pathway_id'.", "errors": ["Provide exactly one of 'task' or 'pathway_id'."]}
message is the first human-readable problem; errors lists all of them (field errors as "field: message").
| Status | Meaning |
|---|---|
400 | Invalid request body — bad phone format, both/neither of task/pathway_id, pathway with no active version; or a stop request for a call that isn't active. |
401 | Missing, malformed, revoked, or expired key (one message for all — the API never says which). |
403 | Valid key without the required scope, or the phone number has opted out. |
404 | Unknown call_id/pathway_id/from_number_id — including ids that belong to another organization. |
429 | Rate limit exceeded; retry after the Retry-After header. |
502 | The voice provider could not place the call; the attempt is recorded as failed. |
Rate limits
Per key: 60 requests/min on POST /calls, 300 requests/min on all reads. 429 responses carry Retry-After.
Scopes
A key minted with no scopes has full access. Scoped keys carry any of calls:write (send), calls:read (list/detail/recording), and pathways:read (list pathways); a request outside the key's scopes gets 403. Use scoped keys for integrations that only need to read.