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

# Error Handling & Rate Limiting

> Response envelope shapes, HTTP status codes, error codes, and rate limit behavior

## Response envelope

A single resource:

```json theme={null}
{ "data": { ... } }
```

A paginated list — see [Pagination](/pagination) for details:

```json theme={null}
{
  "data": [ ... ],
  "meta": { "current_page": 1, "per_page": 10, "total": 42, "last_page": 5 }
}
```

An error:

```json theme={null}
{
  "error_code": "INVALID_API_KEY",
  "message": "Invalid API key."
}
```

A validation error (`VALIDATION_FAILED`) additionally includes an `errors` object with per-field
messages:

```json theme={null}
{
  "error_code": "VALIDATION_FAILED",
  "message": "The given data was invalid.",
  "errors": { "per_page": ["The selected per page is invalid."] }
}
```

`errors` is only present for field-level validation failures (`VALIDATION_FAILED`); every other error
returns just `error_code` and `message`.

## Errors

The KPI Integration API uses standard HTTP status codes to indicate the success or failure of a request:

| Status Code | Description                                                                                                                                                                      |
| ----------: | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|       `200` | Success                                                                                                                                                                          |
|       `400` | Bad request                                                                                                                                                                      |
|       `401` | Missing, invalid, or expired API key                                                                                                                                             |
|       `403` | Key is valid but not allowed to access this resource, IP, or domain                                                                                                              |
|       `404` | Not found                                                                                                                                                                        |
|       `405` | HTTP method not allowed for this endpoint                                                                                                                                        |
|       `409` | Request is valid, but the requested resource isn't ready yet (e.g. a report for an unpublished job) — see that endpoint's documentation below for exactly which conditions apply |
|       `422` | Unprocessable entity (validation failed)                                                                                                                                         |
|       `429` | Too many requests                                                                                                                                                                |
|       `500` | Internal server error                                                                                                                                                            |

`error_code` can be any of the following on any endpoint. Codes specific to one endpoint's business
logic (for example, report-readiness errors) are documented on that endpoint's own page below.

| Code                  | Status | Message                                           |
| --------------------- | ------ | ------------------------------------------------- |
| `MISSING_API_KEY`     | 401    | API key is required.                              |
| `INVALID_API_KEY`     | 401    | Invalid API key.                                  |
| `API_KEY_EXPIRED`     | 401    | API key has expired.                              |
| `FORBIDDEN`           | 403    | You do not have access to this resource.          |
| `IP_NOT_ALLOWED`      | 403    | Request IP is not allowed.                        |
| `DOMAIN_NOT_ALLOWED`  | 403    | Request domain/origin is not allowed.             |
| `BAD_REQUEST`         | 400    | Bad request.                                      |
| `NOT_FOUND`           | 404    | Resource not found.                               |
| `METHOD_NOT_ALLOWED`  | 405    | The HTTP method is not allowed for this endpoint. |
| `VALIDATION_FAILED`   | 422    | The given data was invalid.                       |
| `RATE_LIMIT_EXCEEDED` | 429    | Too many requests.                                |
| `INTERNAL_ERROR`      | 500    | Something went wrong.                             |

## Rate limiting

The KPI Integration API is rate-limited to ensure fair usage. Every response includes headers describing
your current limit:

```http theme={null}
X-RateLimit-Limit: 50
X-RateLimit-Remaining: 47
```

If you exceed the limit, you'll get a `429` response with a `Retry-After` header (seconds to wait
before retrying):

```json theme={null}
HTTP/1.1 429 Too Many Requests
Retry-After: 42

{
  "error_code": "RATE_LIMIT_EXCEEDED",
  "message": "Too many requests."
}
```

If the default limit is insufficient for your workflow, contact your account manager to request an
adjustment.
