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

# Errors

> The error object, every error type and code with its HTTP status and whether to retry it, and how content_rejected and failed generations are charged.

## The error object

Every error has the same shape:

| Field | Description |
| - | - |
| `type` | Broad category of the error, such as `rate_limit_error`. |
| `code` | Stable, specific error code, such as `concurrency_limit`. |
| `message` | Human-readable explanation. |
| `param` | Optional. The request field the error is about, such as `input.duration`. |
| `stage` | Optional. For `content_rejected`: `input` or `output`. |
| `retryable` | Whether sending the same request again may succeed. |

It appears in two places:

* **An error response** wraps it with the request ID, which is also in the `x-request-id` header:

  ```json theme={null}
  {
    "error": {
      "type": "invalid_request_error",
      "code": "invalid_request",
      "message": "input.duration must be at most 10.",
      "param": "input.duration",
      "retryable": false
    },
    "request_id": "req_01JBXK4A2C4E6G8J0K2M4P6R8T"
  }
  ```

* **A failed generation** carries it in its `error` field, with `status: "failed"`:

  ```json theme={null}
  {
    "id": "gen_01JBXK2Y7P1N3R5T7V9X1Z3B5D",
    "status": "failed",
    "error": {
      "type": "upstream_error",
      "code": "timeout",
      "message": "The model did not finish in time.",
      "retryable": true
    },
    "...": "..."
  }
  ```

> [!NOTE]
>
> Branch on `code`, never on `message`. `code` is a stable contract; `message` is for humans and may change at any time. New `type` and `code` values may be added in future, so handle unknown ones with a default, using `retryable` to decide whether to try again.

## Error codes

| `type` | HTTP | `code` | Retry |
| - | - | - | - |
| `invalid_request_error` | 400 | `invalid_request` | No |
| `invalid_request_error` | 400 | `content_rejected` | No |
| `authentication_error` | 401 | `invalid_api_key` | No |
| `billing_error` | 402 | `insufficient_balance` | No |
| `permission_error` | 403 | `api_key_disabled` | No |
| `permission_error` | 403 | `account_suspended` | No |
| `not_found_error` | 404 | `model_not_found` | No |
| `not_found_error` | 404 | `generation_not_found` | No |
| `rate_limit_error` | 429 | `rate_limited` | Yes, after `Retry-After` |
| `rate_limit_error` | 429 | `concurrency_limit` | Yes, after `Retry-After` |
| `upstream_error` | 503, or a failed generation | `model_unavailable` | Yes |
| `upstream_error` | 503, or a failed generation | `upstream_failed` | Yes |
| `upstream_error` | 503, or a failed generation | `timeout` | Yes |
| `api_error` | 500, or a failed generation | `internal_error` | Yes |

What each code means and what to do:

| `code` | Meaning | What to do |
| - | - | - |
| `invalid_request` | The request is malformed: a missing or unknown field, a value out of range, or an input asset that cannot be downloaded or has an unsupported format or size. `param` names the field. | Fix the request. |
| `content_rejected` | Content moderation rejected the input or the output; `stage` says which. | Change the input. |
| `invalid_api_key` | The API key is missing, wrong or revoked. | Check the `Authorization` header. |
| `insufficient_balance` | The balance does not cover the estimate, or is below zero. | [Top up](https://docs.codzen.ai/guides/billing.md#low-and-negative-balance), then retry. |
| `api_key_disabled` | Codzen has disabled the API key. | Contact support. |
| `account_suspended` | The account is suspended. | Contact support. |
| `model_not_found` | No model has this slug. | Check the slug in [Models](https://docs.codzen.ai/models.md). |
| `generation_not_found` | No generation with this ID in your account. | Check the ID. |
| `rate_limited` | Too many requests for this API key. | Wait `Retry-After` seconds. |
| `concurrency_limit` | Too many generations in progress for this account. | Wait `Retry-After` seconds, or until one finishes. |
| `model_unavailable` | The model is unavailable for now. | Retry later. |
| `upstream_failed` | The model failed to produce an output. | Retry. |
| `timeout` | The model did not finish in time. | Retry. |
| `internal_error` | Something went wrong on Codzen's side. | Retry later; contact support with the `request_id` if it persists. |

See [Authentication and rate limits](https://docs.codzen.ai/guides/authentication.md) for the limits behind `429`.

## Retrying

`retryable` tells you whether the same request can succeed later. For `429`, wait for the `Retry-After` header. For `500` and `503`, retry with exponential backoff.

For a failed generation, retrying means submitting a new generation with the same `model` and `input`; a generation never leaves `failed`.

> [!WARNING]
>
> There are no idempotency keys yet. If a `POST /generations` request times out on your side, you cannot tell whether the generation was created. Before submitting again, check `GET /generations` for a generation you just created, or accept that you may occasionally create a duplicate.

## Content rejected

`content_rejected` means content moderation blocked the generation. `stage` says what was rejected:

* `input`: your prompt or an input asset.
* `output`: what the model produced.

A rejected generation is not charged. When the rejection comes after submission, the generation ends `failed` with `cost.amount` `"0.00"` and its estimate is released back to your balance. Retrying the same input will be rejected again, so change it first.

## Failed generations are free

A generation that fails, for any reason, costs nothing: `cost.amount` is `"0.00"` and the estimate held at submission returns to your balance. See [Billing](https://docs.codzen.ai/guides/billing.md).


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.