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

# AI Gateway Errors

> HTTP status codes, structured error codes and error envelopes returned by the AI Gateway management and inference planes, with handling guidance.

Both planes return a structured `errors` array. The inference plane additionally wraps it in the envelope the calling SDK expects, so OpenAI and Anthropic SDK exceptions work unchanged while the Telnyx detail remains available.

## Error envelopes

<CodeGroup>
  ```json Management theme={null}
  {
    "errors": [
      {
        "code": "precondition_failed",
        "title": "Stale If-Match",
        "detail": "The resource version has changed; read it again.",
        "meta": { "current_version": 4 }
      }
    ]
  }
  ```

  ```json OpenAI-compatible theme={null}
  {
    "error": {
      "message": "Send either max_tokens or max_completion_tokens, not both.",
      "type": "invalid_request_error",
      "param": "max_completion_tokens",
      "code": "invalid_request"
    },
    "errors": [
      {
        "code": "invalid_request",
        "title": "Invalid request",
        "detail": "Send either max_tokens or max_completion_tokens, not both.",
        "meta": {}
      }
    ]
  }
  ```

  ```json Anthropic-compatible theme={null}
  {
    "type": "error",
    "error": {
      "type": "permission_error",
      "message": "Model is not available to this token key."
    },
    "request_id": "0b1c2d3e-4f50-4617-8a29-3b4c5d6e7f80",
    "errors": [
      {
        "code": "model_not_in_catalog",
        "title": "Model not allowed",
        "detail": "Model is not available to this token key.",
        "meta": { "scope": "token_key" }
      }
    ]
  }
  ```
</CodeGroup>

Every response carries an `X-Request-ID` header. Keep it, together with the `code`, when reporting a problem. Do not log authorization headers, token keys or full request objects.

An error that occurs after a streaming response has started cannot change the HTTP status. On the OpenAI surface it arrives as an error chunk; on the Anthropic surface, as an `event: error` frame. Consume every stream to completion and handle the SDK's stream exceptions.

## Status codes

| Status | Meaning                                                                                                                                                               | Action                                                                                          |
| ------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------- |
| `400`  | Invalid body, unsupported option or model-specific option, unknown field, request over the size limits, token key limit out of range, invalid date or page parameter. | Correct the request.                                                                            |
| `401`  | Missing or wrong credential for this plane.                                                                                                                           | Use a Telnyx API key on the management plane and an `ltg_sk_` token key on the inference plane. |
| `403`  | Blocked, revoked or expired key; blocked resource; model not allowed; budget or end-user policy denied.                                                               | Read the `code`. Do not treat `403` as retryable.                                               |
| `404`  | Resource does not exist or belongs to another account.                                                                                                                | Check the ID.                                                                                   |
| `405`  | Method not allowed, for example `PATCH` on a provider key.                                                                                                            | Provider keys cannot be edited; create a new one instead.                                       |
| `409`  | Idempotency conflict, membership conflict or pagination snapshot conflict.                                                                                            | Read the `code`.                                                                                |
| `412`  | Stale `If-Match`.                                                                                                                                                     | Read the resource and retry with the current ETag.                                              |
| `428`  | Missing `If-Match` (or `If-None-Match: *` on end-user create).                                                                                                        | Add the precondition header.                                                                    |
| `429`  | Rate limit exceeded.                                                                                                                                                  | Wait for `Retry-After`. Remember that inference retries are not idempotent.                     |
| `502`  | The model provider failed.                                                                                                                                            | Fail closed. The request may or may not have consumed provider work.                            |
| `503`  | Enforcement, catalog, policy propagation or a required dependency is unavailable, or a BYOK model has no attached provider key for its provider.                      | Fail closed. Do not switch credentials or bypass the gateway.                                   |

## Error codes

| Code                       | Status    | Meaning                                                                                                                                                                                                                                                             |
| -------------------------- | --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `invalid_request`          | 400       | Malformed or unsupported request, including a request over the [size limits](/docs/inference/ai-gateway/inference-api#request-size-limits) and a request to `/v1/messages` with a model that is not an Anthropic BYOK model (use `/v1/chat/completions` for those). |
| `limit_out_of_range`       | 400       | A token key `max_budget`, `rpm_limit` or `tpm_limit` is 0 or above its maximum. See [Token key limits](/docs/inference/ai-gateway/controls#token-key-limits).                                                                                                       |
| `invalid_token_key`        | 401       | The inference credential is missing, malformed or unknown.                                                                                                                                                                                                          |
| `unauthorized`             | 401 / 403 | The credential is not valid for this plane or resource.                                                                                                                                                                                                             |
| `token_key_blocked`        | 403       | The key is blocked, revoked or expired.                                                                                                                                                                                                                             |
| `resource_blocked`         | 403       | The key's user, group or asserted end user is blocked.                                                                                                                                                                                                              |
| `budget_exceeded`          | 403       | A key, user or group budget lacks headroom for the request's reservation.                                                                                                                                                                                           |
| `end_user_budget_exceeded` | 403       | The asserted end user's budget lacks headroom.                                                                                                                                                                                                                      |
| `model_not_in_catalog`     | 403       | The model is not in the key's or group's allowlist.                                                                                                                                                                                                                 |
| `rate_limit_exceeded`      | 429       | An RPM or TPM limit was hit.                                                                                                                                                                                                                                        |
| `not_found`                | 404       | No such resource in this account.                                                                                                                                                                                                                                   |
| `conflict`                 | 409       | Membership or pagination snapshot conflict.                                                                                                                                                                                                                         |
| `idempotency_conflict`     | 409       | The `Idempotency-Key` was reused with a different body, or the original request is still in progress.                                                                                                                                                               |
| `precondition_failed`      | 412       | `If-Match` does not match the current version.                                                                                                                                                                                                                      |
| `precondition_required`    | 428       | A required precondition header is missing.                                                                                                                                                                                                                          |
| `enforcement_unavailable`  | 503       | Policy, catalog or a dependency needed to admit the request is unavailable, or the request uses a [BYOK model](/docs/inference/ai-gateway/byok) and the key's group has no attached provider key for that model's provider.                                         |
| `upstream_error`           | 502       | The model provider returned an error.                                                                                                                                                                                                                               |

## Handling guidance

* **Never resolve an error by escalating credentials.** A Telnyx API key, provider secret or any other credential is rejected on the inference plane by design.
* **Retry management mutations with the same idempotency key.** A new key on retry can create a duplicate resource.
* **Do not automatically retry inference.** A timeout or `502` is not proof that no provider work happened. Retry only errors that occurred before dispatch, and honor `Retry-After` on `429`.
* **Re-read before re-writing.** On `412`, fetch the resource, review the change that landed, and apply your update to the current version.
* **Fail closed on `503`.** The old policy may no longer apply; wait and retry rather than assuming the request is authorized. For a BYOK model, check that the group has a provider key attached for that model's provider.
