Guias · Por apipj (MASTER BI TECNOLOGIA LTDA) · atualizado em · 4 min de leitura · Código executado contra a API em (Node.js 18 e 24, Python 3.12 + requests 2.32)

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:

CampoTipoO que é
optantetrue ou falseSe o arquivo da Receita marca a empresa como optante
data_opcaoAAAA-MM-DD ou nullData de opção pelo regime
data_exclusaoAAAA-MM-DD ou nullData 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: false e as duas datas null.

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:

optantedata_exclusaoLeitura
truenullOptante na data da carga
truedepois de hojeOptante, com saída já registrada para essa data
truehoje ou antesA exclusão passou a valer depois que o arquivo foi gerado: trate como excluída e confira no portal
falsepreenchidaFoi optante de data_opcao até a exclusão
falsenull (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 é true e 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.