> ## Documentation Index
> Fetch the complete documentation index at: https://docs.adclear.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Errors & rate limits

> The shared error envelope, every error code, rate limits, and fixes for the issues integrators hit most.

Every error from both services follows one envelope, so you can handle failures the same way everywhere.

## Error envelope

```json theme={null}
{
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "Human-readable description",
    "details": [
      { "type": "field_error", "field": "uploadIds", "message": "Required" }
    ]
  },
  "correlationId": "uuid-for-support"
}
```

The `details` array is present on some errors and identifies what to fix. Its entries take one of these shapes: `field_error` (a bad field), `constraint_violation` (a limit exceeded), `retry_info` (when to retry), or `upload_not_ready` (an upload still processing).

## Error codes

| Code                | HTTP status | Meaning                                                                                      | Action                                                                                    |
| ------------------- | ----------- | -------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------- |
| `VALIDATION_ERROR`  | 400         | Request body failed schema validation                                                        | Fix the payload per the `details` array                                                   |
| `INVALID_REQUEST`   | 400 / 409   | Request isn't valid for the resource's state (for example, an upload that already completed) | Check the request against the current resource state                                      |
| `UNAUTHORIZED`      | 401         | Missing or invalid API key                                                                   | Check the `Authorization` header and key validity                                         |
| `FORBIDDEN`         | 403         | API key lacks permission for this resource                                                   | Contact Adclear to adjust key scoping                                                     |
| `NOT_FOUND`         | 404         | Resource does not exist                                                                      | Verify the resource ID. It may have been deleted                                          |
| `CONFLICT`          | 409         | Resource not in the expected state (uploads not ready, version not editable)                 | Retry with back-off                                                                       |
| `PAYLOAD_TOO_LARGE` | 413         | File exceeds the size limit for its format                                                   | Check the format limits in [Introduction](/developer/introduction#supported-file-formats) |
| `RATE_LIMITED`      | 429         | Too many requests                                                                            | Honour the `Retry-After` header                                                           |
| `INTERNAL_ERROR`    | 500         | Unexpected server error                                                                      | Retry once. If it persists, contact support                                               |
| `UPSTREAM_ERROR`    | 502         | A dependency failed transiently                                                              | Retry after a short delay                                                                 |

## Rate limits

| Service     | Scope                                | Limit                          |
| ----------- | ------------------------------------ | ------------------------------ |
| Adclear API | All `/v1/*` endpoints                | 60 requests/minute per API key |
| File API    | `POST /v1/uploads` (initiation only) | 30 requests/minute per API key |

Chunk uploads (`PUT /v1/uploads/{id}`) and status checks (`GET /v1/uploads/{id}`) are not rate-limited. When you are rate-limited, the response includes a `Retry-After` header telling you how many seconds to wait.

The Adclear API's 60/minute budget is **shared across every `/v1/*` endpoint**, so frequent polling of evaluation status competes with your `create` and `evaluate` calls. Prefer [webhooks](/developer/webhooks) to receive results without spending the budget.

## Common issues

<AccordionGroup>
  <Accordion title="401 Unauthorized on every request" icon="key">
    * Verify the `Authorization` header is `Bearer <key>` (note the space after `Bearer`).
    * Confirm you're using the correct key for the environment. Staging and production keys are not interchangeable.
    * Check the key hasn't been revoked.
  </Accordion>

  <Accordion title="403 Forbidden" icon="ban">
    The API key authenticates but isn't fully configured for your organisation. Contact Adclear support with the `correlationId` from the error response.
  </Accordion>

  <Accordion title="429 Rate limited" icon="hourglass-half">
    Honour the `Retry-After` header. If you're regularly hitting the limit, batch requests or contact support to discuss your usage.
  </Accordion>

  <Accordion title="502 from the Adclear API" icon="triangle-exclamation">
    A transient upstream issue. Retry after 2 to 5 seconds. If it persists, contact support with the `correlationId`.
  </Accordion>
</AccordionGroup>

## General tips

* Pass your own trace ID in the `X-Correlation-ID` request header. Adclear echoes it back in every response.
* Always include the `correlationId` in support requests. It lets us trace the full request lifecycle.
* Test against staging before production.
* Cache reference data (products, channels, jurisdictions, target markets) and refresh daily.
