Como revalidar o cadastro de clientes periodicamente
A IE estava ativa no dia do cadastro. Isso não diz nada sobre hoje. Para pegar a mudança antes da nota, revalide a carteira numa rotina: um job que reconsulta cada cliente, respeita o limite do plano e avisa quando a situação muda.
Com que frequência revalidar#
Não há prazo legal único para isso. Comece pelo risco de cada grupo e ajuste com o fiscal:
| Grupo | Sugestão |
|---|---|
| Clientes que compram todo mês | Mensal, e de novo antes de faturar se a última consulta passou do prazo que vocês definiram |
| Clientes parados há meses | Na volta, antes do primeiro pedido |
| Produtores rurais | Antes da safra e mensal para quem entrega com frequência |
| Cadastro alterado (endereço, razão social, IE) | Na hora da alteração |
A FiscalAPI não avisa quando uma IE muda de situação. Quem percebe a mudança é a sua rotina.
Quanto tempo o job leva#
O limite por minuto é da conta e depende do plano: 5, 20, 60 ou 120 requisições. O tempo mínimo é o número de clientes dividido pelo limite:
| Limite do plano | 2.000 clientes | 10.000 clientes |
|---|---|---|
| 20 por minuto | 1 h 40 min | 8 h 20 min |
| 60 por minuto | 34 min | 2 h 47 min |
| 120 por minuto | 17 min | 1 h 24 min |
Antes de agendar:
- Saldo. Cada cliente revalidado usa 1 consulta do plano. 2.000 clientes por mês são 2.000 consultas. Compare em planos e preços.
- Limite compartilhado. O ERP que consulta na mesma conta durante o dia disputa o mesmo limite. Rode o job à noite ou deixe folga.
- Cache. Toda requisição conta no limite, inclusive a que volta do cache (
cached: true). - Paralelismo. O job abaixo faz uma consulta por vez. Uma consulta que vai ao estado pode levar alguns segundos, então ele não chega a 60 ou 120 por minuto sozinho. Para chegar perto da tabela, divida a carteira entre alguns trabalhadores e mantenha o ritmo total dentro do limite.
O job em Python#
Reconsulta cada cliente na UF dele, no ritmo do plano. Compara com o que está gravado e chama alertar quando muda:
import os
import time
from datetime import datetime, timezone
import requests
API = "https://api.fiscalapi.com.br/api/consultar"
CHAVE = os.environ["FISCALAPI_KEY"] # nunca no código-fonte
LIMITE_POR_MINUTO = 20 # o do seu plano: 5, 20, 60 ou 120
INTERVALO = 60 / LIMITE_POR_MINUTO
class SaldoEsgotado(Exception):
def __init__(self, restantes: list):
super().__init__("saldo do plano esgotado")
self.restantes = restantes # retome por eles quando houver saldo
def so_digitos(texto: str) -> str:
return "".join(c for c in texto or "" if c.isdigit()).lstrip("0")
def situacao_atual(dados: dict, ie: str) -> tuple[str, str]:
for inscricao in dados["results"]:
if so_digitos(inscricao["inscricao_estadual"]) == so_digitos(ie):
return inscricao["situacao_ie"].strip(), inscricao["situacao_nfe"].strip()
return "NAO_ENCONTRADA", "" # a IE gravada não está mais neste CNPJ, nesta UF
def revalidar(clientes: list, salvar, alertar) -> list:
"""Devolve os clientes que ficaram para a próxima rodada."""
pendentes = []
for i, cliente in enumerate(clientes):
inicio = time.monotonic()
try:
resp = requests.get(
API,
headers={"X-API-Key": CHAVE},
params={"uf": cliente["uf"], "cnpj": cliente["cnpj"]},
timeout=95,
)
except requests.RequestException: # rede ou tempo esgotado
pendentes.append(cliente)
continue
if resp.status_code == 429: # passou do limite por minuto
time.sleep(int(resp.headers.get("Retry-After", "60")))
pendentes.append(cliente)
continue
if resp.status_code == 402: # saldo do plano esgotado: repetir não resolve
raise SaldoEsgotado(pendentes + clientes[i:])
if resp.status_code >= 500: # o estado ou a API não responderam
pendentes.append(cliente)
elif resp.ok:
dados = resp.json()
antes = (cliente["situacao_ie"], cliente["situacao_nfe"])
depois = situacao_atual(dados, cliente["ie"])
salvar(cliente["id"], *depois, dados["request_id"], datetime.now(timezone.utc))
if depois != antes:
alertar(cliente, antes, depois)
else: # 400 ou 403: corrija o cadastro ou a chave
alertar(cliente, None, f"HTTP {resp.status_code}")
time.sleep(max(0.0, INTERVALO - (time.monotonic() - inicio)))
return pendentes Como rodar:
- Agende com o cron, o agendador do seu ERP ou uma fila. Uma rodada por mês, à noite.
- Pendentes: rode
revalidar(pendentes, ...)de novo uma hora depois. O que sobrar vai para a rodada seguinte. - Produtor rural: troque
cnpjporcpf. São Paulo, por exemplo, não busca por CPF: lá, consulte pela IE (ie=). Veja qual IE usar quando o produtor tem várias.
Erros e limites#
| HTTP | No job |
|---|---|
| 429 | Espere o Retry-After e devolva o cliente para a fila |
| 500 a 504, ou erro de rede | O estado ou a API não responderam. Tente na próxima rodada |
| 402 | Saldo esgotado. O job para e devolve quem faltou. Avise quem cuida da conta |
| 400, 403 | Documento inválido ou chave errada. Corrija antes de repetir |
As respostas trazem X-RateLimit-Remaining, quantas requisições restam no minuto. Detalhes em rate limiting.
O que fazer com o alerta#
| Mudou para | Ação sugerida |
|---|---|
| Não habilitado | Bloqueie o faturamento automático e peça ao cliente que regularize |
| NAO_ENCONTRADA | A IE gravada não aparece mais para o CNPJ. Confirme a IE com o cliente |
| situacao_nfe diferente | Mudou a lista de documentos eletrônicos habilitados (por exemplo, saiu NFe). Revise antes da próxima nota |
| Voltou a Habilitado | Libere, com a data e o request_id da consulta |
O que cada situação significa está em situação cadastral da inscrição estadual.
Sem código: a planilha#
Para revisar a carteira sem programar, suba uma planilha de até 20.000 CPFs, CNPJs ou IEs na consulta de IE em massa e baixe o resultado com a situação de cada um. Linha com erro não é cobrada.
Perguntas frequentes#
A API tem rota de lote? Não. Pela API é uma chamada por documento, dentro do limite por minuto. Para lote sem código, use a planilha do painel.
Consulta que falha é cobrada? Não. Falha da FiscalAPI ou da fonte oficial não é cobrada.
Por que consultar pelo CNPJ e não pela IE? Pelo CNPJ, a resposta mostra se a IE gravada ainda pertence ao cliente. Pela IE, compare o campo cpf_cnpj da resposta com o documento do cliente.
Uso ERP com vários clientes. O limite é por cliente? O limite e o saldo são da conta. Numa conta só, os clientes do ERP somam. Com a chave de cada cliente, cada um tem o próprio plano. Veja ERPs e hubs de marketplace.
Fontes#
- Rate limiting, documentação da FiscalAPI
- Consultar IE por UF, documentação da FiscalAPI
- Planos e preços, FiscalAPI
Artigos relacionados#
Consulte dados fiscais via API
Consulte Inscrições Estaduais, CNPJs e Certidões Negativas via API REST. Dados direto da SEFAZ e Receita Federal. Planos a partir de R$ 19,99/mês.
Criar conta →