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

# Errors and retries

> The status codes and error body of the Completion API, and which calls are safe to retry

The Completion API reports problems in two places: as an HTTP error when the request itself is rejected, and as a run with `status: "failed"` when the request was accepted but the Canvas could not finish. Handle both.

## HTTP status codes

| Code | Meaning | Typical cause |
| - | - | - |
| `200` | Success. The body is the completion, the stream or the run. | |
| `400` | The body or the query is invalid. | Malformed JSON, a field with the wrong type, a malformed query parameter on a list endpoint. For tasks, a missing required variable or a file of a disallowed type (`INVALID_SCHEMA`). |
| `401` | The API key is missing or invalid. | Wrong `Authorization` header, revoked key. |
| `402` | The Workspace reached its monthly usage limit. | Documented for task creation with `POST /task`. |
| `403` | The key cannot access the resource. | Listing runs with a key whose role is below `member`. |
| `404` | The resource does not exist or is not accessible. | Unknown `canvas_id` or `version_id`; an `environment_name` that does not exist or has no published version; an uploaded file that was not found. |
| `5xx` | A failure on Tela's side. | |

See [Errors](https://docs.tela.com/api-reference/introduction.md#errors) in the API reference introduction for the conventions shared by every endpoint.

## The error body

Errors are JSON objects with a `code`, a human-readable `message`, the HTTP `status` and `name: "Error"`. Some errors add a `details` field with more information about what was rejected.

```json theme={null}
{
    "code": "NOT_FOUND",
    "message": "Task not found",
    "status": 404,
    "name": "Error"
}
```

Branch on `status` and `code` rather than on `message`, which is meant for people and may change.

## Failed runs

When an asynchronous run cannot finish, the HTTP call that created it still returned `200`. The failure shows up later as `status: "failed"` in the run you poll with `GET /v2/chat/completions/{id}`, in the payload posted to your `webhook_url`, and in `GET /v1/completion-run`. Treat `failed` as terminal: a run does not leave that status by itself.

> [!NOTE]
>
> The fields a failed run carries about the cause of the failure are not documented here. The run is also visible in the Canvas **Usage**, where you can inspect its inputs.

## What is safe to retry

* `GET /v2/chat/completions/{id}`, `GET /v1/completion-run` and `GET /v3/files/{id}` are read-only. Retry them freely, for example on a network timeout or a `5xx`.
* `POST /v2/chat/completions` starts a run. Each accepted request creates a new run with its own ID and is counted in your usage, so a blind retry after a timeout may run the Canvas twice. No idempotency key is documented for this endpoint. If the request was rejected with a `4xx`, no run was created and you can send a corrected request.
* `POST /v3/files` only reserves an upload URL and a file ID. Retrying it creates another ID, which is harmless as long as you reference the one you actually uploaded to.

To recover from an uncertain `POST /v2/chat/completions` (you never received the response), tag each request with an identifier of your own, such as `order-123`, and query `GET /v1/completion-run?tags=order-123` before sending it again. If a run with that tag exists, read its result instead of creating a new one. See [Listing past runs](https://docs.tela.com/en/completion-api/async-and-webhooks.md#listing-past-runs).

When you do retry a `5xx` or a network error, wait between attempts and add some randomness to the delay, so that many clients failing at once do not retry at the same moment.

> [!NOTE]
>
> Rate limits and concurrency limits for the Completion API are not documented here. If you receive a status code that indicates throttling, slow down and retry after a delay.

## Avoiding errors before they happen

* Send every variable the Canvas marks as required, using the names shown in **Connect via API**. The `variablesDefinitions` of a run's `metadata` in `GET /v1/completion-run` list each variable with its `type` (`file`, `text` or `mixed`) and whether it is `required`.
* Wrap file URLs in an object with `file_url`, and check that the file is in a [supported format](https://docs.tela.com/en/supported-file-formats.md) and reachable from the internet (or uploaded with `/v3/files`).
* Use only one of `canvas_id`, `version_id` and `application_id`, and only combine `environment_name` with `canvas_id`.
* Do not send `stream` or `async` with `application_id`: tasks are always asynchronous.
* Keep the `x-compatibility-date` header on the file endpoints that require it. See [Compatibility date](https://docs.tela.com/api-reference/introduction.md#compatibility-date).


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