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

# Tratamento de Erros

> Lide com erros de API de forma elegante

## Formato da Resposta de Erro

Todos os erros retornam um formato JSON consistente com [dicas Agent-First](/guides/agent-first-api) opcionais:

```json theme={null}
{
  "error": {
    "message": "Human-readable error description",
    "type": "error_type",
    "code": "error_code",
    "param": "parameter_name",
    "did_you_mean": "suggested_model",
    "suggestions": [{"id": "model-id"}],
    "hint": "Next step guidance",
    "retryable": true,
    "retry_after": 30
  }
}
```

Os campos base obrigatórios (`message`, `type`) estão sempre presentes. `code` e `param` são opcionais e aparecem apenas quando relevantes. Os campos de sugestão (`did_you_mean`, `suggestions`, `hint`, `retryable`, `retry_after`, `balance_usd`, `estimated_cost_usd`) são extensões opcionais para autocorreção de agentes de IA. Veja o [Guia da Agent-First API](/guides/agent-first-api) para mais detalhes.

Endpoints compatíveis com OpenAI usam os tipos de erro estáveis do gateway da TokenLab. Endpoints compatíveis com Anthropic e Gemini usam suas próprias famílias nativas de erro e formatos de resposta.

## Códigos de Status HTTP

| Código | Descrição                                                   |
| ------ | ----------------------------------------------------------- |
| 400    | Bad Request - Parâmetros inválidos                          |
| 401    | Unauthorized - Chave de API inválida ou ausente             |
| 402    | Payment Required - Saldo insuficiente                       |
| 403    | Forbidden - Acesso negado ou modelo não permitido           |
| 404    | Not Found - Modelo ou recurso não encontrado                |
| 413    | Carga muito grande - Tamanho de entrada ou arquivo excedido |
| 429    | Too Many Requests - Limite de taxa excedido                 |
| 500    | Erro interno do servidor                                    |
| 502    | Bad Gateway - Erro do provedor upstream                     |
| 503    | Service Unavailable - Serviço temporariamente indisponível  |
| 504    | Gateway Timeout - Tempo de requisição esgotado              |

## Tipos de Erro

### Erros de Autenticação (401)

| Tipo              | Código            | Descrição                                 |
| ----------------- | ----------------- | ----------------------------------------- |
| `invalid_api_key` | `invalid_api_key` | A chave de API está ausente ou é inválida |
| `expired_api_key` | `expired_api_key` | A chave de API foi revogada               |

```python theme={null}
from openai import OpenAI, AuthenticationError

try:
    response = client.chat.completions.create(...)
except AuthenticationError as e:
    print(f"Authentication failed: {e.message}")
```

### Erros de Pagamento (402)

| Tipo                   | Código                 | Descrição                              |
| ---------------------- | ---------------------- | -------------------------------------- |
| `insufficient_balance` | `insufficient_balance` | Saldo da conta insuficiente            |
| `quota_exceeded`       | `quota_exceeded`       | Limite de uso da chave de API atingido |

```python theme={null}
from openai import OpenAI, APIStatusError

try:
    response = client.chat.completions.create(...)
except APIStatusError as e:
    if e.status_code == 402:
        print("Please top up your account balance")
```

### Erros de Acesso (403)

| Tipo            | Código              | Descrição                                   |
| --------------- | ------------------- | ------------------------------------------- |
| `access_denied` | `access_denied`     | Acesso ao recurso negado                    |
| `access_denied` | `model_not_allowed` | Modelo não permitido para esta chave de API |

```json theme={null}
{
  "error": {
    "message": "You don't have permission to access this model",
    "type": "access_denied",
    "code": "model_not_allowed"
  }
}
```

### Erros de Validação (400)

| Tipo                      | Descrição                                                            |
| ------------------------- | -------------------------------------------------------------------- |
| `invalid_request_error`   | Parâmetros da requisição inválidos                                   |
| `context_length_exceeded` | Entrada longa demais para o modelo                                   |
| `model_not_found`         | O modelo solicitado não está disponível nos detalhes do modelo atual |

```json theme={null}
{
  "error": {
    "message": "Model not found: please check the model name",
    "type": "invalid_request_error",
    "param": "model",
    "code": "model_not_found",
    "did_you_mean": "gpt-5.4",
    "suggestions": [{"id": "gpt-5.4"}, {"id": "gpt-5-mini"}],
    "hint": "Did you mean 'gpt-5.4'? Use GET https://api.tokenlab.sh/v1/models to list all available models."
  }
}
```

Rotas públicas não distinguem no corpo da resposta estados como erro de digitação, modelo oculto, diferido ou não público. Se um modelo não estiver atualmente disponível através dos detalhes do modelo, a TokenLab retorna `model_not_found`.

### Erros de Limite de Taxa (429)

Quando você excede os limites de taxa:

```json theme={null}
{
  "error": {
    "message": "Rate limit: 1000 rpm exceeded",
    "type": "rate_limit_exceeded",
    "code": "rate_limit_exceeded",
    "retryable": true,
    "retry_after": 8,
    "hint": "Rate limited. Retry after 8s. Current limit: 1000/min for user role."
  }
}
```

**Cabeçalhos incluídos:**

```
Retry-After: 8
```

O cabeçalho `Retry-After` e o campo `retry_after` indicam ambos os segundos exatos para aguardar antes de tentar novamente.

### Payload Muito Grande (413)

Quando o tamanho da entrada ou do arquivo excede os limites:

```json theme={null}
{
  "error": {
    "message": "Input size exceeds maximum allowed",
    "type": "invalid_request_error",
    "code": "payload_too_large"
  }
}
```

Causas comuns:

* Arquivo de imagem muito grande (máx. 20MB)
* Arquivo de áudio muito grande (máx. 25MB)
* Texto de entrada que excede o comprimento de contexto do modelo

### Erros Upstream (502, 503)

| Tipo                  | Descrição                         |
| --------------------- | --------------------------------- |
| `upstream_error`      | O provedor retornou um erro       |
| `all_channels_failed` | Nenhum provedor disponível        |
| `timeout_error`       | Requisição excedeu o tempo limite |

Quando todos os canais falham, a resposta inclui modelos alternativos:

```json theme={null}
{
  "error": {
    "message": "Model claude-opus-4-6 temporarily unavailable",
    "code": "all_channels_failed",
    "retryable": true,
    "retry_after": 30,
    "alternatives": [
      {"id": "claude-sonnet-4-6", "status": "available", "tags": []},
      {"id": "gpt-5-mini", "status": "available", "tags": []}
    ],
    "hint": "Retry in 30s or switch to an available model."
  }
}
```

## Tratamento de Erros em Python

```python theme={null}
from openai import OpenAI, APIError, RateLimitError, APIConnectionError

client = OpenAI(
    api_key="sk-your-api-key",
    base_url="https://api.tokenlab.sh/v1"
)

def chat_with_retry(messages, max_retries=3):
    for attempt in range(max_retries):
        try:
            return client.chat.completions.create(
                model="gpt-4o",
                messages=messages
            )
        except RateLimitError as e:
            if attempt < max_retries - 1:
                import time
                time.sleep(2 ** attempt)  # Exponential backoff
                continue
            raise
        except APIConnectionError as e:
            print(f"Connection error: {e}")
            raise
        except APIError as e:
            print(f"API error: {e.status_code} - {e.message}")
            raise
```

## Tratamento de Erros em JavaScript

```javascript theme={null}
import OpenAI from 'openai';

const client = new OpenAI({
  apiKey: 'sk-your-api-key',
  baseURL: 'https://api.tokenlab.sh/v1'
});

async function chatWithRetry(messages, maxRetries = 3) {
  for (let attempt = 0; attempt < maxRetries; attempt++) {
    try {
      return await client.chat.completions.create({
        model: 'gpt-4o',
        messages
      });
    } catch (error) {
      if (error instanceof OpenAI.RateLimitError) {
        if (attempt < maxRetries - 1) {
          await new Promise(r => setTimeout(r, 2 ** attempt * 1000));
          continue;
        }
      }
      throw error;
    }
  }
}
```

## Melhores práticas

<AccordionGroup>
  <Accordion title="Implemente backoff exponencial">
    Quando estiver rate limited, espere períodos progressivamente maiores entre tentativas:

    ```python theme={null}
    wait_time = 2 ** attempt  # 1s, 2s, 4s, 8s...
    ```
  </Accordion>

  <Accordion title="Defina timeouts">
    Sempre defina timeouts razoáveis para evitar requisições travadas:

    ```python theme={null}
    client = OpenAI(timeout=60.0)  # 60 second timeout
    ```
  </Accordion>

  <Accordion title="Registre erros para depuração">
    Registre a resposta completa de erro, incluindo o ID da requisição, para suporte:

    ```python theme={null}
    except APIError as e:
        logger.error(f"API Error: {e.status_code} - {e.message}")
    ```
  </Accordion>

  <Accordion title="Trate erros específicos do modelo">
    Alguns modelos têm requisitos específicos (por exemplo, tokens máximos, formatos de imagem).
    Valide as entradas antes de fazer as requisições.
  </Accordion>
</AccordionGroup>
