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

# Fallbacks e retries no AI Gateway

> Tente novamente solicitações de LLM com falha usando backoff exponencial e configure modelos de fallback no Toqan Router para lidar com rate limits, erros de servidor e falhas de rede.

**Casos de uso**

* Contornar erros transitórios dos provedores sem expor falhas aos usuários finais.
* Failover automático para um provedor de backup quando o principal está degradado ou com rate limit atingido.
* Absorver picos curtos de rate limit sem intervenção manual nem lógica de retry personalizada.
* Cumprir SLAs de disponibilidade em recursos de produção sem adicionar código de retry a cada serviço.

***

> [card] [Retries](#retries)
>
> Tente novamente solicitações com falha automaticamente, com backoff exponencial. Configure quais códigos de erro HTTP disparam retries e quantas tentativas fazer.

> [card] [Fallbacks](#fallbacks)
>
> Roteie para outro modelo quando o principal falhar. Defina uma cadeia de fallback entre provedores para alta disponibilidade.

## Retries

Tente novamente solicitações com falha automaticamente, com backoff exponencial.

### Início rápido

```bash cURL theme={"theme":{"light":"github-light","dark":"github-dark"}}
curl -X POST https://router.toqan.ai/eu/v3/router/responses \
  -H "Authorization: Bearer $TOQAN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "openai/gpt-5.4-mini",
    "input": "Analyze customer feedback",
    "retry": {"count": 3, "on_codes": [429, 500, 502, 503, 504]}
  }'
```

```typescript TypeScript theme={"theme":{"light":"github-light","dark":"github-dark"}}
import OpenAI from "openai";

const client = new OpenAI({
  apiKey: process.env.TOQAN_API_KEY,
  baseURL: "https://router.toqan.ai/eu/v3/router",
});

const response = await client.responses.create({
  model: "openai/gpt-5.4-mini",
  input: "Analyze customer feedback",
  retry: {
    count: 3,
    on_codes: [429, 500, 502, 503, 504],
  },
});

console.log(response.output_text);
```

```python Python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from openai import OpenAI
import os

client = OpenAI(
    api_key=os.environ.get("TOQAN_API_KEY"),
    base_url="https://router.toqan.ai/eu/v3/router",
)

response = client.responses.create(
    model="openai/gpt-5.4-mini",
    input="Analyze customer feedback",
    extra_body={
        "retry": {"count": 3, "on_codes": [429, 500, 502, 503, 504]}
    },
)

print(response.output_text)
```

```typescript TypeScript (Chat Completions) theme={"theme":{"light":"github-light","dark":"github-dark"}}
import OpenAI from "openai";

const client = new OpenAI({
  apiKey: process.env.TOQAN_API_KEY,
  baseURL: "https://router.toqan.ai/eu/v3/router",
});

const response = await client.chat.completions.create({
  model: "openai/gpt-5.4-mini",
  messages: [{ role: "user", content: "Analyze customer feedback" }],
  retry: {
    count: 3,
    on_codes: [429, 500, 502, 503, 504],
  },
});
```

### Configuração

| Parâmetro | Tipo | Obrigatório | Descrição |
| - | - | - | - |
| `count` | number | Sim | Retries por modelo após a tentativa inicial (0-5). `0` desativa os retries. |
| `on_codes` | number\[] | Não | Códigos de status HTTP que disparam retries (padrão: \[408, 429, 500, 502, 503, 504, 529]) |

Quando `retry` é omitido, o gateway tenta novamente duas vezes nos códigos padrão. Defina `"retry": {"count": 0}` para fazer exatamente uma chamada por modelo.

### Códigos de erro

| Código | Significado | Retry? | Causa comum |
| - | - | - | - |
| `408` | Timeout da solicitação |  Sim | Timeout do provedor |
| `429` | Rate limit excedido |  Sim | Excesso de solicitações |
| `500` | Erro interno do servidor |  Sim | Problema no provedor |
| `501` | Não implementado |  Não | Definitivo; uma nova tentativa não terá sucesso |
| `502` | Bad gateway |  Sim | Problema de rede/gateway |
| `503` | Serviço indisponível |  Sim | Manutenção do provedor |
| `504` | Timeout do gateway |  Sim | Sobrecarga do provedor |
| `529` | Provedor sobrecarregado |  Sim | Sobrecarga do provedor |
| `400` | Solicitação inválida |  Não | Parâmetros inválidos |
| `401` | Não autorizado |  Não | Chave de API inválida |
| `403` | Proibido |  Não | Acesso negado |

### Estratégias de retry

```typescript TypeScript theme={"theme":{"light":"github-light","dark":"github-dark"}}
// Conservative
retry: {
  count: 2,
  on_codes: [429, 503]  // Only rate limits and service unavailable
}

// Balanced (recommended)
retry: {
  count: 3,
  on_codes: [429, 500, 502, 503, 504]  // All transient errors
}

// Aggressive
retry: {
  count: 5,
  on_codes: [429, 500, 502, 503, 504]  // Max retries
}
```

### Algoritmo de backoff

#### Backoff exponencial com jitter

* Tentativa 1: 1s (±25%).
* Tentativa 2: 2s (±25%).
* Tentativa 3: 4s (±25%).
* Tentativa 4: 8s (±25%).
* Tentativa 5: 16s (±25%).
  **Atraso total máximo**: \~31 segundos para 5 retries

### Exemplos de código

```bash cURL theme={"theme":{"light":"github-light","dark":"github-dark"}}
curl -X POST https://router.toqan.ai/eu/v3/router/responses \
  -H "Authorization: Bearer $TOQAN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "openai/gpt-5.4-mini",
    "input": "Analyze customer feedback and provide sentiment analysis",
    "retry": {
      "count": 3,
      "on_codes": [429, 500, 502, 503, 504]
    }
  }'
```

```bash cURL (Chat Completions) theme={"theme":{"light":"github-light","dark":"github-dark"}}
curl -X POST https://router.toqan.ai/eu/v3/router/chat/completions \
  -H "Authorization: Bearer $TOQAN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "openai/gpt-5.4-mini",
    "messages": [
      {
        "role": "user",
        "content": "Analyze customer feedback and provide sentiment analysis"
      }
    ],
    "retry": {
      "count": 3,
      "on_codes": [429, 500, 502, 503, 504]
    }
  }'
```

```typescript TypeScript theme={"theme":{"light":"github-light","dark":"github-dark"}}
import OpenAI from "openai";

const client = new OpenAI({
  apiKey: process.env.TOQAN_API_KEY,
  baseURL: "https://router.toqan.ai/eu/v3/router",
});

const response = await client.responses.create({
  model: "openai/gpt-5.4-mini",
  input: "Analyze customer feedback and provide sentiment analysis",
  retry: {
    count: 3,
    on_codes: [429, 500, 502, 503, 504],
  },
});

console.log(response.output_text);
```

```python Python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from openai import OpenAI
import os

client = OpenAI(
    api_key=os.environ.get("TOQAN_API_KEY"),
    base_url="https://router.toqan.ai/eu/v3/router",
)

response = client.responses.create(
    model="openai/gpt-5.4-mini",
    input="Analyze customer feedback and provide sentiment analysis",
    extra_body={
        "retry": {
            "count": 3,
            "on_codes": [429, 500, 502, 503, 504],
        }
    },
)

print(response.output_text)
```

```typescript TypeScript (Chat Completions) theme={"theme":{"light":"github-light","dark":"github-dark"}}
import OpenAI from "openai";

const client = new OpenAI({
  apiKey: process.env.TOQAN_API_KEY,
  baseURL: "https://router.toqan.ai/eu/v3/router",
});

const response = await client.chat.completions.create({
  model: "openai/gpt-5.4-mini",
  messages: [
    {
      role: "user",
      content: "Analyze customer feedback and provide sentiment analysis",
    },
  ],
  retry: {
    count: 3,
    on_codes: [429, 500, 502, 503, 504],
  },
});
```

```python Python (Chat Completions) theme={"theme":{"light":"github-light","dark":"github-dark"}}
from openai import OpenAI
import os

client = OpenAI(
    api_key=os.environ.get("TOQAN_API_KEY"),
    base_url="https://router.toqan.ai/eu/v3/router",
)

response = client.chat.completions.create(
    model="openai/gpt-5.4-mini",
    messages=[
        {
            "role": "user",
            "content": "Analyze customer feedback and provide sentiment analysis",
        }
    ],
    extra_body={
        "retry": {
            "count": 3,
            "on_codes": [429, 500, 502, 503, 504],
        }
    },
)
```

### Boas práticas

#### Recomendações para produção

Siga estas orientações para uma configuração de produção sólida:

* Use `count: 2-3` para equilibrar confiabilidade e velocidade.
* Sempre inclua `429` (rate limits) em `on_codes`.
* Monitore as taxas de retry para detectar problemas sistêmicos.
* Implemente um circuit breaker para falhas persistentes.

#### Tratamento de erros

```typescript TypeScript theme={"theme":{"light":"github-light","dark":"github-dark"}}
import OpenAI from "openai";

const client = new OpenAI({
  apiKey: process.env.TOQAN_API_KEY,
  baseURL: "https://router.toqan.ai/eu/v3/router",
});

try {
  const response = await client.responses.create({
    model: "openai/gpt-5.4-mini",
    input: "Hello",
  });
} catch (error) {
  if (error instanceof OpenAI.APIError) {
    if (error.status === 400) {
      console.error('Bad request:', error.message);
    } else if (error.status >= 500) {
      console.error('Server error:', error.message);
    }
  }
}
```

```typescript TypeScript (Chat Completions) theme={"theme":{"light":"github-light","dark":"github-dark"}}
import OpenAI from "openai";

const client = new OpenAI({
  apiKey: process.env.TOQAN_API_KEY,
  baseURL: "https://router.toqan.ai/eu/v3/router",
});

try {
  const response = await client.chat.completions.create({
    model: "openai/gpt-5.4-mini",
    messages: [{ role: "user", content: "Hello" }],
  });
} catch (error) {
  if (error instanceof OpenAI.APIError) {
    if (error.status === 400) {
      // Don't retry client errors - fix the request
      console.error('Bad request:', error.message);
    } else if (error.status >= 500) {
      // Server errors might need manual intervention
      console.error('Server error:', error.message);
    }
  }
}
```

### Solução de problemas

**Taxas de retry altas**

* Verifique se os rate limits estão sendo atingidos com frequência.
* Confirme se as chaves de API têm cotas suficientes.
* Acompanhe as páginas de status dos provedores para identificar interrupções.

**Tempos de resposta lentos**

* Reduza a quantidade de retries em aplicações sensíveis à latência.
* Use valores de timeout menores com retries.
* Considere fallbacks para alternativas mais rápidas.

**Os erros continuam**

* Verifique se os códigos de erro estão na lista `on_codes`.
* Confirme se a quantidade de retries não se esgotou.
* Consulte a documentação de erros específica do provedor.

### Monitoramento

Acompanhe estas métricas de retry:

```typescript TypeScript theme={"theme":{"light":"github-light","dark":"github-dark"}}
const retryMetrics = {
  totalRequests: 0,
  retriedRequests: 0,
  retriesByAttempt: { 1: 0, 2: 0, 3: 0 }, // Retry attempt distribution
  retriesByCode: { 429: 0, 500: 0 }, // By error code
  avgRetryLatency: 0, // Added latency from retries
  finalFailures: 0, // Requests that failed after all retries
};
```

### Limitações

* **Aumento da latência**: os retries adicionam atraso (até 31s para 5 retries).
* **Impacto nos custos**: solicitações com falha ainda podem gerar cobranças.
* **Consumo de rate limit**: os retries são executados dentro do gateway em uma única solicitação recebida; assim, um retry conta uma vez para os rate limits e budgets da plataforma, enquanto cada tentativa conta para os rate limits do próprio provedor.
* **Retries limitados**: no máximo 5 retries por modelo após a tentativa inicial (até 6 chamadas), para evitar atrasos excessivos.
* **Erros sem retry**: um código de status só é tentado novamente quando está listado em `on_codes`. A maioria dos erros de cliente 4xx, como 400 e 403, não é tentada novamente; o 429 é tentado novamente quando está listado em `on_codes`.

### Uso avançado

**Configurações por ambiente:**

```typescript TypeScript theme={"theme":{"light":"github-light","dark":"github-dark"}}
const retryConfig = {
  development: { count: 1, on_codes: [429] }, // Fast feedback
  staging: { count: 2, on_codes: [429, 503] }, // Light retries
  production: { count: 3, on_codes: [429, 500, 502, 503, 504] }, // Full protection
};
```

**Com outros recursos:**

```json JSON theme={"theme":{"light":"github-light","dark":"github-dark"}}
{
  "retry": { "count": 3, "on_codes": [429, 503] },
  "timeout": { "call_timeout": 10000 },
  "fallbacks": [{ "model": "backup-model" }],
  "cache": { "type": "exact_match", "ttl": 300 }
}
```

**Lógica de retry personalizada (no cliente):**

```typescript TypeScript theme={"theme":{"light":"github-light","dark":"github-dark"}}
const customRetry = async (requestFn, maxAttempts = 3) => {
  for (let attempt = 1; attempt <= maxAttempts; attempt++) {
    try {
      return await requestFn();
    } catch (error) {
      if (attempt === maxAttempts || error.status < 500) {
        throw error; // Final attempt or non-retryable error
      }
      await new Promise(
        (resolve) => setTimeout(resolve, Math.pow(2, attempt) * 1000), // Exponential backoff
      );
    }
  }
};
```

## Fallbacks

Alterne automaticamente para outro modelo quando o principal falhar.

### Início rápido

```bash cURL theme={"theme":{"light":"github-light","dark":"github-dark"}}
curl -X POST https://router.toqan.ai/eu/v3/router/chat/completions \
  -H "Authorization: Bearer $TOQAN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "openai/gpt-5.4-mini",
    "messages": [{ "role": "user", "content": "Generate a product description" }],
    "fallbacks": [{ "model": "openai/gpt-5.6-sol" }, { "model": "azure/gpt-5.6-sol" }]
  }'
```

```typescript TypeScript theme={"theme":{"light":"github-light","dark":"github-dark"}}
import OpenAI from "openai";

const client = new OpenAI({
  apiKey: process.env.TOQAN_API_KEY,
  baseURL: "https://router.toqan.ai/eu/v3/router",
});

const response = await client.responses.create({
  model: "openai/gpt-5.4-mini",
  input: "Generate a product description",
  fallbacks: [{ model: "openai/gpt-5.6-sol" }, { model: "azure/gpt-5.6-sol" }],
});

console.log(response.output_text);
```

```typescript TypeScript (Chat Completions) theme={"theme":{"light":"github-light","dark":"github-dark"}}
import OpenAI from "openai";

const client = new OpenAI({
  apiKey: process.env.TOQAN_API_KEY,
  baseURL: "https://router.toqan.ai/eu/v3/router",
});

const response = await client.chat.completions.create({
  model: "openai/gpt-5.4-mini",
  messages: [{ role: "user", content: "Generate a product description" }],
  fallbacks: [{ model: "openai/gpt-5.6-sol" }, { model: "azure/gpt-5.6-sol" }],
});
```

### Configuração

| Parâmetro | Tipo | Obrigatório | Descrição |
| - | - | - | - |
| `fallbacks` | Array | Sim | Lista de modelos de fallback em ordem de preferência |
| `model` | string | Sim | Identificador do modelo de cada fallback |
| `fallback_on_codes` | number\[] | Não | Códigos de status que disparam o fallback. Padrão: `[408, 429, 500, 502, 503, 504, 529]`. Uma lista vazia usa o padrão. |

Defina `fallback_on_codes` no nível superior da solicitação. Uma lista personalizada **substitui os códigos padrão**. Por exemplo, inclua `400` junto com os padrões para fazer fallback em erros de solicitação inválida:

```json JSON theme={"theme":{"light":"github-light","dark":"github-dark"}}
{
  "model": "google/eu.claude-opus-5-5",
  "input": "Hello",
  "fallbacks": [{ "model": "google/gemini-2.5-pro" }],
  "fallback_on_codes": [400, 408, 429, 500, 502, 503, 504, 529]
}
```

Definir apenas `"fallback_on_codes": [400]` limita o fallback a `400`; rate limits e erros de servidor deixam de dispará-lo. Omita o campo ou use um array vazio para restaurar os padrões.

### Condições de disparo

Por padrão, os fallbacks são ativados nos erros abaixo. Substitua esse conjunto com `fallback_on_codes` em uma solicitação ou no `models_config` de uma regra de roteamento de Fallback. Informe até 20 inteiros únicos entre 400 e 599. Uma regra de roteamento correspondente substitui os modelos e códigos de fallback definidos na solicitação.

Por exemplo, `"fallback_on_codes": [429, 503]` limita o fallback a rate limits e indisponibilidade do serviço. Solicitações canceladas nunca fazem fallback. Modelos sem um recurso necessário são ignorados, independentemente dos códigos configurados.

| Código de erro | Descrição | Dispara fallback por padrão |
| - | - | - |
| `408` | Timeout da solicitação | Sim |
| `429` | Rate limit excedido | Sim |
| `500` | Erro interno do servidor | Sim |
| `501` | Não implementado | Não |
| `502` | Bad gateway | Sim |
| `503` | Serviço indisponível | Sim |
| `504` | Timeout do gateway | Sim |
| `529` | Provedor sobrecarregado | Sim |
| `404` | Não encontrado | Não |
| `400` | Solicitação inválida | Não |
| `401` | Não autorizado | Não |
| `403` | Proibido | Não |

### Boas práticas

Use no máximo 3 modelos de fallback. Ordene-os por preferência ou custo e escolha modelos com recursos semelhantes.

```typescript TypeScript theme={"theme":{"light":"github-light","dark":"github-dark"}}
// Cost-optimized: cheap then expensive
fallbacks: [{ model: "openai/gpt-5.4-mini" }, { model: "openai/gpt-5.6-sol" }];

// Reliability-optimized: different providers
fallbacks: [
  { model: "openai/gpt-5.6-sol" },
  { model: "anthropic/claude-sonnet-5" },
  { model: "azure/gpt-5.6-sol" },
];
```

### Exemplos de código

```bash cURL theme={"theme":{"light":"github-light","dark":"github-dark"}}
curl -X POST https://router.toqan.ai/eu/v3/router/responses \
  -H "Authorization: Bearer $TOQAN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "openai/gpt-5.4-mini",
    "input": "Generate a product description",
    "fallbacks": [
      { "model": "openai/gpt-5.6-sol" },
      { "model": "azure/gpt-5.6-sol" }
    ]
  }'
```

```bash cURL (Chat Completions) theme={"theme":{"light":"github-light","dark":"github-dark"}}
curl -X POST https://router.toqan.ai/eu/v3/router/chat/completions \
  -H "Authorization: Bearer $TOQAN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "openai/gpt-5.4-mini",
    "messages": [{ "role": "user", "content": "Generate a product description" }],
    "fallbacks": [
      { "model": "openai/gpt-5.6-sol" },
      { "model": "azure/gpt-5.6-sol" }
    ]
  }'
```

```typescript TypeScript theme={"theme":{"light":"github-light","dark":"github-dark"}}
import OpenAI from "openai";

const client = new OpenAI({
  apiKey: process.env.TOQAN_API_KEY,
  baseURL: "https://router.toqan.ai/eu/v3/router",
});

const response = await client.responses.create({
  model: "openai/gpt-5.4-mini",
  input: "Generate a product description",
  fallbacks: [{ model: "openai/gpt-5.6-sol" }, { model: "azure/gpt-5.6-sol" }],
});

console.log(response.output_text);
```

```python Python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from openai import OpenAI
import os

client = OpenAI(
    api_key=os.environ.get("TOQAN_API_KEY"),
    base_url="https://router.toqan.ai/eu/v3/router",
)

response = client.responses.create(
    model="openai/gpt-5.4-mini",
    input="Generate a product description",
    extra_body={
        "fallbacks": [
            {"model": "openai/gpt-5.6-sol"},
            {"model": "azure/gpt-5.6-sol"}
        ]
    }
)

print(response.output_text)
```

```typescript TypeScript (Chat Completions) theme={"theme":{"light":"github-light","dark":"github-dark"}}
import OpenAI from "openai";

const client = new OpenAI({
  apiKey: process.env.TOQAN_API_KEY,
  baseURL: "https://router.toqan.ai/eu/v3/router",
});

const response = await client.chat.completions.create({
  model: "openai/gpt-5.4-mini",
  messages: [{ role: "user", content: "Generate a product description" }],
  fallbacks: [{ model: "openai/gpt-5.6-sol" }, { model: "azure/gpt-5.6-sol" }],
});
```

```python Python (Chat Completions) theme={"theme":{"light":"github-light","dark":"github-dark"}}
from openai import OpenAI
import os

client = OpenAI(
    api_key=os.environ.get("TOQAN_API_KEY"),
    base_url="https://router.toqan.ai/eu/v3/router",
)

response = client.chat.completions.create(
    model="openai/gpt-5.4-mini",
    messages=[{"role": "user", "content": "Generate a product description"}],
    extra_body={
        "fallbacks": [
            {"model": "openai/gpt-5.6-sol"},
            {"model": "azure/gpt-5.6-sol"}
        ]
    }
)
```

### Limitações

* **Consistência das respostas**: modelos diferentes podem retornar estilos de saída variados.
* **Suporte a parâmetros**: nem todos os provedores aceitam parâmetros idênticos.
* **Impacto nos custos**: solicitações com falha ainda podem gerar cobranças do provedor principal.
* **Impacto na latência**: tentativas sequenciais aumentam o tempo de processamento.
* **Dependências de provedores**: exige chaves de API para todos os provedores de fallback.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.