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

# Errors and retries

> Handle CarHub API failures predictably.

All non-`2xx` responses share one envelope:

```json theme={null}
{
  "error": {
    "type": "rate_limit",
    "code": "rate_limit_exceeded",
    "message": "Rate limit exceeded.",
    "param": null,
    "doc_url": "https://docs.trycarhub.com/errors/rate_limit_exceeded",
    "request_id": "req_2Kd8xQmPvL4T"
  }
}
```

Use `type` for broad program flow and `code` for precise handling. New codes can be added, so handle unknown codes as their known `type`.

| Status | Typical code                          | What to do                                                                        |
| ------ | ------------------------------------- | --------------------------------------------------------------------------------- |
| `400`  | `missing_input`, `wait_not_supported` | Correct the request. Do not blindly retry.                                        |
| `401`  | `invalid_api_key`                     | Replace or restore the credential.                                                |
| `402`  | `insufficient_credits`                | Add credits, then submit again only if the original request did not create a job. |
| `403`  | `scope_not_granted`                   | Use a key with the needed family scope or adjust permissions.                     |
| `404`  | `job_not_found`                       | Check the identifier and credential mode.                                         |
| `409`  | `idempotency_key_reuse`               | Generate a new key for a deliberately new payload.                                |
| `429`  | `rate_limit_exceeded`                 | Wait for `Retry-After`, add jitter, then retry.                                   |
| `500`  | `internal_error`                      | Retry with the same idempotency key; quote `request_id` if it persists.           |

## Failed jobs

A submission can be accepted and later finish as `failed`. Inspect the job's `error` field. Model failures are distinct from request errors; a processing failure releases the reservation rather than charging successful inference.

<Note>Log `request_id`, the job ID and the endpoint slug together. Those three values make a support investigation much faster.</Note>
