# Error Handling (/docs/api/introduction/error-handling)

> For the complete documentation index, see [llms.txt](https://docs.tandemcx.ai/llms.txt). Any page on this site can be fetched as Markdown by appending `.md` to its URL.

The API uses conventional HTTP status codes and returns a consistent JSON error
envelope so clients can handle failures programmatically.

## Error envelope

Every error response has the same shape:

```json
{
    "error": {
        "code": "VALIDATION_ERROR",
        "message": "A human-readable explanation of what went wrong.",
        "details": [{ "path": "body.name", "message": "Required" }]
    }
}
```

| Field           | Description                                                  |
| --------------- | ------------------------------------------------------------ |
| `error.code`    | A stable, machine-readable error code (see below).           |
| `error.message` | A human-readable description. Do not parse this.             |
| `error.details` | Optional. Field-level issues, present for validation errors. |

Branch on the HTTP status code and `error.code` — never on `error.message`.

## Status codes

| Status                                            | Meaning                                                |
| ------------------------------------------------- | ------------------------------------------------------ |
| `400 Bad Request`                                 | The request was malformed.                             |
| `401 Unauthorized`                                | Authentication is missing or invalid.                  |
| `403 Forbidden`                                   | The token is valid but not permitted to do this.       |
| `404 Not Found`                                   | The resource does not exist.                           |
| `409 Conflict`                                    | The request conflicts with the current state.          |
| `422 Unprocessable Entity`                        | The request was understood but could not be processed. |
| `429 Too Many Requests`                           | You have been rate limited; retry later.               |
| `500 Internal Server Error`                       | An unexpected error occurred.                          |
| `502 Bad Gateway`                                 | An upstream provider returned an error.                |
| `503 Service Unavailable` / `504 Gateway Timeout` | The service was unavailable or timed out.              |

## Error codes

| Code               | Typical status        |
| ------------------ | --------------------- |
| `VALIDATION_ERROR` | `400` / `422`         |
| `UNAUTHORIZED`     | `401`                 |
| `FORBIDDEN`        | `403`                 |
| `NOT_FOUND`        | `404`                 |
| `CONFLICT`         | `409`                 |
| `RATE_LIMITED`     | `429`                 |
| `INTERNAL_ERROR`   | `500`                 |
| `UPSTREAM_ERROR`   | `502` / `503` / `504` |

`UPSTREAM_ERROR` covers every upstream provider failure: a bad response
(`502`), an unavailable service (`503`), and a gateway timeout (`504`). Branch
on the HTTP status code when you need to tell these apart.
