# Errors

Every failure returns the same envelope, whatever went wrong.

```json Error envelope
{"error":{"code":"forbidden","message":"This key cannot access this endpoint."}}
```

Branch on `code`. The `message` is written for a human reading a log and may be reworded; the code will not change under you.

## The codes

| Code | Status | When | Retry? |
| --- | --- | --- | --- |
| `bad_request` | 400 | A parameter is malformed: a bad cursor, a non-integer `limit` or `since`, a `q` outside 2 to 120 characters, or `q` sent anywhere but `/search`. | No. Fix the request. |
| `unauthorized` | 401 | No `Authorization` header, not a Bearer token, not key-shaped, unknown, revoked, or expired. | No. Check the key. |
| `forbidden` | 403 | The key authenticated, but the plan or the key does not carry the scope this endpoint needs. | No. Add the scope or change plan. |
| `suspended` | 403 | The account is suspended, the trial ended, or the subscription lapsed. | No. Settle billing in the console. |
| `not_found` | 404 | No story, newsroom, person or brief for that identifier and language. | No. |
| `rate_limited` | 429 | More requests this minute than the plan allows. | Yes, after `Retry-After` seconds. |
| `quota_exceeded` | 429 | The monthly request quota is used up. | Not until the UTC month rolls over or the plan changes. |
| `internal` | 500 | An unexpected failure while authenticating the key. | Yes, once, then report the request id. |
| `unavailable` | 503 | A dependency is down or a handler failed. | Yes, with exponential backoff and jitter. |

## Reporting one

Include `X-Request-Id` from the failing response, the path, and the UTC time. That is enough to find the request. Write to [support@itsbaba.com](mailto:support@itsbaba.com).
