FiscalAPI
Referência

Rate Limiting

Limites de requisições por plano e como lidar com throttling.

Toda conta possui limites de requisições baseados no plano da assinatura. O rate limiting protege a infraestrutura e garante disponibilidade para todos os usuários.

O limite é por conta, não por chave: se você usa várias API Keys, as requisições de todas elas somam no mesmo limite por minuto.

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-simples-nacional
  • 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.

Planos e preços

Esta pagina foi util?

On this page