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

# Limites de uso

> Como a API limita taxa e concorrência, e o que fazer ao receber 429.

A API aplica três limites independentes. Cada um responde `429`, com um `code` diferente, para você saber o que ajustar.

| Limite                  | Escopo                                     | Código no 429                 |
| ----------------------- | ------------------------------------------ | ----------------------------- |
| Taxa de requisições     | Por conta, separado por classe de operação | `rate_limit_exceeded`         |
| Requisições simultâneas | Por conta                                  | `concurrency_limit_exceeded`  |
| Falhas de autenticação  | Por IP de origem                           | `auth_failure_limit_exceeded` |

## Taxa de requisições

O limite de taxa é por conta e vale para todas as chaves dela somadas. Trocar de chave não aumenta o teto.

As operações são contadas em duas classes separadas, cada uma com seu próprio orçamento:

| Classe                | Operações                                                                         |
| --------------------- | --------------------------------------------------------------------------------- |
| Escrita de validações | Os três `POST /validations/*`                                                     |
| Leitura               | `GET /validations`, `GET /validations/{id}` e todos os endpoints de Chaves de API |

O orçamento funciona como um balde: ele acumula folga quando você fica abaixo do ritmo, o que permite picos curtos, e se recompõe continuamente. Estourar a taxa de leitura não afeta o seu orçamento de criação de validações.

Para conhecer o teto da sua conta ou pedir um aumento, fale com o suporte.

## Requisições simultâneas

Independente da taxa, há um teto de requisições em voo ao mesmo tempo por conta. Uma integração que dispara centenas de validações em paralelo pode bater nele mesmo respeitando a taxa. A saída é limitar a concorrência do seu lado, com uma fila ou um pool.

## Falhas de autenticação

Requisições que terminam em `401` são contadas por IP de origem. Depois de várias seguidas, o IP recebe `429` com `auth_failure_limit_exceeded` por um tempo.

Só o que falha conta. Tráfego com chave válida nunca entra nessa contagem, então volume legítimo vindo de um IP compartilhado não é penalizado.

## Cabeçalhos da resposta

Os cabeçalhos aparecem **na resposta `429`**, não nas bem-sucedidas.

| Cabeçalho             | Descrição                                                      |
| --------------------- | -------------------------------------------------------------- |
| `Retry-After`         | Segundos a esperar antes de tentar de novo. Vem em todo `429`. |
| `RateLimit-Limit`     | Teto da classe para a sua conta.                               |
| `RateLimit-Remaining` | Quanto resta na janela atual.                                  |
| `RateLimit-Reset`     | Segundos até o orçamento se recompor por completo.             |

Os três cabeçalhos `RateLimit-*` só vêm no `429` de taxa. O `429` de concorrência e o de falhas de autenticação trazem apenas `Retry-After`, porque nenhum dos dois descreve um orçamento por janela.

## Como tratar um 429

1. Leia `Retry-After` e espere esse tempo. É a única fonte confiável, em qualquer um dos três casos.
2. Repita com espera exponencial e um pouco de aleatoriedade, para não sincronizar todas as retentativas no mesmo instante.
3. Se for um `POST` de validação, reenvie com o **mesmo** `Idempotency-Key`. Uma requisição barrada no `429` nunca foi cobrada, e a chave garante que uma eventual retentativa duplicada também não seja.

```javascript theme={null}
async function comRetentativa(requisicao, tentativas = 5) {
  for (let tentativa = 0; tentativa < tentativas; tentativa++) {
    const resposta = await requisicao();
    if (resposta.status !== 429) return resposta;

    const espera = Number(resposta.headers.get("Retry-After") ?? 1);
    const jitter = Math.random();
    await new Promise((r) => setTimeout(r, (espera + jitter) * 1000));
  }
  throw new Error("limite de requisições persistente");
}
```

<Note>
  Saldo insuficiente responde `402` com `insufficient_balance`, não `429`. Repetir não resolve: recarregue a conta no [painel](https://id.zapsign.com.br/app).
</Note>
