> ## Knowledge Base Index
> Fetch the complete knowledge base index at: https://help.squarecloud.app/sitemap.xml
> Use this file to discover available pages before exploring further.
> Pure-Markdown content can be obtained by appending a '.md' suffix to the content URLs listed in the sitemap (without the trailing slash).

# Rate limits da API do Discord (erro 429): como evitar

# Como lidar com ratelimits na API do Discord: O Guia Definitivo

Se você desenvolve bots para o Discord, mais cedo ou mais tarde sua aplicação receberá um código de status **HTTP 429 (Too Many Requests)**. O Discord impõe regras rígidas de tráfego para proteger sua infraestrutura contra abusos e ataques de negação de serviço. 

Para que seu bot opere com estabilidade máxima, você precisa entender a mecânica interna desses limites e blindar seu código com um sistema de filas e cache.

## 1. Anatomia dos Ratelimits do Discord

O Discord divide suas restrições em camadas bem definidas. Os limites são contados com base no token do seu bot e no IP de onde as requisições partem.

### O Limite Global (Global Rate Limit)
Por padrão, o Discord aplica um **limite global de 50 requisições por segundo** para cada token de bot. Se o seu bot tentar disparar 51 requisições em um único segundo (mesmo que para endpoints totalmente diferentes), a API bloqueará temporariamente todas as chamadas subsequentes.

### Limites por Rota e Buckets (Per-Route Limits)
Além do limite global, cada rota da API possui seu próprio "bucket" (balde) de créditos, geralmente atrelado a um identificador principal (como o ID de um servidor ou de um canal). 
*   **Rotas comuns:** Enviar mensagens em um canal específico possui um limite diferente de editar o apelido de um usuário.
*   **A rota crítica de Criação/Edição de Canais:** Modificar ou criar canais em um servidor é uma das operações mais monitoradas pelo Discord para evitar ataques de *raid*. Modificações no nome ou tópico de um canal, por exemplo, são estritamente limitadas a **2 alterações a cada 10 minutos por canal**. Abusar dessa rota gera bloqueios severos instantaneamente.

### Os Cabeçalhos HTTP de Controle
Sempre que seu bot faz uma requisição REST, o Discord responde com cabeçalhos que revelam a saúde do seu bucket atual. Seu código deve ler e respeitar esses dados:

> *   `X-RateLimit-Limit`: O número máximo de requisições que você pode fazer neste bucket.
> *   `X-RateLimit-Remaining`: Quantas requisições você ainda pode fazer antes do bloqueio.
> *   `X-RateLimit-Reset-After`: O tempo (em segundos) que você precisa esperar para o bucket resetar.
> *   `X-RateLimit-Bucket`: A string identificadora única daquele bucket específico.

## 2. A Solução Arquitetural: Sistema de Filas

A forma mais eficiente de evitar atingir o limite do Discord é implementar um **Sistema de Filas Assíncronas**. Em vez de permitir que seus comandos executem requisições REST diretamente para a API do Discord à medida que as interações ocorrem, você joga essas ações em uma fila controlada por um trabalhador (*worker*).

O worker consome a fila sequencialmente ou em lotes, verificando os cabeçalhos de ratelimit antes de realizar o próximo disparo. Se o indicador `X-RateLimit-Remaining` chegar a zero, a fila congela voluntariamente durante os segundos informados em `X-RateLimit-Reset-After`.

### Exemplo Conceitual de Fila Otimizada (Python / Asyncio)

Aqui está um exemplo básico de como estruturar um despachante de requisições que respeita os tempos de espera impostos pela API:

```python
import asyncio
import time

class DiscordRequestQueue:
    def __init__(self):
        self.queue = asyncio.Queue()
        self.is_frozen = False
        self.resume_time = 0

    async def add_request(self, action_coroutine):
        """Adiciona uma ação de API à fila"""
        await self.queue.put(action_coroutine)

    async def start_worker(self):
        """Worker que processa e monitora os limites continuamente"""
        while True:
            # Se a fila estiver congelada por ratelimit, aguarda o reset
            if self.is_frozen:
                now = time.time()
                if now < self.resume_time:
                    await asyncio.sleep(self.resume_time - now)
                self.is_frozen = False

            # Pega a próxima requisição da fila
            action = await self.queue.get()
            
            try:
                # Executa a chamada HTTP para o Discord
                response = await action()
                
                # Simulação da leitura dos cabeçalhos do Discord
                remaining = int(response.headers.get("X-RateLimit-Remaining", 1))
                reset_after = float(response.headers.get("X-RateLimit-Reset-After", 0))

                if remaining == 0:
                    # Congela o processador baseado na resposta do Discord
                    self.is_frozen = True
                    self.resume_time = time.time() + reset_after

            except Exception as e:
                # Trata erros 429 inesperados com Recuo Exponencial (Backoff)
                print(f"Erro na requisição: {e}")
            
            finally:
                self.queue.task_done()
```

## 3. Outras Boas Práticas Cruciais

Além de gerenciar suas requisições REST com filas, adote os seguintes hábitos de desenvolvimento para reduzir a carga contra a API:

### 1. Cache Agressivo de Dados
Nunca consulte a API do Discord para obter informações estáticas ou que mudam pouco. 
*   **Dados de Servidores:** Mantenha os nomes dos canais, papéis (*roles*) e permissões salvos na memória local do seu bot (ou em uma instância externa do Redis). 
*   **Biblioteca Nativa:** Se você usa wrappers modernos como `discord.py` ou `discord.js`, eles já possuem sistemas de cache interno automáticos. Evite contorná-los usando métodos como `fetch_channel()` (que faz uma chamada REST direta) quando puder usar `get_channel()` (que busca do cache local).

### 2. Dê Preferência ao Gateway e Webhooks
*   **Gateway (WebSockets):** Use eventos do Gateway para receber atualizações em tempo real em vez de fazer "polling" (ficar perguntando para a API se algo mudou).
*   **Webhooks para Envio Massivo:** Se o seu bot precisa disparar logs de ações, anúncios em massa ou feeds de notícias em canais, utilize **Webhooks**. Os Webhooks possuem limites de requisições isolados da sua aplicação principal (geralmente 30 requisições a cada 5 segundos por webhook), poupando o limite de 50/s global do token do seu bot.

### 3. Implemente Exponential Backoff (Recuo Exponencial)
Se por algum desalinhamento de concorrência seu bot receber um erro HTTP 429 real, sua rotina de tentativas (*retry*) deve recuar estrategicamente. Multiplique o tempo de espera a cada falha consecutiva. Se você bombardear a API imediatamente após receber um 429, o Discord estenderá a punição ou banirá temporariamente o IP da sua VPS/Hospedagem por comportamento abusivo.
