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

# Errors

> Error response format, status codes, and rate limiting

Every error response has a non-2xx status code and a consistent body:

```json theme={null}
{
  "error": {
    "id": "404",
    "name": "not_found",
    "detail": "Transaction not found"
  }
}
```

`id` mirrors the HTTP status, `name` is a stable machine-readable code, and `detail` is a human-readable explanation (its wording may change — branch on `name`, not `detail`).

## Error codes

| Status | `name`                | When                                                                                      |
| ------ | --------------------- | ----------------------------------------------------------------------------------------- |
| 400    | `bad_request`         | Invalid JSON, missing/invalid fields, malformed amounts or dates, invalid cursor          |
| 401    | `unauthorized`        | Missing, invalid, or revoked API key                                                      |
| 403    | `forbidden`           | Read-only key on a write endpoint, no access to the workspace, or workspace archived      |
| 404    | `not_found`           | Unknown endpoint, or the workspace/account/transaction/merchant/category doesn't exist    |
| 409    | `conflict`            | Duplicate name (e.g. merchant or category group already exists)                           |
| 429    | `rate_limit_exceeded` | More than 200 requests in an hour for this key                                            |
| 500    | `internal_error`      | Something went wrong on our side — retry with backoff, and contact support if it persists |

## Rate limiting

Each API key may make **200 requests per hour**. When you exceed it, the response is `429` with a `Retry-After` header containing the number of seconds until the window resets:

```text theme={null}
HTTP/1.1 429 Too Many Requests
Retry-After: 1284

{ "error": { "id": "429", "name": "rate_limit_exceeded", "detail": "Rate limit exceeded. The limit is 200 requests per hour per API key." } }
```

Batch endpoints help you stay under the limit — for example, [`POST /transactions`](/api/transactions) accepts up to 100 transactions in one request.

## Validation errors reference fields by path

Field errors name the offending field, including array indices, so you can pinpoint the bad row in a batch:

```json theme={null}
{
  "error": {
    "id": "400",
    "name": "bad_request",
    "detail": "transactions[2].amount must be a decimal string in the workspace currency (e.g. \"-12.34\")"
  }
}
```
