Documentation menu

Operate

Errors

Every error uses a standard HTTP status code and a small JSON body. There's one shape for the whole API — you never need a different parser for a different endpoint.

The error body

A failed request returns the matching status code and:

{ "detail": "Call not found." }

detail is a human-readable string meant for your logs, not for parsing — switch on the status code (and, for call outcomes, the reason code), not on the text.

Status codes

StatusMeaningWhat to do
400Bad request — a field is missing, malformed, or not one of the allowed values.Check detail; it names the field.
401Missing, unknown, revoked, or suspended-account API key.Check the Authorization: Bearer header — see Authentication.
402Insufficient wallet balance to complete the action (acquiring a number, placing a call).Top up the wallet, then retry. See Wallet.
403The account is suspended, or the action is blocked for this resource (e.g. a destination outside your allowlist).Contact support if this is unexpected.
404The resource doesn't exist, or doesn't belong to your account.Double-check the uuid/sid — we never leak another account's resources as a 403.
409Conflict — the resource is in the wrong state (a number already taken), or a duplicate Idempotency-Key request is still in flight.See idempotency.
429Too many requests — a per-account traffic cap. See Rate limits.Back off and retry; for calls, the refusal also carries a LIMIT.* reason code explaining which cap.
500Something broke on our end.Safe to retry (idempotently for money-moving calls). If it persists, contact support with the request's timestamp.

When a call itself is refused

An originate that returns 402 or 429 never creates a call — nothing was dialled, nothing was billed. That's different from a call that connects and then fails partway through: that failure shows up as a normal 200 response whose Call object carries a terminal reason_code instead. Both paths are covered by the same reason code table, so you can build one handler for "why didn't/doesn't this call work" regardless of which stage it failed at. That table is generated straight from our internal code registry, so it's always current — no separate spec to fall out of sync with.

Tip: 402 (top up) and 429 (slow down / raise your cap) are never the same code — see Events & codes for why that distinction matters for how you react.