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

# Status & Error Codes

> Understand every HTTP status code the Whisul API returns, handle errors programmatically, and apply best practices for rate limiting and retries.

The Whisul API uses standard HTTP status codes to indicate the outcome of every request. Handling errors correctly — especially for asynchronous jobs — ensures your integration stays resilient when things don't go as expected. This page covers every status code the API returns, explains what each one means, and shows you how to respond.

## HTTP status code reference

### POST /generate

| Status code | Meaning                                                                                   | What to do                                                                                |
| ----------- | ----------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------- |
| `202`       | Request accepted. Job is queued.                                                          | Store the `job_id` and begin polling.                                                     |
| `400`       | Invalid input. The request body was malformed or the `prompt` field was missing or empty. | Fix the request body before retrying. Log the response for debugging.                     |
| `401`       | Unauthorized. Your API key was missing, invalid, or expired.                              | Check that you're sending `Authorization: Bearer YOUR_API_KEY` and that the key is valid. |
| `429`       | Rate limit exceeded. You've sent too many requests in a short period.                     | Back off and retry after a delay. See rate limit guidance below.                          |

### GET /jobs/{job_id}

| Status code | Meaning                                                                                                     | What to do                                                                   |
| ----------- | ----------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------- |
| `200`       | Request successful. Check the `status` field in the response body — it may be `"running"` or `"completed"`. | Continue polling if `"running"`. Process the result if `"completed"`.        |
| `404`       | Job not found. The `job_id` does not exist or has expired.                                                  | Verify you're using the correct `job_id` from the `POST /generate` response. |
| `500`       | Server error. An unexpected error occurred on Whisul's side.                                                | Retry after a short delay. If the error persists, contact support.           |

## Handling errors programmatically

### 400 — Invalid input

A `400` response means the API rejected your request before any job was created. Check that:

* The request body is valid JSON.
* The `prompt` field is present and non-empty.
* The `Content-Type: application/json` header is set.

```json 400 response body example theme={null}
{
  "error": "Invalid input",
  "message": "The 'prompt' field is required and must not be empty."
}
```

### 401 — Unauthorized

Every request to the Whisul API must include your API key in the `Authorization` header.

```bash Correct header format theme={null}
Authorization: Bearer YOUR_API_KEY
```

If you receive a `401`, confirm that:

* You're not sending the key as a query parameter or in the request body.
* The API key has not been revoked. Regenerate it in your dashboard if needed.

### 429 — Rate limit exceeded

<Warning>
  Exceeding the rate limit will block your requests until the limit resets. Do not retry immediately — this will prolong the block. Always implement exponential backoff when you receive a `429`.
</Warning>

When you receive a `429`, wait before retrying. A simple backoff strategy:

1. On first `429`: wait 5 seconds, then retry.
2. On second `429`: wait 10 seconds, then retry.
3. On each subsequent `429`: double the wait time, up to a maximum of 60 seconds.

Avoid polling `GET /jobs/{job_id}` more frequently than once every 5–10 seconds, which helps prevent hitting rate limits during job monitoring.

### 404 — Job not found

A `404` from `GET /jobs/{job_id}` means the server has no record of that job. The most common causes are:

* A typo in the `job_id`.
* Using a `job_id` from a different environment or account.
* The job has expired from the system after an extended period.

Always use the `job_id` or `poll_url` returned directly from `POST /generate`.

### 500 — Server error

A `500` indicates an unexpected failure on Whisul's infrastructure. These are typically transient. Retry the same request after 10–30 seconds. If `500` errors persist across multiple retries, check the Whisul status page or contact support.

## Handling failed jobs

A job with `"status": "failed"` is distinct from an HTTP error response. The HTTP status code will be `200` (the request itself succeeded), but the job inside could not complete.

```json Failed job response theme={null}
{
  "status": "failed",
  "prompt": "a relaxing lo-fi hip hop beat",
  "result": null,
  "error": "Generation failed due to an internal error.",
  "started_at": "2026-02-17 15:39:34",
  "finished_at": "2026-02-17 15:41:05"
}
```

When you detect `"status": "failed"`:

* Read the `error` field for a description of what went wrong.
* Retry by submitting a new `POST /generate` request — you cannot resume a failed job.
* Consider adjusting your prompt if the failure may be related to the input.

See the [polling guide](/guides/polling-jobs) for the full job lifecycle and all possible status values.
