# Errors and limits

Check the HTTP status before reading a success response. API errors use an `error` object with a machine-readable code, a message, and a request ID.

## Error response

```json
{
  "error": {
    "code": "content_not_available",
    "message": "An ending explanation is not available for this movie.",
    "request_id": "example-request-id"
  }
}
```

Validation errors can also include `error.details`, an array of `{ "field": "...", "message": "..." }` objects. Use the status and code for application behavior; messages are intended to explain the problem.

## Decide what to do

| Status         | Meaning                                        | Action                                                                   |
| -------------- | ---------------------------------------------- | ------------------------------------------------------------------------ |
| `400`          | Invalid parameters, path values, or cursor.    | Correct the request. Restart pagination if the cursor expired.           |
| `401`          | Missing or invalid credentials.                | Check the Bearer header and API key.                                     |
| `403`          | Access denied.                                 | Check subscription status, payment, and remaining monthly allowance.     |
| `404`          | Resource, content section, or route not found. | Check the path and distinguish missing content from an unknown resource. |
| `429`          | Request limit reached.                         | Wait for `Retry-After` before trying again.                              |
| `500` or `503` | Server or temporary availability problem.      | Retry a small number of times with backoff.                              |

An empty search is a `200` response with an empty `data` array. It is different from a `404` on a detail endpoint. All documented data operations use `GET`; check the method and URL if a route is not found.

## Monthly allowance and burst limit

Free includes **100**, Starter **5,000**, and Pro **25,000 successful requests per monthly subscription period**. Check your exact reset date and remaining allowance in [My Subscriptions](/subscriptions). Each successful page or content request counts as one request. Unsuccessful responses do not consume the monthly allowance.

An exhausted allowance blocks further access with `403`; there are no automatic overage charges. Usage updates and quota enforcement can be briefly delayed, so do not rely on an exact cutoff for your own application budgets. Wait for the next period or change plan. A `403` can also indicate an inactive subscription or a payment problem.

A separate burst limit permits **60 requests per minute per consumer**. Keys attached to the same consumer share that limit. This returns `429` rather than `403`.

A rate-limited response includes `Retry-After` in seconds. Wait at least that long before another attempt. Coordinate workers that share credentials, and avoid launching large bursts of parallel requests.

Pagination requests and requests for separate content sections are separate API calls. Fetch only the sections your interface needs.

## Retry responsibly

For temporary server failures, use exponential backoff with a little random jitter and a maximum number of attempts. Give each request a timeout. Do not automatically retry invalid parameters, rejected credentials, or unavailable content.

Record the HTTP status, `error.code`, request ID, timestamp, and endpoint when troubleshooting. Redact authorization headers and API keys from logs and shared reports.

**Next:** [JavaScript and Python examples →](/examples)
