CNPJ Alfanumérico — Documentação Técnica
Este guia é o companheiro técnico do Comunicado. Se você é desenvolvedor ou arquiteto e precisa adaptar uma integração, é aqui que estão os contratos JSON, os comportamentos por produto e o checklist de migração.
Base regulatória: IN RFB 2.229/2024 · NT Conjunta ENCAT 2025.001 v1.00.
Índice
- Visão geral em 30 segundos
- O novo formato do CNPJ
- O princípio de versionamento da NFE.io
- O que muda no contrato da API
- Mudanças por produto
- Webhooks
- Códigos de status e mensagens de erro
- Checklist de preparação
- Cenários de teste em homologação
- Perguntas frequentes
1. Visão geral em 30 segundos
A partir de 01/08/2026, a Receita Federal passa a emitir CNPJs que podem conter letras. Isso afeta diretamente quem já integra com a gente — então a pergunta que guiou todo o nosso desenho foi: como dar suporte ao formato novo sem que ninguém precise mexer no que já funciona hoje?
A resposta foi criar um novo versionamento das APIs, com uma regra simples de entender:
| Versão | Status | Tipo de federalTaxNumber na request | Tipo na response/webhook |
|---|---|---|---|
| Versionamento atual (v1) | congelada | number | number |
| Versionamento atual (v2) | congelada (boundary defensivo) | number | number |
| Novo versionamento | novo | string (aceita number por compatibilidade na entrada) | sempre string |
Cada produto tem o seu próprio novo versionamento — o número da versão pode variar entre produtos (emissão, cadastro, distribuição e cada consulta evoluem em ritmos diferentes).
Se você guardar só uma frase deste documento, que seja esta:
Mantra: "O versionamento atual nunca enxerga CNPJ alfa. O novo versionamento é alfa-aware."
2. O novo formato do CNPJ
2.1 Especificação
O CNPJ continua com 14 posições, mas agora as 12 primeiras podem misturar letras e números. Só os dois dígitos verificadores no final permanecem estritamente numéricos:
14 posições totais
├── 12 alfanuméricas (raiz 8 + ordem 4) — pode conter [A-Z0-9]
└── 2 numéricas (dígitos verificadores) — sempre [0-9]
Letras vedadas: I, O, U, Q, F
(evitam confusão visual com 0 e 1)
Regex efetiva: ^[A-HJ-NPRT-Z0-9]{12}[0-9]{2}$
2.2 Exemplos
Lado a lado, fica fácil ver a diferença:
CNPJ numérico legado: 12345678000199 (14 dígitos)
CNPJ alfanumérico: 12ABC345000ABC (12 alfanum + 2 dígitos)
2.3 Algoritmo do dígito verificador
O cálculo continua sendo o bom e velho Módulo 11 — a novidade é que os pesos passam a ser aplicados sobre o valor ASCII menos 48 de cada caractere. Na prática, isso faz os dígitos 0–9 continuarem valendo 0–9 e dá um valor numérico para cada letra:
'0' (ASCII 48) → 0
'9' (ASCII 57) → 9
'A' (ASCII 65) → 17
'Z' (ASCII 90) → 42
Se você valida o dígito verificador no seu lado, precisa atualizar esse algoritmo. Nossa recomendação, porém, é não reinventar a roda: delegue para uma biblioteca oficial de validação de CNPJ da sua linguagem. Assim você não precisa se preocupar com os detalhes do cálculo.
3. O princípio de versionamento da NFE.io
3.1 Tabela canônica
Esta tabela resume, camada por camada, o que acontece quando um CNPJ alfanumérico encontra cada versão das APIs de emissão, cadastro e distribuição. A leitura é direta: na coluna legado, o sistema protege você do formato novo; na coluna do novo versionamento, ele o entrega de forma consistente.
| Camada | Versionamento atual | Novo versionamento (alfa-aware) |
|---|---|---|
| API de Empresas (cadastro) | empresa alfa → 400 Bad Request (requer o novo versionamento) | aceita, response string |
| Emissão de NF-e/NFC-e | issuer alfa → 400 Bad Request | aceita, response string |
| Emissão de NFS-e | issuer alfa → 400 Bad Request | aceita, response string |
| Distribuição de Documentos Fiscais (inbound) | federalTaxNumber tratado como texto; visibilidade segue a versão da assinatura | documento alfa entregue como string |
| Webhook | formato do payload segue a versão da assinatura/webhook | entregue como string |
| Response JSON | sempre number | sempre string |
Consultas — trilha própria de versionamento
As APIs de Consulta seguem em trilha separada das de emissão. O versionamento ainda está em estudo, voltado à compatibilização entre as versões existentes. Hoje, em homologação, o CNPJ alfanumérico está disponível apenas para teste — porém vamos trabalhar em um versionamento próprio para essa alteração (uma versão alfa-aware dedicada às Consultas), que será comunicado quando definido. O contrato pretendido: a versão atual recusa CNPJ alfa (400) e o novo versionamento entrega o dado (200) ou 404 se não existir. Detalhes e roadmap em Consultas.
| Camada | Versionamento atual | Versão alfa-aware |
|---|---|---|
| API de Consulta de Notas | CNPJ alfa → 400 Bad Request | 200 OK (string); 404 se o registro não existir |
| API de Consulta de Pessoa Jurídica (CNPJ) | CNPJ alfa → 400 Bad Request | 200 OK (string); 404 se o registro não existir |
3.2 Por que desenhamos assim
Três objetivos guiaram esse desenho — e vale a pena entender cada um, porque eles explicam praticamente todo o comportamento descrito neste documento:
- Zero regressão. Para clientes nas suas versões atuais, nada muda — nem no schema, nem no tipo do campo, nem no comportamento. Quem está integrado hoje pode ignorar tranquilamente toda essa mudança.
- Sem flags, sem espera. Não existe feature flag, whitelist nem código
412para "habilitar" o alfa. Quem decide quando o alfa entra em produção é a origem do dado (a SEFAZ, na NF-e/NFC-e; as prefeituras, na NFS-e): no instante em que ela libera o formato alfa, o sistema NFE.io passa a autorizar automaticamente (ex.:cStat=100na NF-e), sem nenhuma intervenção manual da nossa parte. - Determinístico. O novo versionamento não escolhe o tipo do JSON conforme o valor do CNPJ — ele é sempre
string. Isso significa que seu parser nunca precisa lidar com union types nem adivinhar o formato; é texto, ponto.
4. O que muda no contrato da API
4.1 Request — o novo versionamento aceita os dois tipos
Para facilitar a sua vida na migração, o novo versionamento é flexível na entrada: ele aceita federalTaxNumber como string (o jeito recomendado) ou como number (por compatibilidade, útil enquanto você ainda tem código antigo). Internamente, tudo é normalizado para string.
Os valores de
federalTaxNumbernos exemplos abaixo são ilustrativos — não são CNPJs reais.
// ✅ Recomendado (novo versionamento)
{
"federalTaxNumber": "12ABC345000ABC"
}
// ✅ Também aceito (novo versionamento, compat — para CNPJ numérico)
{
"federalTaxNumber": 12345678000199
}
// ❌ Versionamento atual rejeita string com letras
{
"federalTaxNumber": "12ABC345000ABC" // → 400 Bad Request
}
4.2 Response — novo versionamento sempre string
Na saída, o novo versionamento é rígido de propósito: sempre string, seja o CNPJ numérico ou alfanumérico. Essa consistência é o que permite que o seu parser não tenha surpresas.
Os valores de
federalTaxNumbernos exemplos abaixo são ilustrativos — não são CNPJs reais.
// Versionamento atual (hoje e amanhã — congelada)
{
"id": "...",
"federalTaxNumber": 12345678000199, // number
"name": "Empresa Exemplo S.A."
}
// Novo versionamento — CNPJ numérico
{
"id": "...",
"federalTaxNumber": "12345678000199", // string
"name": "Empresa Exemplo S.A."
}
// Novo versionamento — CNPJ alfanumérico
{
"id": "...",
"federalTaxNumber": "12ABC345000ABC", // string
"name": "Empresa Nova Ltda."
}
4.3 Selecionando a versão
A versão é escolhida pelo endpoint — o segmento de versão fica na URL (ex.: /v{versão}/...). Não há versionamento por header: o número da versão está sempre no caminho da chamada.
O número da versão varia por produto — cada API tem a sua versão atual (numérica, congelada) e a sua versão alfa-aware (o novo versionamento), e essas numerações não são iguais entre os produtos. Consulte a numeração de cada um nos guias Emissões / DF-e e Consultas.
5. Mudanças por produto
O comportamento detalhado por produto está organizado em dois guias:
- Emissões / DF-e — cadastro de empresas, NF-e/NFC-e, NFS-e e Distribuição de DF-e.
- Consultas — Consulta de Notas (NF-e) e Consulta de Pessoa Jurídica (CNPJ / legalentities).
6. Webhooks
6.1 Regra de envio
Aqui o critério é importante e às vezes contraintuitivo, então vale destacar:
O webhook segue a versão do contrato que o subscriber assinou — e não o valor do CNPJ da nota.
| Subscriber assinado em | CNPJ numérico | CNPJ alfanumérico |
|---|---|---|
| Versionamento atual | ✅ entregue, payload com federalTaxNumber: number | 🚫 não entregue |
| Novo versionamento | ✅ entregue, payload com federalTaxNumber: string | ✅ entregue, payload com federalTaxNumber: string |
6.2 Migração de webhook
A migração de webhook é tranquila e pode ser feita sem downtime:
- Cadastre uma nova subscription no novo versionamento apontando para um endpoint já preparado para receber
string. - Com as duas rodando em paralelo e o novo versionamento confirmado, desligue o versionamento atual.
- Lembre-se: não há "duplicação" automática — se você mantiver as duas subscriptions ativas, vai receber o mesmo evento numérico nas duas versões.
6.3 Exemplo de payload — webhook do novo versionamento
{
"event": "invoice.authorized",
"data": {
"id": "5f9...",
"issuer": {
"federalTaxNumber": "12ABC345000ABC", // string sempre
"name": "Empresa Nova Ltda."
},
"accessKey": "35260512ABC345000ABCxx...",
"status": "Authorized"
}
}
7. Códigos de status e mensagens de erro
Os códigos e mensagens abaixo descrevem o comportamento das APIs de emissão (NF-e/NFC-e/NFS-e, cadastro e distribuição). O comportamento de erro das Consultas está no guia Consultas.
7.1 Tabela canônica
Quando algo dá errado, a resposta é sempre clara sobre o motivo — nada de 500 genérico:
| Status | Quando ocorre | Mensagem típica |
|---|---|---|
400 Bad Request / rejeição | Tentativa de emitir com CNPJ alfa na versão atual | a versão atual rejeita; o erro orienta o novo versionamento. O formato varia por produto — ex.: NFS-e devolve texto orientando a v3; na NF-e/NFC-e a emissão na versão atual não resolve a empresa alfa |
400 Bad Request | federalTaxNumber com formato inválido (tamanho ≠ 14, letras vedadas I/O/U/Q/F, DV inválido) | {"message":"Invalid federalTaxNumber"} |
404 Not Found | Consulta, via versão atual, de uma nota emitida no novo versionamento (CNPJ alfa) | {"message":"Not Found"} |
cStat=215 (resposta SEFAZ — NF-e/NFC-e) | XML chegou à SEFAZ, mas SEFAZ rejeitou (XSD antigo) | resposta real da SEFAZ, sem mascaramento NFE.io |
cStat=100 (NF-e/NFC-e) | SEFAZ aceitou (caminho feliz, alfa autorizado) | Autorizado o uso da NF-e |
7.2 O que não existe
Para evitar que você procure por algo que não vai encontrar:
- ❌ Não há
412 Precondition Failed— não usamos esse código para isto. - ❌ Não há feature flag de "habilitar CNPJ alfa para minha conta".
- ❌ Não há whitelist por AccountId.
8. Checklist de preparação
8.1 Para quem só usa CNPJ numérico
A boa notícia: é uma lista curtíssima.
- Documentar internamente que
federalTaxNumberno versionamento atual continuanumber— nada precisa mudar. - Treinar suporte/atendimento: quando um cliente final pedir suporte a CNPJ alfa, direcionar para a migração ao novo versionamento do produto utilizado.
8.2 Para quem vai suportar CNPJ alfanumérico
Aqui vale ser metódico. Separamos por frente para você não esquecer nenhum ponto.
Código
- Tipo de
federalTaxNumberem modelos / DTOs / entities →string(nãolong,int64,bigint, etc. — qualquer tipo de armazenamento numérico). - Validação de formato → aceita
[A-HJ-NPRT-Z0-9]{12}[0-9]{2}ou usar a lib oficial da sua linguagem para CNPJ. - Validação de DV → Módulo 11 com ASCII−48.
- Remover qualquer
Long.parseLong(cnpj),int64(cnpj),cnpj.toFixed(0),cnpj.padStart(14, '0')aplicado antes de saber se é numérico. - Trocar máscara de display de
"00.000.000/0000-00"para algo tolerante a letras (ou exibir sem máscara).
Banco de dados
- Analise como o
federalTaxNumberé armazenado no seu banco: se hoje é um tipo numérico (ex.:BIGINT,NUMERIC(14)), será necessário acomodar texto (ex.:VARCHAR(14)ou equivalente). A decisão de modelagem é sua. - Índices de igualdade → continuam funcionando, mas revise índices que dependiam de ordenação numérica.
- Considere
COLLATEou normalização paraUPPERno armazenamento (CNPJs alfa são[A-Z], mas inputs podem vir minúsculos).
Integração
- Trocar o endpoint da versão atual pelo do novo versionamento do produto que você usa (o número da versão varia por produto).
- Atualizar a webhook subscription para o novo versionamento.
- Atualizar parsers JSON para esperar
string(a maioria das libs lida nativamente, mas linguagens de tipagem forte podem precisar de cast). - Logs / observabilidade → garantir que o CNPJ não está sendo serializado como número em algum sink (ex.: mapping do Elasticsearch).
Teste
- Cenário positivo numérico no novo versionamento.
- Cenário positivo alfa no novo versionamento.
- Cenário no versionamento atual com payload
stringcontendo letras → confirmar400. - Cenário no versionamento atual com
GETde empresa alfa → confirmar400. - Webhook do novo versionamento com CNPJ alfa → confirmar entrega e parse.
9. Cenários de teste em homologação
A Sefaz / Emissor Nacional disponibilizam CNPJs alfanuméricos de teste no ambiente de homologação a partir de junho/2026 (sem data definida) — use-os para validar a integração de ponta a ponta antes de 01/08/2026.
9.1 Exemplos didáticos (não reais — substitua pelos publicados pela Receita)
CNPJ alfa de homologação: 12ABC345000ABC
CNPJ numérico de homologação: 12345678000199
9.2 Fluxo recomendado
Um roteiro que cobre os principais caminhos:
- Cadastre a empresa alfa via
POST /v3/companies(homologação). - Tente emitir uma NF-e/NFS-e de teste pelo novo versionamento.
- Observe a resposta da origem do dado (na NF-e/NFC-e, via
cStatda SEFAZ; na NFS-e, conforme a prefeitura):- autorizada (ex.:
cStat=100na NF-e) → caminho feliz, alfa funcionando. - rejeitada (ex.:
cStat=215na NF-e) → a autoridade ainda não liberou o formato alfa (esperado em alguns períodos).
- autorizada (ex.:
- Confira o webhook do novo versionamento chegando com
string. - Por fim, tente a mesma operação via versionamento atual → confirme os
400/404esperados.
10. Perguntas frequentes
P1. Vocês vão descontinuar o versionamento atual? Não por causa dessa mudança. O versionamento atual continua suportado por tempo indeterminado, com o contrato congelado. Se houver depreciação no futuro, ela será comunicada com antecedência pelos canais oficiais.
P2. Preciso pedir liberação para emitir com CNPJ alfa? Não. Não existe whitelist, feature flag nem aprovação manual. Quando você usa o novo versionamento com CNPJ alfa, a requisição vai até a SEFAZ/prefeitura, e a emissão só funciona se a autoridade aceitar.
P3. O que acontece se eu mandar uma string "12345678000199" (numérico, mas como texto) no novo versionamento?
Funciona normalmente. O novo versionamento aceita os dois tipos na entrada — numérico ou alfanumérico, como string ou number.
P4. E se eu mandar number no versionamento atual com um CNPJ que deveria existir como alfa?
JSON number não consegue representar letras. Se você tentar mandar "12ABC345000ABC" no versionamento atual (que espera número), a request falha no parser/validador → 400 Bad Request.
P5. Os CNPJs numéricos atuais vão virar alfa em algum momento? Não. CNPJs já emitidos pela Receita Federal continuam numéricos. Só os novos cadastros (a partir de 01/08/2026) é que podem vir alfanuméricos.
P6. Como sei se um CNPJ é alfa ou numérico programaticamente?
Verifique se há algum caractere fora do conjunto [0-9] nas 12 primeiras posições. Se houver, é alfa. Os 2 dígitos finais (DV) são sempre numéricos.
function isAlphanumericCnpj(cnpj) {
return /[A-Z]/.test(cnpj.substring(0, 12));
}
P7. O DANFE / PDF da nota vai mudar? Internamente, sim — o barcode da chave de acesso passa a aceitar caracteres alfanuméricos (CODE-128A). Visualmente, o layout permanece o mesmo. Se você consome o PDF, nada muda no seu lado.
P8. E o cliente que tem rotina de batch processando milhares de notas?
Comece fazendo um inventário dos pontos onde federalTaxNumber é parseado. Migre o tipo e os parsers para string e rode tudo em homologação antes de subir para produção. Nossa recomendação é migrar de forma incremental: comece pelo fluxo de consulta (o mais barato), depois cadastro e, por último, emissão.
P9. E os meus dados históricos com CNPJ numérico no Mongo/Postgres?
Eles permanecem como estão. A NFE.io não exige reescrita dos dados antigos. Internamente, lemos o campo de forma polimórfica (number ou string) e sempre o expomos como string no novo versionamento.
P10. Onde abrir dúvidas?
- Suporte técnico: portal de integradores NFE.io.
- Documentação pública: https://nfe.io/docs.
- Fontes regulatórias oficiais: IN RFB 2.229/2024 e NT Conjunta ENCAT 2025.001 v1.00.
Resumo técnico em 3 linhas:
- Trate
federalTaxNumbercomostringem qualquer integração nova.- Use o novo versionamento de cada produto para consumir/produzir CNPJ alfa (o número da versão varia por produto).
- Não invente whitelist nem flag — a origem do dado (SEFAZ/prefeitura) é o único gate real.