success: false and a human-readable message.
errors array with per-field detail.
Status codes
403 is returned rather than 404 when a resource exists but isn’t yours — and 404 when it isn’t visible to your workspace at all. Neither confirms the existence of another workspace’s data.Common causes
401 on a key that used to work
401 on a key that used to work
The key was deactivated, it hit its expiry date, or you’re sending a truncated value. Check for whitespace or a partially-copied key in your environment variables.
403 on a request you expect to work
403 on a request you expect to work
A missing permission scope. Transcript and recording access are separate from
calls:read — see Authentication.400 on a phone number
400 on a phone number
Send E.164 —
+14155551234, with country code and no punctuation.403 when sending SMS
403 when sending SMS
The
from number doesn’t belong to your workspace. Use one of your own provisioned numbers.429 on call creation
429 on call creation
Either the API rate limit or your plan’s call limit. The message distinguishes them.
Handling errors well
1
Branch on status code, not message text
message is written for humans and may be reworded. Status code and success are the stable contract.2
Don't retry 4xx
Except
429. A 400 or 403 will fail identically every time — retrying just burns your rate limit.3
Retry 5xx and 429 with exponential backoff
Respect
Retry-After on 429. Add jitter so parallel workers don’t retry in lockstep.4
Log the whole response
Status,
message, and any errors array. Diagnosing from “the API failed” is guesswork.