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

# Errors

> Every error is JSON with a machine-readable code and a human-readable fix — here's how to handle each one.

All errors return JSON with a consistent structure:

```json theme={null}
{
  "errorCode": "API_KEY_MISSING",
  "message": "No API Key was presented on the header X-API-KEY"
}
```

* `errorCode` — machine-readable
* `message` — human-readable explanation

## Status codes

| Code  | Meaning          | What to do                                                        |
| ----- | ---------------- | ----------------------------------------------------------------- |
| `400` | Bad request      | Fix the request (invalid or missing parameters)                   |
| `401` | Unauthenticated  | Send a valid API key in `X-API-Key` (not `Authorization: Bearer`) |
| `402` | Out of credits   | Stop — wait for reset or upgrade                                  |
| `403` | Forbidden        | Endpoint not included in your plan                                |
| `404` | Not found        | Check the ID or resource                                          |
| `422` | Validation error | Fix request based on `message`                                    |
| `429` | Rate limited     | Wait and retry                                                    |
| `5xx` | Server error     | Retry with backoff                                                |

## Retry rules

* **Retry only:** `429` and `5xx`
* **Do not retry:** `400`, `401`, `403`, `404`, `422`
* **Stop on:** `402` (credits exhausted)

### Backoff strategy

* On `429` → wait for `X-RateLimit-Reset`
* On `5xx` → retry with exponential backoff (start \~1s, max 3–5 attempts)

## Notes

* `404` = resource doesn't exist
* Empty results (`200` + `[]`) = valid, but no data
* `400` and `5xx` are not charged
* Per-result endpoints only charge for data returned
