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

# Errors & status codes

> How the API reports success and failure

## Error format

Errors nest a consistent envelope under `detail`, with a machine-readable `error` code and a human-readable `message`:

```json theme={null}
{
  "detail": {
    "error": "NOT_FOUND",
    "message": "Submission not found."
  }
}
```

Two cases shape `detail` differently:

* **`422` validation errors**: `detail` is a list of issues, each naming the offending field in `loc` with a `msg` and a `type`.
* **`502` and `503` from [search](/concepts/brand-search)**: `detail` is a plain string.

## Status codes

| Status | Code                     | Meaning                                                                                                              |
| ------ | ------------------------ | -------------------------------------------------------------------------------------------------------------------- |
| 200    | (none)                   | Success. The result endpoint may return a partial body while a job runs.                                             |
| 202    | (none)                   | The submission was accepted for asynchronous processing.                                                             |
| 401    | `UNAUTHORIZED`           | The API key is missing, invalid, or expired.                                                                         |
| 402    | `INSUFFICIENT_CREDITS`   | The account doesn't have enough credits to run the request.                                                          |
| 403    | `FORBIDDEN`              | The key is valid but is not allowed to call this endpoint.                                                           |
| 404    | `NOT_FOUND`              | The resource was not found or isn't accessible with these credentials.                                               |
| 409    | `NOT_READY`              | The result isn't ready yet. Keep polling.                                                                            |
| 422    | (validation)             | The request payload failed validation. `detail` lists the issues.                                                    |
| 424    | `BRAND_ADHERENCE_FAILED` | A [brand-adherence](/concepts/brand-adherence) job failed permanently. No verdict will be produced, so stop polling. |
| 500    |                          | An unexpected server error occurred. The body is plain text.                                                         |
| 502    |                          | A [search](/concepts/brand-search) failed. The credit is refunded.                                                   |
| 503    |                          | [Search](/concepts/brand-search) is at capacity. Retry after the `Retry-After` header.                               |

## Polling and `409 NOT_READY`

`409 NOT_READY` is expected, not a failure: it means no checkpoint has landed yet for a running job. Retry [`GET /design/submissions/{id}/result`](/api-reference/endpoint/get-submission-result) (or [`GET /judge/brand-adherence/{job_id}/result`](/api-reference/endpoint/get-brand-adherence-verdict) for adherence jobs) shortly. Once a checkpoint lands you'll get a `200` (possibly with a partial body) and you keep polling until `status` is `completed` or `failed`.

The adherence result endpoint adds one terminal case: a job whose `status` is `failed` returns `424 BRAND_ADHERENCE_FAILED`. Unlike `409`, that state never resolves, so stop polling and read the job's `error` for the reason.

## Authentication errors

* A request your key is not allowed to make returns `403 FORBIDDEN`.
* An expired or invalid key returns `401 UNAUTHORIZED`.

See [Authentication](/concepts/authentication) for how expiration works.

## Insufficient credits

When credit metering is enabled for your account, credit-metered endpoints return `402 INSUFFICIENT_CREDITS` if your balance is too low to cover the request. Creating a submission ([`POST /design/submissions`](/api-reference/endpoint/create-submission)) and running a [search](/concepts/brand-search) both cost credits; the charge is refunded automatically if the request fails.

The response includes your current `balance` and the `required` amount:

```json theme={null}
{
  "detail": {
    "error": "INSUFFICIENT_CREDITS",
    "message": "Not enough credits for this request.",
    "balance": 0,
    "required": 1
  }
}
```
