Every error is one envelope:

```json
{ "error": { "code": "INSUFFICIENT_CREDITS", "message": "what to do" } }
```

The `message` says what to do; the `code` is the stable value to branch on. A non-2xx response is never charged.

## Metered calls

| Code | Status | Meaning |
| --- | --- | --- |
| `UNAUTHORIZED` | 401 | Missing or invalid key. |
| `INVALID_API_KEY` | 401 | Key not found or revoked. |
| `VALIDATION_ERROR` | 400 | The request does not match the entry's input. |
| `INSUFFICIENT_CREDITS` | 402 | The wallet cannot cover this call. |
| `BUDGET_EXCEEDED` | 402 | A credit cap for this key, org or agent would be exceeded. |
| `CALL_CAP_EXCEEDED` | 402 | The call cap for this key has been reached. |
| `POLICY_DENIED` | 402 | A deny rule blocked this host, path or method; its note is in the body. |
| `PAYMENT_REQUIRED` | 402 | x402 offer issued (see [x402](/authentication/x402)). |
| `UNPRICED_PRODUCT` | 402 | The product has no price in the price table; it is refused, not served free. |
| `NOT_FOUND` | 404 | Unknown catalog id, or a path this API does not serve. |
| `CATALOG_PRICE_UNVERIFIED` | 409 | The entry's price has no provenance. |
| `NO_CANDIDATE_SOURCE` | 422 | No source may serve this routed capability for this caller. |
| `RATE_LIMITED` | 429 | Too many requests for this key; retry after `Retry-After`. |
| `NO_USABLE_SOURCE` | 502 | Every candidate source was tried and none could express the request. |
| `UPSTREAM_ERROR` | 502 | The provider answered 4xx or 5xx. |
| `UPSTREAM_UNAVAILABLE` | 502 | The provider could not be reached or timed out. |
| `UPSTREAM_RESPONSE_TOO_LARGE` | 502 | The provider's answer exceeded the tool's response limit. |

## Account and billing

| Code | Status | Meaning |
| --- | --- | --- |
| `TURNSTILE_REQUIRED` | 400 | Turnstile token required. |
| `TURNSTILE_FAILED` | 403 | Turnstile verification failed. |
| `EMAIL_EXISTS` | 409 | Email already registered. |
| `EMAIL_NOT_VERIFIED` | 403 | A verified email is required. |
| `INVALID_CREDENTIALS` | 401 | Bad email or password. |
| `ACCOUNT_SUSPENDED` | 403 | Account suspended. |
| `UNAUTHORIZED` / `INVALID_TOKEN` | 401 | Bad or expired JWT. |
| `FORBIDDEN` | 403 | Admin route for a non-admin. |
| `INVALID_PACKAGE` | 400 | Unknown top-up `package_id`. |
| `PAYMENT_NOT_CONFIGURED` | 503 | The payment provider is not configured. |
| `PAYMENT_PROVIDER_ERROR` | 502 | The Polar checkout could not be created; nothing was charged. |
| `INVALID_SIGNATURE` | 403 | Payment webhook signature invalid (Polar to 1ToolRing only). |