# Errors

Error response format and the status codes the API returns.

When a request fails, the API returns a non-2xx status code and a JSON body with an `error` field describing the problem.

```json
{
  "error": "Forbidden - Admin access required"
}
```

Successful responses instead carry `"success": true` and a `data` payload (legacy endpoints), or the resource / `{ data, pagination }` envelope (`/api/v1`).

## Error shapes

The legacy endpoints return a human-readable `{ "error": "..." }` message. The **`/api/v1`** endpoints return a stable **machine code** in `error`, optionally with a `message` and extra fields:

```json
{ "error": "insufficient_scope", "message": "This API key is missing required scope(s): candidates:read.", "requiredScopes": ["candidates:read"], "grantedScopes": ["roles:read"] }
```

```json
{ "error": "bad_request", "message": "Invalid field(s)", "details": ["status must be a non-empty string"] }
```

`/api/v1` machine codes: `bad_request` (400), `insufficient_scope` (403), `forbidden` (403), `not_found` (404), `internal_error` (500). On `insufficient_scope`, read `requiredScopes` / `grantedScopes` to self-correct.

## Status codes

| Status | Meaning | What to do |
| --- | --- | --- |
| `200` | Success | Read the response body. |
| `201` | Created | A `POST` created the resource; read it from the body. |
| `204` | No content | A `DELETE` succeeded; there is no body. |
| `400` | Validation error | Fix the request body or parameters; `error`/`details` say what is wrong. |
| `401` | Unauthorized | No valid API key was supplied. Check the `Authorization` header. |
| `403` | Forbidden / insufficient scope | The key's owner lacks the required role, **or** the key is missing the required `/api/v1` scope (`insufficient_scope`). |
| `404` | Not found | The resource does not exist — or, on `/api/v1`, exists but is not visible to the key (no existence leak). |
| `429` | Rate limited | Honor the `Retry-After` header and back off. |
| `500` | Server error | Transient — retry with backoff; if it persists, contact support. |

## Common error messages

| Endpoint | Message | Cause |
| --- | --- | --- |
| Create key | `Name is required` | Missing `name` in the body. |
| Create key | `userId is required` | Missing `userId` in the body. |
| Create key | `expiresInDays must be between 1 and 365` | Out-of-range expiry. |
| Create key | `Target user not found` | `userId` does not match a user. |
| Revoke / usage | `Key not found` | The `id` does not match a key. |
| Any | `Unauthorized` | Missing or invalid key. |
| Any (admin) | `Forbidden - Admin access required` | Key owner is not an admin. |