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

# Errors

> Every error is a stable JSON envelope with a machine-readable code.

All errors - including unexpected server errors - return:

```json theme={null}
{
  "error": "Human-readable message",
  "code": "MACHINE_READABLE_CODE"
}
```

Some errors add context fields (`details`, `limit`, `tokenBalance`, `resetAt`, ...). The `code` values are stable; branch on them, not on messages.

## Common codes

| HTTP | Code                                                        | Meaning                                            | What to do                                               |
| ---- | ----------------------------------------------------------- | -------------------------------------------------- | -------------------------------------------------------- |
| 400  | `INVALID_MODULES`                                           | Unknown or malformed `modules` array               | Fix the module names                                     |
| 400  | `INVALID_FOUNDER_PROFILE`                                   | Missing/invalid `founderProfile` for `founderFit`  | Fix the fields listed in `details`                       |
| 400  | `INVALID_ANALYSIS_ID`                                       | Malformed run/report id                            | Use the id returned by create                            |
| 401  | (auth codes)                                                | Bad key, signature, timestamp, or nonce            | Check [Authentication](/authentication); sync your clock |
| 402  | `INSUFFICIENT_TOKENS`                                       | Deep scan with no quota and no tokens              | Top up or use `scanType: "starter"`                      |
| 403  | `MODULES_REQUIRE_DEEP`                                      | Modules requested on a non-deep report             | Run a deep scan first                                    |
| 403  | `STARTER_LIMIT_REACHED`                                     | Starter scan allowance exhausted (free/regional)   | Wait for reset or run deep                               |
| 429  | `FAIR_USE_LIMIT`                                            | Paid account hit the starter fair-use ceiling      | Contact support to lift it                               |
| 404  | `ANALYSIS_NOT_FOUND`                                        | Unknown id, or the run belongs to another account  | Check the id                                             |
| 409  | `ANALYSIS_NOT_COMPLETE`                                     | Run still processing                               | Keep polling                                             |
| 409  | `ENRICHMENT_NOT_COMPLETE`                                   | Export requested before enrichment                 | Call enrich, poll, retry                                 |
| 409  | `MODULE_ALREADY_GENERATED`                                  | Per-module cap reached (one success per report)    | Read the payload from the export                         |
| 413  | `PAYLOAD_TOO_LARGE`                                         | Body over the size limit                           | Trim the request                                         |
| 422  | `ANALYSIS_FAILED`                                           | The analysis itself failed                         | Create a new run                                         |
| 429  | `RATE_LIMITED`                                              | Per-route rate limit hit                           | Back off and retry                                       |
| 429  | `CONCURRENT_LIMIT_REACHED`                                  | Too many analyses in flight (3 free / 2 deep)      | Wait for one to finish, re-POST the same `clientRunId`   |
| 429  | `DAILY_LIMIT_REACHED`                                       | Rolling 24h creation ceiling                       | Retry after `resetAt`                                    |
| 429  | `REGEN_LIMIT_REACHED`                                       | Founder Fit lifetime cap on this report            | No retry - cap is final                                  |
| 503  | `INSUFFICIENT_TIME_BUDGET`                                  | Inline module refused to start late in the request | Retry the same enrich call                               |
| 503  | `SERVICE_DISABLED` / `GENERATION_DISABLED` / `POD_DISABLED` | Feature temporarily off                            | Retry later                                              |
| 502  | `ENQUEUE_FAILED`                                            | Background dispatch failed                         | Retry; nothing was consumed                              |
| 500  | `INTERNAL_ERROR`                                            | Unexpected server error                            | Retry with backoff                                       |

## Partial success (207)

Enrich returns HTTP `207` with a **success-shaped** body when some sections or modules failed while others succeeded. Inspect `failures` (core sections) and the per-module `modules` map, then retry the failed parts - the route is idempotent and never regenerates what already completed.
