# Errors

> The error envelope and the stable error codes.

Source: https://docs.tune.toys/developers/errors/ (updated 2026-11-01)

Every failing response uses one envelope. `requestId` echoes the `X-Request-Id` response header; include it in support requests.

```json
{
  "error": {
    "code": "SCOPE",
    "message": "This key is missing a required scope.",
    "details": {
      "requiredScopes": ["write:projects"],
      "missingScopes": ["write:projects"]
    },
    "requestId": "req_..."
  }
}
```

Match on `code`, never on `message`. `details` is bounded, machine-readable context.

| Code                                    | Status | Meaning                                                       |
| --------------------------------------- | ------ | ------------------------------------------------------------- |
| `MIXED_AUTH`                            | 400    | A key was sent with a cookie or another credential            |
| `IDEMPOTENCY_KEY`                       | 400    | A required `Idempotency-Key` is missing or malformed          |
| `VALIDATION`                            | 400    | The body failed schema validation; `details` carries paths    |
| `KEY_INVALID`                           | 401    | Unknown, malformed or expired key                             |
| `KEY_NETWORK`                           | 403    | The caller address is outside the key's allowlist             |
| `AUTH_MODE`                             | 403    | The route does not accept keys                                |
| `SCOPE`                                 | 403    | A required scope is missing                                   |
| `TIER_REQUIRED`                         | 403    | The feature needs a pro app                                   |
| `PUBLISHER_ROLE`                        | 403    | The acting user lacks the publisher role                      |
| `VERSION_CONFLICT`, `REVISION_CONFLICT` | 409    | Your expected version or revision is stale; re-read and retry |
| `IDEMPOTENCY_CONFLICT`                  | 409    | The same `Idempotency-Key` was used with different input      |
| `RATE_LIMIT`                            | 429    | A bucket or the daily quota is exhausted                      |

The authoritative per-route list is in the [route index](https://docs.tune.toys/developers/api/) and the OpenAPI document.
