API do Simples Nacional e do MEI: opção e datas pelo CNPJ
A consulta de CNPJ do apipj já traz a opção da empresa pelo Simples Nacional e pelo MEI (o SIMEI), com as datas de opção e de exclusão, na mesma chamada e sem custo extra. Os dados vêm do arquivo do Simples que a Receita Federal publica todo mês junto com os dados abertos do CNPJ: não são em tempo real.
Dados mensais, não em tempo real. A carga em uso é a de 09/2026. Uma opção ou exclusão registrada depois que a Receita gerou o arquivo só aparece na carga seguinte, semanas depois. Para comprovar a situação de uma empresa, vale a Consulta Optantes do Portal do Simples Nacional.
Os campos simples e mei
No formato completo (padrão), cada resposta de GET /v1/cnpj/{cnpj} traz dois blocos com os mesmos três campos:
| Campo | Tipo | O que é |
|---|---|---|
optante | true ou false | Se o arquivo da Receita marca a empresa como optante |
data_opcao | AAAA-MM-DD ou null | Data de opção pelo regime |
data_exclusao | AAAA-MM-DD ou null | Data de exclusão registrada; pode estar no futuro |
simplesé o Simples Nacional;meié o SIMEI, o regime do microempreendedor individual.- A opção é da empresa, não do estabelecimento: matriz e filiais com a mesma raiz de CNPJ trazem os mesmos blocos.
- Empresa sem nenhum registro no arquivo do Simples vem com
optante: falsee as duas datasnull.
Como ler a data de exclusão
O campo optante sozinho não basta. O arquivo da Receita traz casos em que a empresa ainda está marcada como optante, mas já tem uma data de exclusão registrada, às vezes no futuro e às vezes já vencida no dia em que você consulta. Leia sempre os três campos juntos:
optante | data_exclusao | Leitura |
|---|---|---|
true | null | Optante na data da carga |
true | depois de hoje | Optante, com saída já registrada para essa data |
true | hoje ou antes | A exclusão passou a valer depois que o arquivo foi gerado: trate como excluída e confira no portal |
false | preenchida | Foi optante de data_opcao até a exclusão |
false | null (e data_opcao null) | Sem opção registrada no arquivo |
Um exemplo real: a LEADS2B S/A (11.378.117/0001-20) optou pelo Simples em 2009 e tem exclusão em 31/12/2019. Nunca optou pelo MEI.
{
"cnpj": "11378117000120",
"simples": { "optante": false, "data_opcao": "2009-11-24", "data_exclusao": "2019-12-31" },
"mei": { "optante": false, "data_opcao": null, "data_exclusao": null },
"atualizado_em": "2026-09"
}{
"cnpj": "11.378.117/0001-20",
"simples": { "optante": false, "data_opcao": "24/11/2009", "data_exclusao": "31/12/2019", "ultima_atualizacao": "2026-10-09T20:31:43.201Z" },
"simei": { "optante": false, "data_opcao": null, "data_exclusao": null, "ultima_atualizacao": "2026-10-09T20:31:43.201Z" }
}No formato simplificado (?formato=simplificado), o bloco do MEI se chama simei, as datas vêm em DD/MM/AAAA e cada bloco ganha ultima_atualizacao. Esse campo é o momento em que o apipj gerou a carga, igual em todas as empresas: não é a data de uma mudança no Simples. Para saber o mês dos dados, use atualizado_em no formato completo ou GET /v1/status.
Código: situação no Simples e no MEI numa data
A função abaixo consulta o CNPJ e aplica a tabela acima para a data de hoje, ou para a data que você passar. Ela trata a própria data de exclusão como fora do regime; num caso limítrofe, confira no portal.
export function lerOpcao({ optante, data_opcao, data_exclusao }, data) {
if (data_exclusao && data_exclusao <= data) return `excluída em ${data_exclusao}`;
if (optante) return data_exclusao ? `optante, com exclusão registrada para ${data_exclusao}` : 'optante';
return data_opcao ? 'não optante' : 'sem opção registrada';
}
export async function opcaoSimples(cnpj, data = new Date().toISOString().slice(0, 10)) {
const r = await fetch(`https://apipj.com.br/v1/cnpj/${encodeURIComponent(cnpj)}`, {
headers: { Authorization: `Bearer ${process.env.APIPJ_KEY}` },
});
if (r.status === 404) return null; // CNPJ fora da carga do mês
if (!r.ok) throw new Error(`apipj: HTTP ${r.status}`);
const e = await r.json();
return {
cnpj: e.cnpj,
simples: lerOpcao(e.simples, data),
mei: lerOpcao(e.mei, data),
carga: e.atualizado_em,
};
}
console.log(await opcaoSimples('11378117000120'));import os
from datetime import date
import requests
def ler_opcao(o: dict, data: str) -> str:
if o["data_exclusao"] and o["data_exclusao"] <= data:
return f"excluída em {o['data_exclusao']}"
if o["optante"]:
if o["data_exclusao"]:
return f"optante, com exclusão registrada para {o['data_exclusao']}"
return "optante"
return "não optante" if o["data_opcao"] else "sem opção registrada"
def opcao_simples(cnpj: str, data: str | None = None) -> dict | None:
data = data or date.today().isoformat()
r = requests.get(
f"https://apipj.com.br/v1/cnpj/{cnpj}",
headers={"Authorization": f"Bearer {os.environ['APIPJ_KEY']}"},
timeout=10,
)
if r.status_code == 404:
return None # CNPJ fora da carga do mês
r.raise_for_status()
e = r.json()
return {
"cnpj": e["cnpj"],
"simples": ler_opcao(e["simples"], data),
"mei": ler_opcao(e["mei"], data),
"carga": e["atualizado_em"],
}
print(opcao_simples("11378117000120"))Saída real, em 10/10/2026:
{
cnpj: '11378117000120',
simples: 'excluída em 2019-12-31',
mei: 'sem opção registrada',
carga: '2026-09'
}{'cnpj': '11378117000120', 'simples': 'excluída em 2019-12-31', 'mei': 'sem opção registrada', 'carga': '2026-09'}As datas da API vêm em AAAA-MM-DD, então a comparação de texto (<=) já ordena certo, sem converter para data. Além do exemplo real, as duas versões foram testadas com os cinco casos da tabela e com um CNPJ que não está na base (resposta null / None).
Quando conferir no portal oficial
- Para provar a situação perante um cliente, um fornecedor ou o fisco: a Consulta Optantes, da própria Receita, consulta a opção pelo Simples Nacional e pelo SIMEI no momento.
- Quando a decisão depende de uma mudança recente: empresa aberta, que optou ou que foi excluída depois da geração do arquivo do mês.
- Quando
optanteétruee a data de exclusão já passou, ou cai em cima da data que importa para você.
Para o resto, como preencher o cadastro, separar a carteira por regime ou marcar quem precisa de revisão, a carga mensal basta, e uma reconsulta a cada carga nova mantém a informação em dia. O guia de validação de fornecedor mostra como fazer essa reconsulta.
Perguntas frequentes
A consulta do Simples custa à parte?
Não. Os blocos simples e mei vêm em toda consulta de CNPJ e contam como uma consulta só. O plano gratuito tem 50.000 consultas por mês. Veja a API de CNPJ para os outros campos.
A API diz qual imposto a empresa paga ou se devo reter tributo?
Não. Ela informa a opção registrada pela Receita e as datas. Regras de retenção, alíquota e enquadramento dependem da operação: confirme com o seu contador.
Por que a filial aparece como optante se quem optou foi a matriz?
Porque a opção pelo Simples é da empresa, identificada pela raiz do CNPJ (os 8 primeiros caracteres). Todos os estabelecimentos da mesma raiz trazem os mesmos blocos.
Um MEI aparece como optante do Simples também?
Em geral, sim: nos dados da Receita, quase todo MEI optante também está marcado como optante do Simples Nacional. Mesmo assim, leia cada bloco pela sua própria data de exclusão, porque a saída do MEI e a do Simples podem ter datas diferentes.