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

# Errors

> The Croma API error envelope: how failures are shaped, every status code the API returns, stable error codes and how to branch on them safely in a client.

## Envelope

Successful responses return `{ "data": … }`. Failures return an `error` object
and a non-2xx HTTP status. Branch on the status code, not a body flag:

```json theme={"dark"}
{
  "error": {
    "type": "invalid_request_error",
    "code": "invalid_param",
    "message": "String must contain at least 3 character(s)",
    "param": "name",
    "details": { "issues": [{ "path": "name", "message": "String must contain at least 3 character(s)" }] }
  }
}
```

| Field     | Notes                                                      |
| --------- | ---------------------------------------------------------- |
| `type`    | Broad category (see below).                                |
| `code`    | Specific machine-readable code. Branch on this.            |
| `message` | Human-readable; safe to surface in UI.                     |
| `param`   | Offending field. Present on validation errors.             |
| `details` | Optional structured detail (e.g. all validation `issues`). |

Responses from data endpoints also carry an `X-Request-Id` header; include it
when reporting an issue.

## Types and codes

| Status | `type`                  | `code`                         | Meaning                                                                                |
| ------ | ----------------------- | ------------------------------ | -------------------------------------------------------------------------------------- |
| `400`  | `invalid_request_error` | `invalid_param`                | Body failed validation; see `param` / `details`.                                       |
| `400`  | `invalid_request_error` | `too_many_results`             | Query matched too many records to return. Narrow it.                                   |
| `401`  | `authentication_error`  | `invalid_api_key`              | Missing or invalid key.                                                                |
| `401`  | `authentication_error`  | `personal_api_key_not_allowed` | A personal key was used; org keys only.                                                |
| `404`  | `not_found_error`       | `endpoint_not_found`           | No API endpoint at that path. See the [API Reference](/api-reference/overview).        |
| `404`  | `not_found_error`       | `job_not_found`                | No [async job](/async-jobs) with that id in your organization.                         |
| `405`  | `invalid_request_error` | `method_not_allowed`           | Wrong method. Data endpoints are `POST`.                                               |
| `402`  | `billing_error`         | `plan_limit_reached`           | The plan's credits for this period are spent; see [Rate limits](/rate-limits#credits). |
| `429`  | `rate_limit_error`      | `rate_limited`                 | Hourly ceiling exceeded; see [Rate limits](/rate-limits).                              |
| `5xx`  | `upstream_error`        | `<source>_upstream`            | A government source failed or was unreachable.                                         |
| `500`  | `api_error`             | `internal_error`               | Unexpected internal error.                                                             |

<Note>
  Not every endpoint emits every code; each endpoint's reference page lists its
  own. A "no match" is never a `404`; it's a successful `200`: single-record
  lookups return `found: false`, and searches return an empty list. A `404`
  means the endpoint or job id itself doesn't exist.
</Note>

<Note>
  [Async lookups](/async-jobs) can fail as a **job** rather than an HTTP error. A
  failed job carries the same `error` object in the envelope, with
  `code: "job_failed"`.
</Note>
