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

# Limites de requisição

> 120 por minuto no geral, 10 por hora em saque. E como não bater neles.

## Os limites

| Escopo | Limite | Janela |
| - | - | - |
| Todas as rotas `/v1/*` | 120 requisições | 60 segundos |
| `POST /v1/payouts` | 10 saques | 1 hora, por chave |
| `POST /v1/payouts` com `turbo` | 5 saques | 1 hora, por chave, dentro do limite acima |

O limite geral é somado entre todos os endpoints. Não existe cota separada por recurso.

## Headers

Toda resposta traz os headers padrão, então dá pra desacelerar antes de bater no teto:

| Header | Conteúdo |
| - | - |
| `RateLimit-Limit` | Total permitido na janela |
| `RateLimit-Remaining` | Quanto ainda resta |
| `RateLimit-Reset` | Segundos até a janela reiniciar |

## Quando estoura

```
HTTP/1.1 429 Too Many Requests
RateLimit-Limit: 120
RateLimit-Remaining: 0
RateLimit-Reset: 42

{ "error": "Rate limit exceeded. Check the RateLimit-* response headers for your account's limit and reset time." }
```

> [!WARNING]
>
> Não faça retry imediato de um `429`. Você continua bloqueado até a janela virar, e cada
> tentativa só empurra o problema pra frente.

Espere pelo menos o `RateLimit-Reset`, e use backoff exponencial com jitter:

```js theme={null}
async function comRetry(fn, maxTentativas = 5) {
  for (let i = 0; i <= maxTentativas; i++) {
    const res = await fn();
    if (res.status !== 429) return res;

    const reset = Number(res.headers.get("RateLimit-Reset")) || 2 ** i;
    const jitter = Math.random() * 1000;
    await new Promise((r) => setTimeout(r, reset * 1000 + jitter));
  }
  throw new Error("rate limit: máximo de tentativas excedido");
}
```

O jitter não é enfeite: sem ele, todos os seus workers acordam no mesmo instante e batem
no limite de novo, juntos.

## O jeito de não chegar perto

> [card] [Use webhook em vez de polling](https://docs.purin.cash/webhooks/visao-geral.md)
>
> É de longe a maior economia. Uma cobrança consultada a cada 3 segundos por 30 minutos
> são 600 requisições. O webhook resolve em uma.

> [card] Se precisar consultar, espace
>
> Intervalo de 5 segundos ou mais, e pare no primeiro status final (`paid`, `expired`,
> `refunded`).

> [card] Pagine com limite alto
>
> As listagens aceitam `limit` até 100. Buscar de 10 em 10 gasta 10 vezes mais
> requisição pelo mesmo resultado.

> [card] Cacheie o que não muda
>
> Catálogo de produto não precisa ser relido a cada request do seu usuário.

> [!TIP]
>
> Se você tem vários serviços integrando, dê uma chave para cada um. Assim o limite de
> saque de um job não é consumido pelo checkout, e você descobre rápido qual serviço está
> gastando requisição à toa.


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