---
title: Errors
slug: errors
docTags: 
createdAt: 2026-06-02T09:00:53.233Z
---

All v1 errors share one envelope. Build your error handling around the stable
`code` field — not the human-readable message.

## The error envelope

```json
{
  "error": {
    "code": "insufficient_credits",
    "message": "Your account is out of verification credits.",
    "type": "billing_error",
    "request_id": "req_a1b2c3"
  }
}
```

| Field        | Use it for                                                                                                                     |
| ------------ | ------------------------------------------------------------------------------------------------------------------------------ |
| `code`       | **Branch on this.** A stable, machine-readable slug. Adding new codes is non-breaking; renaming one is a major-version change. |
| `message`    | Display / logging only. Wording can change at any time — **never pattern-match on it.**                                        |
| `type`       | Coarse category, derived deterministically from the HTTP status (see below). Handy for grouping.                               |
| `request_id` | Echoes the `X-Request-Id` response header. **Quote it in support tickets** so we can trace the request.                        |

## Error categories (`type`)

`type` is a function of the HTTP status code:

| HTTP status        | `type`                  |
| ------------------ | ----------------------- |
| 400, 405, 413, 415 | `invalid_request_error` |
| 401, 403           | `authentication_error`  |
| 402                | `billing_error`         |
| 404                | `not_found_error`       |
| 409                | `conflict_error`        |
| 429                | `rate_limit_error`      |
| 5xx                | `api_error`             |

## HTTP status codes

| Status        | Meaning                                                                |
| ------------- | ---------------------------------------------------------------------- |
| 200           | Success.                                                               |
| 400           | Invalid request — missing or malformed parameter.                      |
| 401           | Invalid credentials — key rejected.                                    |
| 402           | Payment required — out of credits (`insufficient_credits`).            |
| 403           | Forbidden — credentials valid but policy/scope/origin denies.          |
| 404           | Not found — the resource doesn't exist or belongs to another account.  |
| 409           | Conflict — a request with the same `Idempotency-Key` is still running. |
| 413           | Payload too large.                                                     |
| 415           | Unsupported media type — `Content-Type` must be `application/json`.    |
| 422           | Same `Idempotency-Key` reused with a different request body.           |
| 429           | Rate limited — honor `Retry-After`. See the **Rate limits** guide.     |
| 500           | Server error — likely a bug. Retry once with backoff.                  |
| 502, 503, 504 | Upstream unavailable. Retry with backoff.                              |

## Common error codes

Branch on these slugs. The list is grouped by category; see the API reference
per-endpoint for which codes each can return.

**Authentication & permission** — `missing_api_key`, `invalid_api_key`,
`forbidden`, `forbidden_scope`, `domain_not_authorized`.

**Input validation** — `missing_email`, `invalid_email`, `missing_emails`,
`invalid_emails`, `missing_job_id`, `invalid_job_id`, `invalid_content_type`,
`invalid_request`.

**Limits** — `payload_too_large`, `rate_limited`.

**Billing** — `insufficient_credits`.

**Not found / conflict** — `not_found`, `job_not_found`, `job_not_completed`,
`idempotency_key_in_progress` (409), `idempotency_key_fingerprint_mismatch`
(422).

**Server / upstream** — `job_creation_failed`, `job_fetch_failed`,
`delete_failed`, `timeout`, `server_error`, `service_unavailable`.

## Recommended handling

1. Switch on the HTTP status for coarse control flow (retry vs. fail).
2. Within a status, switch on `error.code` for specific handling
   (e.g. `insufficient_credits` → prompt a top-up).
3. Log `error.request_id` alongside your own context, and quote it in any
   support ticket.
4. For `429` and `5xx`, retry with exponential backoff — honor `Retry-After`
   when present.
