FiscalAPI
Referência

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

PlanoRequisiçõesPeríodo
Lite5por minuto
Starter20por minuto
Pro60por minuto
Enterprise120por minuto

Endpoints com rate limiting

Os seguintes endpoints estão sujeitos ao rate limiting:

  • GET /api/consultar
  • GET /api/consultar-cnpj
  • GET /api/consultar-ie-todos
  • GET /api/perfil-produtor
  • GET /api/consultar-cnd
  • GET /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:

HeaderDescrição
X-RateLimit-LimitNúmero máximo de requisições permitidas por minuto
X-RateLimit-RemainingNúmero de requisições restantes na janela atual
X-RateLimit-ResetTimestamp Unix de quando a janela será reiniciada
Retry-AfterSegundos para aguardar (somente em respostas 429)

Boas práticas

  • Implemente backoff exponencial ao receber respostas 429 — comece com o valor do Retry-After e dobre o tempo a cada tentativa
  • Respeite o header Retry-After em 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?

On this page