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

# Errors

> One envelope. Machine-readable code. Human-readable message.

## Envelope

```json theme={null}
{
  "error": {
    "code":    "insufficient_credits",
    "message": "Not enough credits to render, need 10, have 4.",
    "needed":  10,
    "have":    4
  }
}
```

`code` is stable and safe to switch on. `message` is for humans and may
change. Extra structured fields are namespaced per error code.

## Error codes

| Code                   | HTTP | Meaning                                                                          |
| ---------------------- | ---- | -------------------------------------------------------------------------------- |
| `unauthenticated`      | 401  | Missing or invalid `Authorization` header.                                       |
| `rate_limited`         | 429  | Per-account rate cap hit. Honor `Retry-After` header AND `retry_after_ms` field. |
| `invalid_args`         | 400  | Body or query failed validation.                                                 |
| `workflow_not_found`   | 404  | No workflow with that id, or not owned by this user.                             |
| `clip_not_found`       | 404  | Clip id doesn't exist in the workflow graph.                                     |
| `track_not_found`      | 404  | Track id not derivable from the workflow's edges.                                |
| `job_not_found`        | 404  | Render job id doesn't exist.                                                     |
| `insufficient_credits` | 402  | Reserve would go below zero. Includes `needed`, `have`.                          |
| `monthly_cost_cap`     | 402  | Per-user upstream USD budget exceeded for the month.                             |
| `workflow_too_large`   | 413  | Workflow JSON exceeds 5 MB ceiling.                                              |
| `ledger_read`          | 500  | Unrecoverable read error on the ledger; retryable.                               |
| `upstream`             | 502  | An underlying generation provider returned a non-200.                            |
| `timeout`              | 504  | Upstream call exceeded the per-route deadline.                                   |

## Handling

<CodeGroup>
  ```js Node theme={null}
  const res = await fetch(url, { method: 'POST', headers, body });
  if (!res.ok) {
    const { error } = await res.json();
    if (error.code === 'insufficient_credits') {
      // surface upgrade CTA with error.needed / error.have
    } else {
      // generic error surface, use error.message
    }
  }
  ```

  ```py Python theme={null}
  import httpx
  r = httpx.post(url, headers=headers, json=body)
  if r.status_code >= 400:
      err = r.json()["error"]
      if err["code"] == "insufficient_credits":
          ...
  ```
</CodeGroup>
