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

# Errors

> The Voyager API error envelope and every error code, with its HTTP status, whether to retry, and what to do.

Every error response has the same shape, and every `code` has a section on this page. `doc_url` links straight to it. An example:

```json theme={"system"}
{
  "error": {
    "type": "permission",
    "code": "insufficient_credits",
    "message": "Not enough credits for this job.",
    "doc_url": "https://docs.voyager.so/api/errors#insufficient_credits",
    "request_id": "req_01JC4T6P0D2F4H6K8M0P2R4T6V",
    "retryable": false,
    "details": { "upgrade_url": "https://voyager.so/dashboard/billing", "required_hold": …, "available_credits": … }
  }
}
```

| Field | Type | Description |
| - | - | - |
| `type` | `ErrorType` | Stable category to branch on. |
| `code` | `string` | Stable machine code; never renamed once published (x-voyager-errors lists each). |
| `message` | `string` | For developers. Not localized. |
| `doc_url` | `string` | [https://docs.voyager.so/api/errors#\&lt;code>](https://docs.voyager.so/api/errors.md#\&lt;code>) |
| `request_id` | `string` or `null` | Also in the X-Request-ID header; quote it to support. |
| `retryable` | `boolean` or `null` | Whether the same request can succeed later. |
| `retry_after_ms` | `integer` or `null` | How long to wait before retrying. |
| `param` | `string` or `null` | The request field at fault, as a path (e.g. input.resolution); set on invalid\_input. |
| `details` | `object` or `null` | Code-specific detail, e.g. upgrade\_url on a billing wall. |

`type` is a broad category; `code` is the specific error and is never renamed, so branch on it. `message` is for developers and can change: don't parse it. `429` responses also send `Retry-After` in seconds.

## How to handle errors

* **Branch on `code`**, not on `message` or the status alone.
* **Retry only when `retryable` is `true`**, after `retry_after_ms` or `Retry-After`, with backoff, and with the **same `Idempotency-Key`**. Then a retry can never create a second job.
* **Billing errors (`402`) aren't fixed by retrying**, except `credits_reloading`. Show `details.upgrade_url` to the person who manages the workspace. Nothing was held or charged.
* **Log `request_id`** on every error.

Codes come back in two ways: as an HTTP error response, or in a finished job's `error` object (`{code, message, details}`).

| Group | Code | Returned as | Retryable | Meaning |
| - | - | - | - | - |
| **model** | [`invalid_request`](#invalid_request) | `400` | no | The request is not a valid model request. |
| | [`invalid_input`](#invalid_input) | `400` | no | The model can't take this input as sent. |
| | [`content_policy`](#content_policy) | `422` | no | This request was refused under the model's content policy. |
| | [`upstream_unavailable`](#upstream_unavailable) | `503` | yes | The model couldn't run this request right now. |
| | [`rate_limited`](#rate_limited) | `429` | yes | Too many requests. |
| | [`queue_full`](#queue_full) | `429` | yes | Your plan's limit of generations running at once is reached. |
| | [`model_unavailable`](#model_unavailable) | `503` | yes | This model isn't available right now. |
| | [`model_not_found`](#model_not_found) | `404` | no | Unknown model. |
| | [`insufficient_credits`](#insufficient_credits) | `402` | no | Not enough credits for this generation. |
| | [`paid_plan_required`](#paid_plan_required) | `402` | no | This model needs a paid plan. |
| | [`model_not_in_plan`](#model_not_in_plan) | `402` | no | This model isn't included in your plan. |
| | [`model_access_required`](#model_access_required) | `403` | no | This model needs access to be granted first. |
| | [`outcome_unknown`](#outcome_unknown) | `503` | yes | Voyager couldn't confirm this generation yet. |
| | [`expired`](#expired) | `410` | no | These results have expired. |
| | [`not_found`](#not_found) | `404` | no | No such generation for this workspace. |
| | [`conflict`](#conflict) | `409` | no | This generation can't change from its current state. |
| | [`forbidden`](#forbidden) | `403` | no | This request isn't allowed for this workspace. |
| | [`internal_error`](#internal_error) | `500` | no | Something went wrong on Voyager's side. |
| | [`catalog_unavailable`](#catalog_unavailable) | `503` | yes | The model catalog is temporarily unavailable. |
| | [`billing_unavailable`](#billing_unavailable) | `503` | yes | Your plan couldn't be checked right now, so this paid request can't run yet. |
| | [`no_voyager_seat`](#no_voyager_seat) | `402` | no | You don't have a seat on this workspace's Voyager plan. |
| | [`credits_reloading`](#credits_reloading) | `402` | yes | Your credits are reloading and the balance is briefly short. |
| | [`cast_not_supported`](#cast_not_supported) | `422` | no | Cast works with image and video models only. |
| | [`voice_cloning_unavailable`](#voice_cloning_unavailable) | `403` | no | Voice cloning isn't available to this workspace. |
| | [`too_many_references`](#too_many_references) | `422` | no | Too many reference files for this model and operation. |
| | [`payload_too_large`](#payload_too_large) | `413` | no | The request body is too large. |
| | [`upload_too_large`](#upload_too_large) | `413` | no | This file is over your plan's per-file limit. |
| | [`intake_full`](#intake_full) | `429` | yes | Too many recent reference files are stored. |
| | [`invalid_url`](#invalid_url) | `422` | no | That URL can't be used: it must be a public https URL. |
| | [`fetch_failed`](#fetch_failed) | `502` | no | That URL couldn't be downloaded. |
| | [`unsupported_file`](#unsupported_file) | `415` | no | That file isn't a supported image, video or audio type. |
| **api** | [`invalid_api_key`](#invalid_api_key) | `401` | no | Missing, invalid or revoked API key. |
| | [`idempotency_conflict`](#idempotency_conflict) | `409` | no | This Idempotency-Key was already used for a different request. |
| | [`idempotency_in_flight`](#idempotency_in_flight) | `409` | yes | A request under this Idempotency-Key is still running; retry shortly. |
| | [`invalid_idempotency_key`](#invalid_idempotency_key) | `400` | no | Idempotency-Key must be 1-200 printable ASCII characters. |
| | [`invalid_cursor`](#invalid_cursor) | `400` | no | Pass next\_cursor exactly as a page returned it. |
| | [`invalid_webhook_url`](#invalid_webhook_url) | `400` | no | webhook\_url must be a public https URL. |
| | [`method_not_allowed`](#method_not_allowed) | `405` | no | This method is not supported on this path. |
| | [`account_unavailable`](#account_unavailable) | `402` | no | This Voyager account is not eligible for generation. |
| | [`plan_required_for_faces`](#plan_required_for_faces) | `403` | no | This video model needs the Ultra or GigaMax plan for a photoreal Cast character. |
| | [`version_conflict`](#version_conflict) | `409` | no | The Cast card changed since you read it. |
| | [`slug_taken`](#slug_taken) | `409` | no | Another Cast card in this workspace already uses that slug. |
| | [`already_referenced`](#already_referenced) | `409` | no | That image is already a reference on this Cast card. |
| | [`asset_in_use`](#asset_in_use) | `409` | yes | The file is in use by a running job or saved in a Cast card. |
| | [`upload_incomplete`](#upload_incomplete) | `409` | no | Nothing was uploaded yet. |
| | [`cancel_unsupported`](#cancel_unsupported) | `409` | no | This kind of job cannot be stopped once started. |
| | [`unsupported_model`](#unsupported_model) | `422` | no | This model can't run that operation. |
| | [`invalid_job_id`](#invalid_job_id) | `400` | no | Job ids look like job\_…; pass one exactly as returned. |
| | [`voice_required`](#voice_required) | `422` | no | Choose a voice: pick one from GET /v1/voices and pass its id as input.voice\_id. |
| | [`observation_timeout`](#observation_timeout) | `503` | yes | The job's status couldn't be read in time. |
| | [`reference_unavailable`](#reference_unavailable) | `503` | yes | A reference file couldn't be prepared right now. |
| **job** | [`queue_timeout`](#queue_timeout) | job `canceled` | no | The job waited in the queue too long and was canceled; nothing was charged. |
| | [`reference_missing`](#reference_missing) | job `failed` | no | A reference file was deleted before the job started. |

## invalid\_request

**`400`** · type `invalid_request` · not retryable

The request is not a valid model request.

## invalid\_input

**`400`** · type `invalid_request` · not retryable

The model can't take this input as sent.

| `details` field | Description |
| - | - |
| `field` | The input at fault, as a path (input.\<name>); also in param. |
| `fields` | Unknown input names, when the input names fields the model does not take. |

## content\_policy

**`422`** · type `unprocessable` · not retryable

This request was refused under the model's content policy. Change the prompt or inputs; retrying it unchanged will not succeed.

| `details` field | Description |
| - | - |
| `reason` | What the refusal was about. One of `copyright`, `likeness`, `minors`, `other`, `sexual`, `violence`. One of `copyright`, `likeness`, `minors`, `other`, `sexual`, `violence`. |

## upstream\_unavailable

**`503`** · type `upstream_error` · retryable

The model couldn't run this request right now. You were not charged; try again shortly.

## rate\_limited

**`429`** · type `rate_limited` · retryable

Too many requests. Retry after the indicated delay.

## queue\_full

**`429`** · type `rate_limited` · retryable

Your plan's limit of generations running at once is reached. Retry when one finishes.

| `details` field | Description |
| - | - |
| `upgrade_url` | Where to upgrade the plan or add credits. |

## model\_unavailable

**`503`** · type `upstream_error` · retryable

This model isn't available right now.

## model\_not\_found

**`404`** · type `not_found` · not retryable

Unknown model.

## insufficient\_credits

**`402`** · type `permission` · not retryable

Not enough credits for this generation.

| `details` field | Description |
| - | - |
| `upgrade_url` | Where to upgrade the plan or add credits. |

## paid\_plan\_required

**`402`** · type `permission` · not retryable

This model needs a paid plan.

| `details` field | Description |
| - | - |
| `upgrade_url` | Where to upgrade the plan or add credits. |

## model\_not\_in\_plan

**`402`** · type `permission` · not retryable

This model isn't included in your plan.

| `details` field | Description |
| - | - |
| `upgrade_url` | Where to upgrade the plan or add credits. |

## model\_access\_required

**`403`** · type `permission` · not retryable

This model needs access to be granted first.

## outcome\_unknown

**`503`** · type `upstream_error` · retryable

Voyager couldn't confirm this generation yet. Ask for its status again; never submit it again, or it may be charged twice.

| `details` field | Description |
| - | - |
| `support_ref` | Quote it to support. |

## expired

**`410`** · type `not_found` · not retryable

These results have expired.

## not\_found

**`404`** · type `not_found` · not retryable

No such generation for this workspace.

## conflict

**`409`** · type `conflict` · not retryable

This generation can't change from its current state.

## forbidden

**`403`** · type `permission` · not retryable

This request isn't allowed for this workspace.

## internal\_error

**`500`** · type `internal_error` · not retryable

Something went wrong on Voyager's side.

## catalog\_unavailable

**`503`** · type `upstream_error` · retryable

The model catalog is temporarily unavailable. Retry shortly.

## billing\_unavailable

**`503`** · type `upstream_error` · retryable

Your plan couldn't be checked right now, so this paid request can't run yet. Retry shortly.

## no\_voyager\_seat

**`402`** · type `permission` · not retryable

You don't have a seat on this workspace's Voyager plan.

## credits\_reloading

**`402`** · type `permission` · retryable

Your credits are reloading and the balance is briefly short. Retry shortly.

## cast\_not\_supported

**`422`** · type `unprocessable` · not retryable

Cast works with image and video models only.

## voice\_cloning\_unavailable

**`403`** · type `permission` · not retryable

Voice cloning isn't available to this workspace.

## too\_many\_references

**`422`** · type `unprocessable` · not retryable

Too many reference files for this model and operation.

## payload\_too\_large

**`413`** · type `invalid_request` · not retryable

The request body is too large.

## upload\_too\_large

**`413`** · type `invalid_request` · not retryable

This file is over your plan's per-file limit.

## intake\_full

**`429`** · type `rate_limited` · retryable

Too many recent reference files are stored. Delete some, or wait: they're kept 7 days.

## invalid\_url

**`422`** · type `unprocessable` · not retryable

That URL can't be used: it must be a public https URL.

## fetch\_failed

**`502`** · type `upstream_error` · not retryable

That URL couldn't be downloaded. Check it is live and public.

## unsupported\_file

**`415`** · type `invalid_request` · not retryable

That file isn't a supported image, video or audio type.

## invalid\_api\_key

**`401`** · type `authentication` · not retryable

Missing, invalid or revoked API key.

## idempotency\_conflict

**`409`** · type `idempotency_conflict` · not retryable

This Idempotency-Key was already used for a different request.

## idempotency\_in\_flight

**`409`** · type `conflict` · retryable

A request under this Idempotency-Key is still running; retry shortly.

## invalid\_idempotency\_key

**`400`** · type `invalid_request` · not retryable

Idempotency-Key must be 1-200 printable ASCII characters.

## invalid\_cursor

**`400`** · type `invalid_request` · not retryable

Pass next\_cursor exactly as a page returned it.

## invalid\_webhook\_url

**`400`** · type `invalid_request` · not retryable

webhook\_url must be a public https URL.

## method\_not\_allowed

**`405`** · type `invalid_request` · not retryable

This method is not supported on this path.

## account\_unavailable

**`402`** · type `permission` · not retryable

This Voyager account is not eligible for generation.

## plan\_required\_for\_faces

**`403`** · type `permission` · not retryable

This video model needs the Ultra or GigaMax plan for a photoreal Cast character. Use a stylized character or a different video model.

## version\_conflict

**`409`** · type `conflict` · not retryable

The Cast card changed since you read it. Read it again and retry with its current version.

## slug\_taken

**`409`** · type `conflict` · not retryable

Another Cast card in this workspace already uses that slug.

## already\_referenced

**`409`** · type `conflict` · not retryable

That image is already a reference on this Cast card.

## asset\_in\_use

**`409`** · type `conflict` · retryable

The file is in use by a running job or saved in a Cast card. Delete it after the job ends, or remove it from the card first.

## upload\_incomplete

**`409`** · type `conflict` · not retryable

Nothing was uploaded yet. PUT the file to upload\_url first.

## cancel\_unsupported

**`409`** · type `conflict` · not retryable

This kind of job cannot be stopped once started. It finishes on its own.

## unsupported\_model

**`422`** · type `unprocessable` · not retryable

This model can't run that operation. GET /v1/models/\{id} lists the operations it runs.

## invalid\_job\_id

**`400`** · type `invalid_request` · not retryable

Job ids look like job\_…; pass one exactly as returned.

## voice\_required

**`422`** · type `unprocessable` · not retryable

Choose a voice: pick one from GET /v1/voices and pass its id as input.voice\_id.

## observation\_timeout

**`503`** · type `upstream_error` · retryable

The job's status couldn't be read in time. Ask again with the same id; never submit it again.

## reference\_unavailable

**`503`** · type `upstream_error` · retryable

A reference file couldn't be prepared right now. Retry shortly.

## queue\_timeout

On a finished job: status `canceled` · not retryable

The job waited in the queue too long and was canceled; nothing was charged.

## reference\_missing

On a finished job: status `failed` · not retryable

A reference file was deleted before the job started. Nothing was charged.

## Cloud machines errors

The cloud machines endpoints (`/v1/machines`) use the same envelope with UPPER\_SNAKE codes, such as `PLAN_REQUIRED`, `INSUFFICIENT_CREDITS` and `MACHINE_NOT_READY`. They're listed in the [cloud machines reference](https://docs.voyager.so/api/machines/reference.md#errors).


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