Skip to content

Errors and retries

Every failed request returns the same JSON envelope, so you can branch on a stable code and build reliable error handling once.

{
"code": "VALIDATION_ERROR",
"message": "phone_number must be a valid E.164 number.",
"request_id": "b3f1c8d2-2b9e-4c5e-8a1f-2c7d6a9e4b1a",
"details": { "field": "phone_number" }
}
  • code: a stable, machine-readable string. Branch on this, not on message.
  • message: a human-readable summary. Wording may change; do not parse it.
  • request_id: also returned in the X-Request-Id response header. Quote it when you contact support.
  • details: optional, structured context that depends on the code.

The full list is in the errors reference.

StatusRetry?Why
400, 409, 422NoThe request is wrong. Fix it, then resend.
401, 403NoAuthentication or permission issue. Check your key.
404NoThe resource does not exist.
429YesRate limited. Back off, then retry.
500, 502, 503, 504YesTransient server-side or network issue.

Always pair a retry of a POST with an Idempotency-Key so a retried write is never applied twice.

Use exponential back-off with jitter, capped, with a bounded number of attempts:

async function withRetry(send, { maxAttempts = 5 } = {}) {
for (let attempt = 1; ; attempt++) {
const response = await send();
if (response.ok) return response;
const retriable = response.status === 429 || response.status >= 500;
if (!retriable || attempt >= maxAttempts) return response;
const base = Math.min(1000 * 2 ** (attempt - 1), 30000);
const jitter = Math.random() * base * 0.2;
await new Promise((r) => setTimeout(r, base + jitter));
}
}

Start around one second, double each attempt, cap at roughly 30 seconds, and add jitter so retries from many clients do not align into a thundering herd. Give up after a handful of attempts and surface the request_id for support.

A 400 with VALIDATION_ERROR means the request body or query is malformed. details.field points at the offending field when it can be isolated. These are never retriable: correct the payload and resend.