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

# Limites de taxa

> Como funciona o rate limiting da API pública da VMArea, os cabeçalhos de resposta e como lidar com respostas 429.

A API pública da VMArea usa dois buckets encadeados, ambos com Redis como backend — os limites são compartilhados entre todas as instâncias da API.

## Limites atuais

| Bucket                   | Limite                                           | Chaveado por       | Aplica-se a                                                                                    |
| ------------------------ | ------------------------------------------------ | ------------------ | ---------------------------------------------------------------------------------------------- |
| API pública (por token)  | **600 requisições / minuto** (10 RPS sustentado) | ID do token de API | Toda requisição `/api/public/v1/*` após autenticação bem-sucedida com `x-api-key`              |
| Fallback global (por IP) | **100 requisições / minuto**                     | Endereço IP        | Todo o tráfego — principalmente para conter abusos em rotas não autenticadas (login, cadastro) |

O bucket por token garante que clientes pesados e clientes atrás de NAT compartilhado não penalizem uns aos outros. Combine com o cabeçalho `Idempotency-Key` para que retentativas seguras não consumam cota extra — veja [Idempotência](/pt/idempotency).

## Resposta 429

Quando você excede algum dos limites, a API retorna HTTP `429 Too Many Requests` com o envelope padrão:

```json theme={null}
{
  "success": false,
  "error": "Rate limit exceeded for this API token: 600 requests per minute. Retry after 42."
}
```

A string `error` identifica qual bucket foi atingido (por token ou fallback global por IP).

## Cabeçalhos

Toda resposta inclui os cabeçalhos padrão de rate limit; `Retry-After` é adicionado nas respostas `429`.

| Cabeçalho               | Descrição                                                           |
| ----------------------- | ------------------------------------------------------------------- |
| `X-RateLimit-Limit`     | Número máximo de requisições permitidas na janela atual.            |
| `X-RateLimit-Remaining` | Requisições restantes na janela atual.                              |
| `X-RateLimit-Reset`     | Segundos até a janela reiniciar.                                    |
| `Retry-After`           | Segundos para aguardar antes de tentar novamente (apenas em `429`). |

## Tratando 429 no seu cliente

Leia `Retry-After` para o tempo mínimo de espera, depois aplique backoff exponencial com jitter começando em 1 segundo:

```js theme={null}
async function requestWithRetry(url, options, maxAttempts = 5) {
  for (let attempt = 1; attempt <= maxAttempts; attempt++) {
    const res = await fetch(url, options);
    if (res.status !== 429) return res;

    const retryAfter = parseInt(res.headers.get("Retry-After") ?? "1", 10);
    const base = Math.max(retryAfter, 1) * 1000;
    const jitter = Math.random() * 1000;
    const delay = base * Math.pow(2, attempt - 1) + jitter;
    await new Promise((r) => setTimeout(r, delay));
  }
  throw new Error("Rate limit: max retry attempts exceeded");
}
```

## Boas práticas

* **Use `Idempotency-Key` para escritas.** Retentativas seguras não consomem cota extra nem criam recursos duplicados.
* **Agrupe leituras onde possível.** Endpoints de listagem paginados são mais eficientes do que múltiplos GETs individuais.
* **Faça cache dos dados do catálogo.** Planos, regiões e templates de SO mudam raramente — armazene-os localmente em vez de buscar repetidamente.
* **Use webhooks para mudanças de estado.** Assinar `vm.started`, `vm.stopped` etc. evita polling em loop em `GET /vms/:id`.
* **Precisa de limites maiores?** Entre em contato com o suporte — 10 RPS cobre praticamente todas as integrações, mas podemos aumentar os limites por token sob solicitação.
