# Errors & quotas

All errors share one envelope:

```
json{
    "error": {
        "code": "rate_limited",
        "message": "..."
    }
}
```

SDKs turn this into a native exception (`FivexerApiError`, `FivexerApiException`, etc.) with `status`, `code`, `message`, and — on `402`/`429` — the current quota snapshot.

## Quota headers

Every response carries `X-Quota-*` headers parsed onto `client.quota`:

- `x-quota-task-rate-limit` / `x-quota-task-rate-remaining`
- `x-quota-queued-tasks-limit` / `x-quota-queued-tasks-remaining`
- `x-quota-workers-limit` / `x-quota-workers-remaining`
- `x-quota-skills-limit` / `x-quota-skills-remaining`

Monitor `task_rate_remaining` and back off before you hit zero.

## Monthly matched-task quota

Separately from those per-request limits, each workspace includes a number of **matched tasks per UTC calendar month**:

| Workspace | Included matched tasks / month |
| --- | --- |
| Production (free) | 10,000 |
| Sandbox | 1,000 |

A sandbox is a demo surface, not a smaller plan — every other limit matches the free plan. Note that a sandbox reset wipes the routing data but deliberately **keeps the meter**, so repeated resets still count against the month.

**Running out does not reject writes.** On the free tier, exhausting the meter *pauses matching*: `POST /tasks` keeps returning `202` and tasks keep queuing, they simply stop being assigned until the meter resets. Nothing is dropped. That means you will never see a 402 for the monthly quota — what you'll see is the queue growing, and eventually a `402 plan_limit_exceeded` carrying `x-quota-queued-tasks-*` once `maxQueuedTasks` fills.

Read the meter programmatically from `GET /v1/stats`:

```
json{
    "meter": { "period": "202607", "matchedTasks": 8412, "includedTasksPerMonth": 10000 }
}
```

## Retry behavior

SDKs retry once by default on:

- `429 Too Many Requests` — honoring `Retry-After` if present
- `5xx` server errors

`POST /tasks` automatically sends an `Idempotency-Key` header, so a retried create is deduplicated safely.

## Common error codes

| Code | HTTP | Meaning |
| --- | --- | --- |
| `rate_limited` | 429 | Per-second task rate exceeded. Back off. |
| `plan_limit_exceeded` | 402 | A plan resource limit is full — queued tasks, workers, skills, attachments. Never the monthly meter. |
| `not_found` | 404 | Task/worker/decision does not exist. |
| `validation_error` | 400 | Request body failed validation. |
| `unauthorized` | 401 | Invalid or missing API key. |
| `forbidden` | 403 | Key lacks permission for this operation. |
