Rate Limiting
Limites de requisições por plano e como lidar com throttling.
Toda API Key possui limites de requisições baseados no plano da assinatura. O rate limiting protege a infraestrutura e garante disponibilidade para todos os usuários.
Limites por plano
| Plano | Requisições | Período |
|---|---|---|
| Lite | 5 | por minuto |
| Starter | 20 | por minuto |
| Pro | 60 | por minuto |
| Enterprise | 120 | por minuto |
Endpoints com rate limiting
Os seguintes endpoints estão sujeitos ao rate limiting:
GET /api/consultarGET /api/consultar-cnpjGET /api/consultar-ie-todosGET /api/perfil-produtorGET /api/consultar-cndGET /api/consultar-cnd-todos
Toda requisição conta para o rate limit, inclusive quando a resposta vem do cache. A vantagem do cache é a latência (resposta em milissegundos, sem ida ao portal de origem).
Resposta ao exceder o limite
Quando o limite é excedido, a API retorna HTTP 429 Too Many Requests com o header Retry-After indicando quantos segundos aguardar antes da próxima requisição.
{
"type": "urn:fiscalapi:error:rate_limit_exceeded",
"title": "RATE_LIMIT_EXCEEDED",
"status": 429,
"detail": "Limite de requisicoes excedido. Tente novamente em 45 segundos."
}Headers de rate limit
As respostas dos endpoints listados acima incluem headers informativos sobre o estado do seu rate limit — tanto quando a requisição passa quanto no 429:
| Header | Descrição |
|---|---|
X-RateLimit-Limit | Número máximo de requisições permitidas por minuto |
X-RateLimit-Remaining | Número de requisições restantes na janela atual |
X-RateLimit-Reset | Timestamp Unix de quando a janela será reiniciada |
Retry-After | Segundos para aguardar (somente em respostas 429) |
Boas práticas
- Implemente backoff exponencial ao receber respostas 429 — comece com o valor do
Retry-Aftere dobre o tempo a cada tentativa - Respeite o header
Retry-Afterem vez de usar um valor fixo de espera - Use cache local para evitar chamadas duplicadas e reduzir o consumo da API
- Considere fazer upgrade de plano se você atingir o limite com frequência
- Monitore seu uso pelo Dashboard para antecipar necessidades de escala
Exemplo de retry com backoff
async function fetchWithRetry(url, headers, maxRetries = 3) {
for (let attempt = 0; attempt < maxRetries; attempt++) {
const response = await fetch(url, { headers });
if (response.status !== 429) {
return response;
}
const retryAfter = parseInt(response.headers.get("Retry-After") || "60");
const backoff = retryAfter * Math.pow(2, attempt);
console.log(`Rate limited. Aguardando ${backoff}s antes de tentar novamente...`);
await new Promise((r) => setTimeout(r, backoff * 1000));
}
throw new Error("Limite de tentativas excedido");
}import requests
import time
def fetch_with_retry(url: str, headers: dict, max_retries: int = 3):
for attempt in range(max_retries):
response = requests.get(url, headers=headers)
if response.status_code != 429:
return response
retry_after = int(response.headers.get("Retry-After", 60))
backoff = retry_after * (2 ** attempt)
print(f"Rate limited. Aguardando {backoff}s antes de tentar novamente...")
time.sleep(backoff)
raise Exception("Limite de tentativas excedido")Não faça polling agressivo após receber um 429. Respeite sempre o tempo indicado no Retry-After para evitar bloqueios mais longos.
Esta pagina foi util?