Referência
API EvoDATA
Acesso em JSON ao cadastro público de CNPJ da Receita Federal: busca por 27 filtros combináveis, ficha completa com quadro societário e tabelas de referência.
Começando
Todos os recursos vivem sob um único host, em uma versão fixada no caminho. Não há SDK: qualquer cliente HTTP serve.
| URL base | https://evodata.app/api/v1 |
|---|---|
| Protocolo | HTTPS obrigatório. Chamadas em HTTP recebem redirecionamento permanente. |
| Formato | application/json, codificado em UTF-8. Acentos saem escapados como \uXXXX, que é JSON válido. |
| Métodos | Somente GET. A API é de leitura. |
| Versão | v1. Campos novos podem ser acrescentados sem aviso; remoções e mudanças de tipo abrem uma versão nova. |
Primeira chamada
curl "https://evodata.app/api/v1/empresas?uf=DF&situacao=02&por_pagina=1"
Autenticação
Existem dois regimes, conforme a sensibilidade do dado:
| Recursos | Acesso |
|---|---|
/empresas, /referencias |
Público. Nenhuma credencial. É cadastro aberto da Receita Federal. |
/pessoas |
Chave obrigatória + plano pago. São dados pessoais. |
Obtendo a chave
Emita em Chaves de API, no painel. A chave em claro aparece uma única vez, no momento da criação: o sistema guarda apenas um SHA-256, então nem o suporte consegue recuperá-la. Perdeu, revogue e emita outra. Cada conta pode manter até 5 chaves ativas — use uma por integração, para poder revogar uma sem derrubar as demais.
Enviando a chave
curl -H "Authorization: Bearer evd_SUA_CHAVE" \
"https://evodata.app/api/v1/pessoas?nome=MARIA&uf=SP"
O cabeçalho X-API-Key é aceito como alternativa. A chave
não é lida da query string, de propósito: parâmetro de URL vaza
em log de servidor, histórico de navegador e cabeçalho Referer.
403 plano_sem_api
— a permissão é do plano, não do saldo de créditos, então zerar ou acumular
créditos não muda nada. A busca pela interface web segue disponível a todos.
Recusas possíveis
| HTTP | erro | Significado |
|---|---|---|
401 | credencial_ausente | Nenhuma chave foi enviada. |
401 | credencial_invalida | Chave inexistente, revogada ou expirada. Os três casos respondem igual, para não confirmar que uma chave já existiu. |
403 | plano_sem_api | Chave válida, conta sem direito. Trocar a chave não resolve; mudar de plano sim. |
Limites de uso
O custo real de cada chamada é uma consulta em um PostgreSQL de ~118 GB compartilhado com outro sistema em produção. O limite protege o banco, não o servidor de aplicação.
| Situação | Limite | Chave |
|---|---|---|
| Anônimo — recursos públicos | 20 req/min | Endereço IP |
| Autenticado por chave | 120 req/min | ID da conta |
Cabeçalhos em toda resposta
X-RateLimit-Limit | Teto da janela corrente. |
|---|---|
X-RateLimit-Remaining | Quanto resta antes do bloqueio. |
Retry-After | Segundos até liberar. Presente apenas no 429. |
Convenções
Listas
Parâmetros marcados como lista aceitam duas formas equivalentes.
Valores repetidos são deduplicados e a ordem é irrelevante.
?uf=SP,RJ,MG # separados por vírgula
?uf[]=SP&uf[]=RJ # repetindo a chave
Valores fora do domínio
Filtros com domínio fechado — uf, situacao,
porte, size_class, buscar_em,
ordenar — descartam em silêncio o que não reconhecem, em vez
de devolver erro. Uma UF digitada errado simplesmente não filtra. Se a lista
inteira for inválida, o padrão do campo volta a valer.
Booleanos
Campos boolean ativam com 1, true,
on ou yes; qualquer outra coisa desativa.
Os campos marcados boolean³ são ternários: aceitam
1/true/S para sim,
0/false/N para não, e tratam
a ausência como “indiferente”, que é diferente de “não”.
Números e datas
Valores monetários aceitam ponto ou vírgula decimal: 1500.50
e 1.500,50 chegam ao mesmo lugar. Datas usam
AAAA-MM-DD e passam por validação de calendário —
2025-02-30 é descartada silenciosamente.
Buscar empresas
GET https://evodata.app/api/v1/empresas
Busca paginada sobre estabelecimentos. Ao menos um filtro é
obrigatório — uma consulta irrestrita sobre dezenas de milhões
de linhas não é atendida e devolve 422.
situacao tem padrão 02 (ativa) e não conta
como filtro para essa exigência. Chamar /empresas?situacao=02
ainda resulta em filtros_ausentes.
Parâmetros
Identificação
| Parâmetro | Tipo | Descrição | Exemplo |
|---|---|---|---|
q |
string | Termo livre sobre razão social ou nome fantasia, conforme buscar_em. Se o valor contiver apenas dígitos (com ou sem pontuação de CNPJ) e tiver 8 ou mais deles, é reinterpretado como cnpj e o termo é descartado. |
padaria |
buscar_em |
enum | Onde q incide: razao, fantasia ou ambos. Valor desconhecido cai no padrão. |
ambos |
cnpj |
string | CNPJ completo ou raiz. Pontuação é ignorada. Tem precedência sobre q. |
62.170.939/0001-51 |
Localização
| Parâmetro | Tipo | Descrição | Exemplo |
|---|---|---|---|
uf |
lista | Siglas de estado. Valores fora da tabela oficial são descartados em silêncio. | SP,RJ |
municipio |
lista | Códigos de município da Receita — não o nome. Obtenha em /referencias/municipios/{uf}. |
7107 |
bairro |
string | Nome do bairro, casamento por prefixo. | Centro |
cep |
string | Prefixo de CEP. Só dígitos são considerados. | 01310 |
Atividade econômica
| Parâmetro | Tipo | Descrição | Exemplo |
|---|---|---|---|
cnae |
lista | Códigos CNAE de 7 dígitos. Busque o código em /referencias/cnae. |
4721102 |
cnae_secundario |
boolean | Quando verdadeiro, casa também no CNAE secundário do estabelecimento, não só no principal. | 1 |
natureza |
lista | Códigos de natureza jurídica. | 2135 |
Situação e porte
| Parâmetro | Tipo | Descrição | Exemplo |
|---|---|---|---|
situacao |
lista | Códigos de situação cadastral. Padrão: 02 (ativa) — para incluir baixadas é preciso informar explicitamente. |
02,08 |
matriz_filial |
enum | 1 somente matrizes, 2 somente filiais. Ausente traz ambas. |
1 |
porte |
lista | Códigos de porte declarado. | 01,03 |
abertura_de |
data | Data de abertura mínima, em AAAA-MM-DD. Data inexistente no calendário é descartada. |
2024-01-01 |
abertura_ate |
data | Data de abertura máxima, em AAAA-MM-DD. |
2025-12-31 |
capital_min |
número | Capital social mínimo. Aceita 1500.50 e 1.500,50. |
10000 |
capital_max |
número | Capital social máximo. | 5000000 |
mei |
boolean³ | 1 só MEI, 0 exclui MEI, ausente é indiferente. |
1 |
simples |
boolean³ | 1 só optantes do Simples, 0 exclui, ausente é indiferente. |
1 |
Presença de contato
| Parâmetro | Tipo | Descrição | Exemplo |
|---|---|---|---|
com_email |
boolean | Somente estabelecimentos com e-mail preenchido. | 1 |
com_telefone |
boolean | Somente com telefone preenchido. | 1 |
com_celular |
boolean | Somente com telefone identificado como celular. | 1 |
com_geo |
boolean | Somente com latitude e longitude resolvidas. | 1 |
Enriquecimento
| Parâmetro | Tipo | Descrição | Exemplo |
|---|---|---|---|
funcionarios_min |
inteiro | Número mínimo estimado de funcionários. Vem de base de enriquecimento, não da Receita — nem todo estabelecimento tem. | 10 |
funcionarios_max |
inteiro | Número máximo estimado de funcionários. | 500 |
size_class |
lista | Classe de tamanho estimada: micro, pequena, media, grande. |
media,grande |
rating_min |
número | Avaliação mínima no Google Places, de 0 a 5. | 4.0 |
Paginação e ordenação
| Parâmetro | Tipo | Descrição | Exemplo |
|---|---|---|---|
ordenar |
enum | Ordenação desejada. Pode ser recusada — veja Avisos. | abertura_desc |
pagina |
inteiro | Página, começando em 1. Valores menores que 1 viram 1. | 2 |
por_pagina |
inteiro | Itens por página. Padrão 25, teto 100. | 50 |
Resposta
{
"dados": [ { /* objeto Empresa, ver abaixo */ } ],
"paginacao": {
"pagina": 1,
"por_pagina": 25,
"total": 482163,
"total_exato": false,
"tem_proxima": true
},
"avisos": []
}
total_exato: false muda o significado de total.
Contar exatamente dezenas de milhões de linhas leva minutos, então acima de
5.000 resultados o número é a estimativa do planejador do PostgreSQL,
não uma contagem. Trate-o como ordem de grandeza: não use para paginação
exata nem para relatórios. Abaixo desse limiar a contagem é real e o campo
vem true.
avisos é um array de strings. Hoje ele só recebe uma mensagem,
quando a ordenação pedida em ordenar foi descartada: classificar
um conjunto muito grande faz o planejador trocar o índice correto por uma
varredura ordenada da tabela inteira. Nesse caso os resultados voltam na ordem
natural do índice e a requisição segue sendo 200.
Objeto Empresa
| Campo | Tipo | Descrição |
|---|---|---|
cnpj |
string | 14 dígitos, sem pontuação. |
cnpj_formatado |
string | Com máscara: 00.000.000/0000-00. |
razao_social |
string | Razão social registrada. |
nome_fantasia |
string|null | Nome fantasia, quando declarado. |
nome_exibicao |
string | Fantasia quando existe, senão razão social. Pronto para exibir. |
situacao |
string | Rótulo legível: Ativa, Baixada, Suspensa, Inapta, Nula. |
situacao_codigo |
string | Código de dois dígitos correspondente. |
ativa |
boolean | Atalho para situacao_codigo === "02". |
tipo_unidade |
string | Matriz ou Filial. |
cnae_codigo |
string | CNAE principal, 7 dígitos. |
cnae |
string | Descrição do CNAE principal. |
uf |
string | Sigla do estado. |
municipio |
string | Nome do município. |
bairro |
string|null | Bairro. |
cep |
string|null | CEP com máscara. |
endereco |
string | Logradouro, número e complemento concatenados. |
telefone |
string|null | Telefone principal com DDD, formatado. |
email |
string|null | E-mail declarado à Receita. |
porte |
string | Porte declarado, legível. |
natureza |
string | Natureza jurídica, legível. |
capital_social |
number | Capital social em reais. |
abertura |
string|null | Data de abertura em AAAA-MM-DD. |
funcionarios |
integer|null | Estimativa de funcionários. Enriquecimento. |
porte_estimado |
string|null | Classe de tamanho estimada. Enriquecimento. |
faturamento_estimado |
number|null | Faturamento estimado. Enriquecimento. |
confianca_estimativa |
string|null | Confiança das estimativas acima. Enriquecimento. |
latitude |
number|null | Latitude. Google Places. |
longitude |
number|null | Longitude. Google Places. |
avaliacao |
number|null | Nota média, 0 a 5. Google Places. |
avaliacoes_total |
integer|null | Quantidade de avaliações. Google Places. |
site |
string|null | Site oficial. Google Places. |
null
como caso comum, não como exceção.
Exemplo
curl -G "https://evodata.app/api/v1/empresas" \
--data-urlencode "uf=SP,RJ" \
--data-urlencode "cnae=4721102" \
--data-urlencode "abertura_de=2024-01-01" \
--data-urlencode "com_email=1" \
--data-urlencode "ordenar=abertura_desc" \
--data-urlencode "por_pagina=50"
Ficha de empresa
GET https://evodata.app/api/v1/empresas/{cnpj}
Retorna um único estabelecimento com todo o detalhamento. O CNPJ pode vir
com ou sem máscara e é validado pelos dígitos verificadores antes de
qualquer consulta — um CNPJ malformado devolve 422 sem tocar
o banco.
curl "https://evodata.app/api/v1/empresas/62.170.939/0001-51"
curl "https://evodata.app/api/v1/empresas/62170939000151" # equivalente
A resposta é { "dados": { … } } com todos os campos do objeto
Empresa, mais os seguintes:
| Campo | Tipo | Descrição |
|---|---|---|
cnpj_basico |
string | Raiz de 8 dígitos, compartilhada por todas as unidades. |
situacao_desde |
string|null | Data da situação cadastral atual. |
situacao_especial |
string|null | Situação especial, quando houver. |
telefone_secundario |
string|null | Segundo telefone declarado. |
cnaes_secundarios |
array | Objetos {codigo, descricao} das atividades secundárias. |
simples |
object|null | Adesão ao Simples e ao MEI — ver abaixo. |
socios |
array | Quadro societário — ver abaixo. |
unidades |
array | Matriz e filiais que compartilham a raiz — ver abaixo. |
Objeto sócio
{
"nome": "FULANO DE TAL",
"documento": "***040852**", # PF sempre parcial
"tipo": "Pessoa física",
"eh_pessoa_juridica": false,
"qualificacao": "Sócio-Administrador",
"entrada": "2019-03-12",
"faixa_etaria": "41 a 50 anos",
"representante": null
}
documento de sócio pessoa física vem parcial, no formato
***XXXXXX** — seis dígitos centrais, sem pontuação. É assim que
a própria Receita Federal publica o quadro societário; o CPF completo não
existe na origem e não há como recompô-lo. Sócio pessoa jurídica traz o CNPJ
inteiro e formatado.
Objeto simples
{
"optante": true,
"desde": "2020-01-01",
"excluido_em": null,
"mei": true,
"mei_desde": "2020-01-01",
"mei_excluido_em": null
}
Objeto unidade
Lista com todas as unidades que compartilham a mesma raiz de CNPJ, incluindo a própria consultada. Útil para navegar de uma filial à matriz.
{
"cnpj": "62170939000151",
"cnpj_formatado": "62.170.939/0001-51",
"nome_fantasia": null,
"tipo": "Matriz",
"eh_matriz": true,
"situacao": "Ativa",
"ativa": true,
"uf": "DF",
"municipio": "BRASILIA",
"cnae": "Cabeleireiros, manicure e pedicure",
"abertura": "2025-08-11"
}
Buscar pessoas
GET https://evodata.app/api/v1/pessoas
chave + plano pago
Busca sobre 233 milhões de pessoas físicas. Ao menos um filtro é obrigatório.
Diferente da busca de empresas, aqui não há paginação: o
parâmetro por_pagina define quantas linhas voltam, e
tem_mais indica se existem outras. Percorrer profundamente um
conjunto de centenas de milhões de linhas não é uma operação que esta base
sustente — o caminho é refinar até o recorte caber.
Parâmetros
| Parâmetro | Tipo | Descrição | Exemplo |
|---|---|---|---|
nome |
string | Início do nome. A base grava em maiúsculas e sem acento; a conversão é feita para você. | MARIA DA SILVA |
nome_mae |
string | Início do nome da mãe. Combinado com nome, é o par mais eficaz para desambiguar homônimos. |
ANA |
cpf |
string | CPF completo, 11 dígitos. Pontuação ignorada. Parcial é recusado — ver abaixo. | 000.000.001-91 |
rg |
string | Número de RG, igualdade exata. | 123456789 |
titulo_eleitor |
inteiro | Título de eleitor completo. | 123456789012 |
pis |
inteiro | PIS/NIT completo. | 12345678901 |
sexo |
enum | M ou F. |
F |
estado_civil |
enum | S, C, D, V ou O. |
C |
nasc_de |
data | Nascimento mínimo, AAAA-MM-DD. |
1980-01-01 |
nasc_ate |
data | Nascimento máximo, AAAA-MM-DD. |
1990-12-31 |
cbo |
string | Código de ocupação, casa por prefixo. | 2521 |
uf |
enum | Estado de um endereço conhecido. | SP |
cidade |
string | Cidade, por prefixo e sem acento. | SAO PAULO |
bairro |
string | Bairro, por prefixo. | CENTRO |
logradouro |
string | Nome do logradouro, sem “Rua” ou “Av.”. | PAULISTA |
cep |
string | CEP completo, 8 dígitos. | 01310-100 |
uf_emissao |
enum | UF de emissão do RG. | SP |
email |
string | E-mail completo ou o começo dele. Domínio sozinho é recusado — ver abaixo. | joao.silva@ |
ddd |
inteiro | DDD, de 11 a 99. | 11 |
telefone |
inteiro | Número completo, sem DDD e sem pontuação. | 999998888 |
por_pagina |
inteiro | Linhas retornadas. Padrão 25, teto 100. | 50 |
422 filtro_nao_suportado:
CPF parcial. A coluna é
char(11) e um prefixo
obrigaria varredura sobre 233 milhões de linhas. Informe os 11 dígitos.
Domínio de e-mail (
@provedor.com). Nenhum índice
cobre o final de uma string, e a coluna dominio da base guarda uma
classificação (PUBLICO), não o domínio. Aceitar o filtro devolveria
resultado plausível e errado.
Resposta
{
"dados": [
{
"id": 2091705,
"nome": "MARIA APARECIDA SILVA",
"cpf": "***.456.789-**",
"nome_mae": "ROSA MARIA BELLONI",
"sexo": "F",
"sexo_descricao": "Feminino",
"nascimento": "1975-03-22",
"idade": 51,
"estado_civil": "C",
"estado_civil_descricao": "Casado(a)",
"cbo": "2521",
"cidade": "SAO PAULO",
"uf": "SP",
"ddd": 11,
"telefone": 999998888
}
],
"paginacao": {
"por_pagina": 25,
"retornados": 25,
"tem_mais": true,
"amostra": false
},
"consulta": {
"condutor": "pessoas",
"ms": 32
}
}
amostra: true muda o significado do resultado.
Quando o filtro mais seletivo ainda casa candidatos demais — uma UF sozinha,
por exemplo —, a busca lê no máximo 4.000 candidatos e filtra dentro deles.
O que volta é um recorte válido, mas não é “os primeiros N do conjunto”
nem permite concluir que não existem outros. Para cobertura, refine até
amostra vir false.
O bloco consulta é diagnóstico: condutor revela por qual
tabela a consulta entrou, o que explica por que uma combinação ficou lenta.
Filtros exatos — CPF, telefone, e-mail, CEP, PIS — conduzem por índice único e
respondem em milissegundos; uf ou sexo sozinhos conduzem
mal e tendem a virar amostra ou 503.
Exemplo
curl -H "Authorization: Bearer evd_SUA_CHAVE" -G "https://evodata.app/api/v1/pessoas" \
--data-urlencode "nome=MARIA" \
--data-urlencode "nome_mae=ANA" \
--data-urlencode "uf=SP" \
--data-urlencode "por_pagina=50"
Ficha de pessoa
GET https://evodata.app/api/v1/pessoas/{id}
chave + plano pago
O id é o identificador interno devolvido no campo id da
busca — não é o CPF, que nunca sai em claro por nenhum endpoint.
A resposta traz todos os campos da linha de busca, mais os blocos:
| Bloco | Tipo | Conteúdo |
|---|---|---|
obito_em |
string|null | Data de óbito, quando registrada na origem. |
nome_pai |
string|null | Nome do pai. |
rg |
string|null | Número do RG, com orgao_emissor e uf_emissao. |
nacionalidade |
string|null | Nacionalidade declarada. |
situacao_cadastral |
integer|null | Código de situação, com situacao_cadastral_em. |
documentos |
object | pis, titulo_eleitor, zona, secao. |
score |
object|null | csb8 e csba com suas faixas de risco, de 0 a 1000. |
perfil_financeiro |
object|null | classe, codigo_classe e faixa de renda estimada. |
enderecos |
array | Até 12, do mais recente ao mais antigo. |
telefones |
array | Até 30, com tipo_descricao legível. |
emails |
array | Até 25, com qualidade e blacklist. |
vinculos |
array | Até 40 relações familiares, resolvidas nos dois sentidos do parentesco. |
***.456.789-** quando a
origem traz o documento da contraparte, e ***.***.***-** quando não
traz. A tabela de parentesco grava apenas uma das direções, então a contraparte
falta com frequência — trate a segunda forma como caso normal.
Tabelas de referência
Os filtros cnae e municipio esperam códigos.
Estes dois endpoints resolvem nome para código e servem bem a campos de
autocompletar.
Buscar CNAE
GET https://evodata.app/api/v1/referencias/cnae?q={termo}
Busca textual na descrição das atividades. Termos com menos de 2 caracteres
devolvem lista vazia e 200 — não é erro.
curl "https://evodata.app/api/v1/referencias/cnae?q=padaria"
{
"dados": [
{ "codigo": 1091102, "descricao": "Fabricação de produtos de padaria e confeitaria com predominância de produção própria" },
{ "codigo": 4721101, "descricao": "Padaria e confeitaria com predominância de produção própria" },
{ "codigo": 4721102, "descricao": "Padaria e confeitaria com predominância de revenda" }
]
}
codigo aqui volta como número, sem o zero à
esquerda que alguns CNAEs têm. Ao repassar para o filtro cnae,
trate como texto de 7 posições.
Municípios por UF
GET https://evodata.app/api/v1/referencias/municipios/{uf}
Todos os municípios de um estado, com o código que o filtro
municipio espera. A sigla não diferencia maiúsculas.
curl "https://evodata.app/api/v1/referencias/municipios/df"
{ "dados": [ { "codigo": "9701", "nome": "BRASILIA" } ] }
Erros
Respostas de erro trazem erro, um código estável seguro para
comparar em código, e quase sempre mensagem, texto em português
voltado a quem lê — sujeito a mudar de redação. Compare pelo
erro, nunca pela mensagem.
| HTTP | erro | Quando acontece |
|---|---|---|
422 |
filtros_ausentes |
GET /empresas sem nenhum filtro além do padrão de situação. |
422 |
cnpj_invalido |
O CNPJ não passa na validação dos dígitos verificadores. |
422 |
uf_invalida |
A sigla informada não está na tabela oficial. |
404 |
nao_encontrado |
CNPJ válido, mas ausente da base da Receita. |
429 |
— |
Limite de requisições excedido. Corpo padrão do Laravel; veja os cabeçalhos. |
503 |
consulta_expirada |
A combinação de filtros excedeu o tempo limite no banco. |
{
"erro": "filtros_ausentes",
"mensagem": "Informe ao menos um filtro. A base tem 72 milhões de estabelecimentos e uma consulta irrestrita não é atendida."
}
O 503 consulta_expirada merece tratamento próprio: ele não indica
indisponibilidade, e sim que aquela combinação de filtros é ampla
demais para o tempo limite do banco. Repetir a mesma chamada tende a falhar
de novo — o caminho é acrescentar um recorte mais estreito, como UF ou
município. Vale notar que a consulta expirada não fica em cache: se o cache
do PostgreSQL esquentar por outra via, a mesma chamada pode passar depois.
Enumerações
situacao
01 | Nula |
02 | Ativa |
03 | Suspensa |
04 | Inapta |
08 | Baixada |
porte
00 | Não informado |
01 | Microempresa |
03 | Empresa de pequeno porte |
05 | Demais |
matriz_filial
1 | Matriz |
2 | Filial |
ordenar
relevancia | Mais relevantes |
abertura_desc | Abertura mais recente |
abertura_asc | Abertura mais antiga |
capital_desc | Maior capital social |
razao_asc | Razão social (A–Z) |
buscar_em
razao | Razão social (padrão) |
fantasia | Nome fantasia |
ambos | Os dois campos |
size_class
micro | Microempresa |
pequena | Pequeno porte |
media | Médio porte |
grande | Grande porte |
uf
AC
AL
AP
AM
BA
CE
DF
ES
GO
MA
MT
MS
MG
PA
PB
PR
PE
PI
RJ
RN
RS
RO
RR
SC
SP
SE
TO
EX
EX designa estabelecimento sediado no exterior.
Limitações conhecidas
Nem tudo que a interface web faz está exposto por HTTP. Vale conhecer as fronteiras antes de desenhar a integração.
-
O CPF nunca sai em claro. Nenhum endpoint devolve o número
completo — busca, ficha e vínculos trazem sempre a forma mascarada
***.XXX.XXX-**. A busca por CPF exige os 11 dígitos, de modo que a API confirme uma identidade que você já tem, em vez de permitir descobri-las. - Não há exportação em massa. O teto é 100 itens por página, e a paginação profunda fica cara porque o banco precisa descartar tudo que veio antes. Para volumes grandes, use a exportação da interface, que percorre o conjunto por chave e não repete nem omite registros.
-
Não há ordenação garantida. Qualquer valor de
ordenarpode ser recusado em conjuntos grandes — a resposta continua200, com a explicação emavisos. Um cliente que dependa de ordem precisa checar esse array. - Não há webhooks nem notificação de mudança. A base acompanha as publicações mensais da Receita Federal; descobrir o que mudou exige reconsultar.
- Respostas são cacheadas. Buscas e fichas passam por cache de curta duração. Duas chamadas idênticas em sequência podem devolver exatamente o mesmo corpo mesmo que a base tenha mudado no meio.