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

# Errors

> Error response shape and the full list of error codes returned by the Syrto API.

When a request fails, the API returns a non-`2xx` HTTP status and a JSON body with a single `error` object. The `code` is a stable, machine-readable identifier; branch on it rather than on the human-readable `message`.

## Error envelope

```json theme={null}
{
  "error": {
    "code": "not_found",
    "message": "No company matches that identifier.",
    "requestId": "req_018f9c2e7b7a7c3e9a1b2c3d4e5f6a7b",
    "details": [
      { "path": "path.taxId", "message": "Required" }
    ]
  }
}
```

<ResponseField name="error.code" type="string">
  A stable error code from the table below. The set of possible codes is also enumerated in your [OpenAPI spec](/api/openapi).
</ResponseField>

<ResponseField name="error.message" type="string">
  A human-readable description. May change between releases - do not match on it programmatically.
</ResponseField>

<ResponseField name="error.requestId" type="string">
  The request id, matching the `X-Request-Id` header. Quote it in support requests.
</ResponseField>

<ResponseField name="error.details" type="object[]">
  Present only for validation failures (`invalid_params`). Each entry has a `path` (prefixed `path.`, `query.`, or `body.` to show where the invalid value was) and a `message`.
</ResponseField>

## Error codes

| Code                      | HTTP  | Meaning                                                                    |
| ------------------------- | ----- | -------------------------------------------------------------------------- |
| `missing_api_key`         | `401` | No bearer token in the `Authorization` header.                             |
| `invalid_api_key`         | `401` | The API key is not recognised.                                             |
| `credits_exhausted`       | `402` | Your credit balance is used up.                                            |
| `limit_reached`           | `402` | Your usage allowance for the current period is reached.                    |
| `client_not_configured`   | `403` | The key is valid but its organization has no API access configured.        |
| `not_entitled`            | `403` | Your plan does not include this endpoint.                                  |
| `unknown_endpoint`        | `404` | No such route.                                                             |
| `not_found`               | `404` | The request was valid but no company matches the identifier. Not billed.   |
| `invalid_params`          | `422` | A path or query parameter failed validation. See `details`.                |
| `rate_limited`            | `429` | You exceeded your [rate limit](/api/rate-limits). See `Retry-After`.       |
| `internal_error`          | `500` | An unexpected error occurred.                                              |
| `upstream_error`          | `502` | The upstream data source returned an error.                                |
| `auth_unavailable`        | `503` | Key validation is temporarily unavailable. Retry after a short wait.       |
| `entitlement_unavailable` | `503` | Entitlement checking is temporarily unavailable. Retry after a short wait. |
| `upstream_timeout`        | `504` | The upstream data source did not respond in time.                          |

<Note>
  A `not_found` (no matching company) is never billed. Neither is any request that fails before it reaches the data source - including validation, rate-limit, and entitlement errors.
</Note>

## Retrying

`429` and the `5xx` service-availability codes (`auth_unavailable`, `entitlement_unavailable`, `upstream_timeout`, and transient `upstream_error`) are safe to retry. When a `Retry-After` header is present, wait at least that many seconds; otherwise use exponential backoff. `4xx` codes other than `429` indicate a problem with the request or plan and won't succeed on retry.
