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

# Errors

> Error handling and response codes

## Error Response Format

All errors return a JSON object with this structure:

```typescript theme={null}
type ErrorResponse = {
  error: {
    message: string;
    type: string;
    code?: string;
    metadata?: Record<string, unknown>;
  };
};
```

The HTTP status code matches the error type. Request validation errors return non-200 status codes. Errors occurring during generation may be returned in the response body or as SSE events (for streaming).

## HTTP Status Codes

### 400 Bad Request

Invalid request parameters, malformed JSON, or missing required fields.

```json theme={null}
{
  "error": {
    "message": "Invalid request: model is required",
    "type": "invalid_request_error"
  }
}
```

Common causes:

* Missing required fields (`model`, `messages`)
* Invalid parameter values (e.g., `temperature` > 2.0)
* Malformed JSON
* Invalid message format

### 401 Unauthorized

Invalid, expired, or missing API key.

```json theme={null}
{
  "error": {
    "message": "Authentication required",
    "type": "authentication_error"
  }
}
```

### 402 Payment Required

Insufficient credits or account balance.

```json theme={null}
{
  "error": {
    "message": "Insufficient credits",
    "type": "insufficient_quota_error"
  }
}
```

### 403 Forbidden

Content moderation failure. Input was flagged by safety systems.

```json theme={null}
{
  "error": {
    "message": "Content flagged by moderation",
    "type": "content_filter_error",
    "metadata": {
      "reasons": ["violence", "harassment"],
      "flagged_input": "...",
      "provider_name": "openai",
      "model_slug": "gpt-5-mini"
    }
  }
}
```

### 408 Request Timeout

Request exceeded timeout limit.

```json theme={null}
{
  "error": {
    "message": "Request timeout",
    "type": "timeout_error"
  }
}
```

### 429 Too Many Requests

Rate limit exceeded.

```json theme={null}
{
  "error": {
    "message": "Rate limit exceeded",
    "type": "rate_limit_error"
  }
}
```

Check rate limits via `GET /v1/key`. See [Limits documentation](/API/LIMITS).

### 502 Bad Gateway

Model provider error or invalid response.

```json theme={null}
{
  "error": {
    "message": "Provider error",
    "type": "provider_error",
    "metadata": {
      "provider_name": "openai",
      "raw": {...}
    }
  }
}
```

### 503 Service Unavailable

No available provider meets routing requirements.

```json theme={null}
{
  "error": {
    "message": "No available provider",
    "type": "service_unavailable_error"
  }
}
```

## Error Types

### `invalid_request_error`

Request validation failed. Check parameter types and required fields.

### `authentication_error`

API key authentication failed. Verify key is valid and active.

### `insufficient_quota_error`

Account lacks sufficient credits. Add credits to continue.

### `rate_limit_error`

Request rate exceeds limits. Implement exponential backoff.

### `content_filter_error`

Input flagged by content moderation. Review input content.

### `timeout_error`

Request exceeded timeout. Retry with shorter context or simpler request.

### `provider_error`

Model provider returned an error. May be transient - retry request.

### `service_unavailable_error`

No providers available matching routing requirements. Adjust `provider` preferences or retry later.

## Error Metadata

Some errors include metadata for debugging:

### Moderation Errors

```typescript theme={null}
type ModerationErrorMetadata = {
  reasons: string[];        // Flag categories
  flagged_input: string;     // Flagged content
  provider_name: string;     // Provider that flagged
  model_slug: string;        // Model identifier
};
```

### Provider Errors

```typescript theme={null}
type ProviderErrorMetadata = {
  provider_name: string;     // Provider identifier
  raw: unknown;              // Raw provider response
};
```

## Error Handling Examples

### Python

```python theme={null}
import requests

try:
  response = requests.post(
    "https://api.anannas.ai/v1/chat/completions",
    headers={"Authorization": f"Bearer {api_key}"},
    json={"model": "openai/gpt-5-mini", "messages": [...]}
  )
  response.raise_for_status()
  data = response.json()
except requests.HTTPError as e:
  if e.response.status_code == 401:
    print("Invalid API key")
  elif e.response.status_code == 402:
    print("Insufficient credits")
  elif e.response.status_code == 429:
    print("Rate limit exceeded - retry after delay")
  else:
    error_data = e.response.json()
    print(f"Error: {error_data['error']['message']}")
```

### TypeScript

```typescript theme={null}
try {
  const response = await fetch("https://api.anannas.ai/v1/chat/completions", {
    method: "POST",
    headers: {
      "Authorization": `Bearer ${apiKey}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      model: "openai/gpt-5-mini",
      messages: [...]
    }),
  });

  if (!response.ok) {
    const error = await response.json();
    switch (response.status) {
      case 401:
        console.error("Invalid API key");
        break;
      case 402:
        console.error("Insufficient credits");
        break;
      case 429:
        console.error("Rate limit exceeded");
        break;
      default:
        console.error(error.error.message);
    }
    return;
  }

  const data = await response.json();
} catch (error) {
  console.error("Request failed:", error);
}
```

## Retry Logic

Implement exponential backoff for transient errors:

```python theme={null}
import time
import random

def retry_with_backoff(func, max_retries=3):
  for attempt in range(max_retries):
    try:
      return func()
    except requests.HTTPError as e:
      if e.response.status_code in [429, 502, 503]:
        wait = (2 ** attempt) + random.uniform(0, 1)
        time.sleep(wait)
        continue
      raise
  raise Exception("Max retries exceeded")
```

## Streaming Errors

In streaming responses, errors are sent as SSE events:

```
data: {"error": {"message": "Rate limit exceeded", "type": "rate_limit_error"}}
```

Parse and handle errors in your SSE event loop.

## Best Practices

1. **Check Status Codes**: Always verify HTTP status before parsing JSON
2. **Handle 429**: Implement exponential backoff for rate limits
3. **Log Metadata**: Include error metadata in logs for debugging
4. **User-Friendly Messages**: Translate technical errors to user-friendly messages
5. **Retry Transient Errors**: Retry 502, 503, and 408 errors
6. **Monitor Credits**: Track 402 errors and alert when credits are low

## See Also

* [Authentication](/API/Authentication) - API key management
* [Limits](/API/LIMITS) - Rate limits and quotas
