# Errors

The API uses standard HTTP status codes to indicate success or failure.

## Error Response Format

```json
{
  "error": {
    "code": "ERROR_CODE",
    "message": "Human-readable error message"
  },
  "meta": {
    "request_id": "abc123"
  }
}
```

## Common Error Codes

| HTTP Status | Error Code | Description |
|-------------|------------|-------------|
| 400 | `BAD_REQUEST` | The request body is malformed or missing required fields |
| 401 | `UNAUTHORIZED` | Authentication is required but was not provided |
| 403 | `FORBIDDEN` | The authenticated user lacks permission for this action |
| 404 | `NOT_FOUND` | The requested resource does not exist |
| 409 | `CONFLICT` | The request conflicts with existing data (e.g., duplicate) |
| 422 | `VALIDATION_ERROR` | The request data failed validation rules |
| 429 | `RATE_LIMITED` | Too many requests; slow down |
| 500 | `INTERNAL_ERROR` | An unexpected server error occurred |
| 503 | `SERVICE_UNAVAILABLE` | The service is temporarily unavailable |

## Validation Errors

Validation errors (422) include field-specific details:

```json
{
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "Validation failed",
    "details": {
      "name": "name is required",
      "email": "invalid email format"
    }
  }
}
```

## Rate Limiting

When rate limited (429), the response includes headers indicating when you can retry:

| Header | Description |
|--------|-------------|
| `X-RateLimit-Limit` | Maximum requests per window |
| `X-RateLimit-Remaining` | Requests remaining in current window |
| `X-RateLimit-Reset` | Unix timestamp when the window resets |
| `Retry-After` | Seconds to wait before retrying |
