{statusCode, error, message, sefazCode, sefazMessage}: esses campos não existem
no contrato real.
Formato de Erro (RFC 7807)
Timeout depois de emitir: consulte, não reemita
Um timeout não prova que a SEFAZ recusou ou deixou de receber o documento. A autorização pode ter acontecido e apenas a resposta ter sido perdida. Por isso:- consulte o mesmo recurso com
GET /v1/nfe/{id}ouGET /v1/nfce/{id}; - espere o webhook de autorização/rejeição;
- não crie outra emissão com o mesmo pedido só porque o
POSTterminou em timeout.
Como o slug de error.type nasce
O último segmento de error.type (o <SLUG> em .../errors/<SLUG>) é resolvido nesta
ordem, pelo filtro global de exceções:
- Se a exceção carrega um
code(ouerror) explícito e catalogado, entre eles os códigos de negócio (CERTIFICADO_AUSENTE,CNPJ_CONFLICTetc.), o slug é esse valor, normalizado (maiúsculas, espaços viram_). - Sem
code/errorexplícito, o slug cai num mapa fixo por status HTTP (400viraBAD_REQUEST,422viraUNPROCESSABLE_ENTITY,429viraRATE_LIMIT_EXCEEDEDetc.). - Payload de validação em formato de array (rejeição da validação de schema, global
a toda a API) sempre vira
VALIDATION_ERROR, independente do status.
RECUSA_NAO_CATALOGADA; a ocorrência é registrada para correção
interna. O integrador pode tratar esse slug genérico sem depender do código inválido.
errors[] (validação) vs erros[] (fiscal): nunca os dois juntos
Os dois arrays de erro do envelope têm formato e origem diferentes e uma resposta
carrega no máximo um dos dois:
null, "" e campo ausente no PATCH
O GET devolve null em todo campo que ainda não foi preenchido. Como a integração
costuma ler o recurso, mudar um campo e devolver o objeto inteiro, o PATCH de emissor
(PATCH /v1/companies/{id}) trata os três casos assim:
null só desliga a escrita daquele campo. Não afrouxa validação: valor não-nulo
continua passando por DV do CNPJ, formato e limite de tamanho, e erro de conteúdo segue
400 com error.errors[]. sandbox e ambienteFiscal iguais ao atual (roundtrip do
GET) são ignorados; valor diferente recusa com 422 AMBIENTE_IMUTAVEL, não é 200
silencioso.
Casas decimais em valores monetários (400)
Campos monetários de total da NF-e e da NFC-e cujo leiaute declara 2 casas decimais, comovalorFrete, valorSeguro, desconto, outrasDespesas, valores
de ICMS, ST, DIFAL e benefícios, pagamentos[].valor, troco e cobrança, aceitam
no máximo 2 casas. Na NFS-e, a mesma regra vale para servico.valorServicos,
descontos, deduções e retenções. Enviar uma fração de centavo devolve 400 antes
de qualquer efeito.
A engineAPI não arredonda frações de centavo intencionais nem transmite um
centavo diferente do valor declarado. Só desconsidera o resíduo inevitável da
representação binária de operações JavaScript, com tolerância proporcional à
grandeza e muito menor que meio centavo.
valorUnitario é diferente: o tipo do leiaute permite até 10 casas decimais e
essa precisão continua aceita.
A mesma régua agora confere a parte inteira de todo formato decimal fixo. Um
campo 13v2 aceita até 13 dígitos inteiros e 2 casas decimais; acima disso, a
requisição devolve 400 antes de emitir. O teto exato 9999999999999.99 e a
borda 99999999999.99 continuam válidos. A tolerância de ruído binário vale
somente para a comparação das casas decimais e nunca aumenta esse teto.
Campos numéricos fixos que não são dinheiro também seguem o dicionário. Na
NF-e, transporte.volumes[].pesoLiquido e pesoBruto são 12v3: aceitam no
máximo 3 casas decimais. Por exemplo, 1.234 é aceito e 1.2345 devolve 400
com o caminho do volume e a mensagem Campo de precisão fixa aceita no máximo 3 casas decimais. Recebido: 1.2345.
Na NFS-e, os valores TSDec15V2 aceitam até 15 dígitos inteiros e 2 casas
decimais. A largura também é derivada do dicionário da DPS, sem uma lista
manual paralela. Formatos de precisão variável, como o 11v0-10 de
valorUnitario, conservam sua faixa de casas; só o teto de 11 dígitos inteiros
passa a ser aplicado.
Campo desconhecido no payload (400)
O contrato de emissão é estrito: campo que a engineAPI não conhece devolve400 e
nada é emitido (nenhum número fiscal é consumido, nenhuma fatura é criada). Vale para
POST /v1/nfe, POST /v1/nfe/batch, POST /v1/nfce e POST /v1/nfse.
A recusa acontece antes de qualquer processamento, inclusive quando você usa
resolverTributacao: true.
caminho para localizar o campo no seu payload e motivo para decidir o que fazer:
sem motivo, é nome errado ou campo que não existe (a mensagem sugere o campo aceito mais
parecido, quando há um, e avisa quando a diferença é só a caixa das letras). Com motivo,
leia a frase: ela diz se o grupo não existe ainda ou para onde ir.
Campos do leiaute que existem no contrato com outro nome
O corpo da requisição não é o XML. Alguns grupos existem, com nome de campo próprio:Recursos fiscais suportados por passthrough
Estes grupos entram no documento depois de validados. A API verifica forma e coerência, mas não apura os valores nem consulta a regra da UF:Campos do leiaute que a engineAPI ainda não suporta
Estes são campos reais da NF-e. Enviar qualquer um deles devolve400 com o motivo
específico, em vez de a nota sair sem o grupo:
O que muda para quem já integra
Se o seu payload usa apenas campos documentados, nada muda: mesma requisição, mesma resposta. Se você envia algum campo a mais, o que antes era ignorado em silêncio agora é400. Foi
uma decisão deliberada, e o motivo é o desfecho que o silêncio produzia:
POST /v1/nfe/batch) a recusa é tudo ou nada: uma chave desconhecida em uma
única nota recusa o envio inteiro com 400, e nenhuma nota é enfileirada. Antes o lote
respondia 201 e descartava a chave. O caminho é o mesmo do singular: caminho em
camposDesconhecidos diz a nota pelo índice (ex.: notas[2].items[0].comb).
Checklist de migração:
- Rode seus payloads de homologação uma vez. Campo a mais aparece em
details.camposDesconhecidoscom o caminho exato. - Remova os campos sem
motivo(nome errado ou campo inexistente). - Para os campos com
motivo, o grupo ainda não é suportado: retire do payload e trate o cenário fora da API até o suporte existir.
Quando a SEFAZ rejeita: como ver o que foi transmitido
Recusa da SEFAZ vem com o código (cStat) e o motivo verbatim, mas quem depura
precisa do documento que saiu daqui, não só da mensagem. O XML transmitido
de uma emissão rejeitada fica guardado e é recuperável pelo id da nota:
id, devolve também o de uma rejeitada, que não tem
chave. É o documento assinado exatamente como foi enviado, então dá para
conferir tag a tag o que a SEFAZ recusou.
finNFe 2, 3 ou 4 sem o documento referenciado (422)
ide.finNFe: 2 (complementar), 3 (ajuste) ou 4 (devolução) pressupõem, no leiaute, o
documento fiscal referenciado apontando a nota original: sem ele o documento sai
incompleto. A exigência é regra de validação de negócio da SEFAZ (tabela cStat), não
uma restrição do XSD (o grupo é minOccurs="0" no schema): sem ele, a SEFAZ rejeitaria a
nota depois de consumir o número, com cStat 254 na finalidade 2 e cStat 321 na
finalidade 4 (a tabela não tem código dedicado para a 3). A engineAPI recusa as três antes,
com 422, apontando o campo do contrato que resolve:
finNFe: 3 (ajuste) recusa com o mesmo code, mas sem cravar cStat: a mensagem diz
“sem ele a SEFAZ rejeitaria a nota depois de a numeração já ter sido consumida”, porque a
tabela cStat não tem entrada dedicada confirmada para essa finalidade.
finNFe ausente ou 1 (normal) segue emitindo sem mudança. Ver Cobertura fiscal.
Documento referenciado inválido e a forma Sem Pagamento (422)
referenciadas[].chaveAcesso vira a tag do documento referenciado numa nota assinada, e a
forma de pagamento "90" (Sem Pagamento) descreve uma operação sem contraprestação
(remessa, bonificação, comodato, devolução). Quatro recusas cercam os dois campos, todas
422 e todas antes de consumir número fiscal.
REFERENCIADA_INVALIDA: a chave de referenciadas[].chaveAcesso não tem 44 dígitos
numéricos, o código de UF embutido nela não existe na tabela do IBGE, o ano/mês embutido não
traz um mês entre 01 e 12, o modelo embutido não é NF-e (55), NFC-e (65) nem CF-e SAT
(59), o número do documento embutido veio zerado, o dígito verificador não fecha pelo
módulo 11, a mesma chave aparece duas vezes no array, o array tem mais de 500 entradas (o
teto do grupo no leiaute), a chave aponta para a própria nota que está sendo emitida, ou
finNFe: 2 (complementar) veio com mais de uma referência (a complementar complementa uma
nota específica):
SEM_PAGAMENTO_INVALIDO: a forma "90" usada numa combinação que o leiaute não
comporta: valor diferente de zero na entrada com forma "90" (a SEFAZ rejeita com o
código 904), ou a forma "90" presente junto de outra forma de pagamento no mesmo
documento (a forma descreve o documento inteiro, não convive com mais nenhuma entrada em
pagamentos):
SEM_PAGAMENTO_VEDADO_NFCE: a forma "90" numa NFC-e (modelo 65). É vedação da
SEFAZ, não limitação da engineAPI: a NFC-e registra venda a consumidor final com
contraprestação; operação sem pagamento se documenta em NF-e (modelo 55):
FINALIDADE_EXIGE_SEM_PAGAMENTO: o inverso, finNFe: 3 (ajuste) ou 4 (devolução)
com uma forma de pagamento diferente de "90". As duas finalidades registram a operação,
não uma cobrança, e a SEFAZ rejeita a combinação com o código 871:
finNFe: 4, referenciadas apontando a nota
original, e pagamentos com uma única entrada, forma "90" e valor: 0. Ver Cobertura
fiscal para o escopo exato de referenciadas (hoje só a chave de acesso de
NF-e/NFC-e).
Códigos HTTP
Catálogo de códigos de negócio
Todo código abaixo é ocode que vira o slug de error.type (ver
Como o slug nasce). A tabela é gerada da
fonte — apps/api/src/common/errors/catalogo-recusas.ts, o registro único
de onde cada código é lançado — e cobre os codes de negócio ESTÁVEIS das
famílias 400/402/403/409/422, fora dos slugs genéricos por status
(BAD_REQUEST, UNAUTHORIZED, VALIDATION_ERROR etc., já cobertos em
Códigos HTTP) e fora da rejeição SEFAZ/SEFIN (erros[],
passthrough do Fisco — ver Rejeição SEFAZ/SEFIN).
Código que você não reconhece: consulte a versão atual deste catálogo e
mostre error.detail ao usuário. RECUSA_NAO_CATALOGADA indica que a API
substituiu um código não registrado; informe error.requestId ao suporte.
MUNICIPIO_NAO_ADERENTE_PADRAO_NACIONAL (422) é o mesmo código do aviso
aditivo avisos[] no cadastro da empresa: município que não adere ao Padrão
Nacional da NFS-e neste ambiente. Na emissão, recusa antes de numerar se
o espelho já confirma nao_aderente; se a SEFIN ainda devolver E0037, a
mensagem original segue em details.mensagemSefin. desconhecido nunca
dispara este código.
finNFe sem documento
referenciado,
Documento referenciado inválido
e Outros códigos de negócio.CNPJ_CONFLICT sai com code e message idênticos nos dois casos (CNPJ seu ou de
outro parceiro). A mensagem orienta GET /v1/companies e
POST /v1/companies/transfer-request sem revelar o detentor (anti-oráculo, #383): a API
nunca deixa um CNPJ de terceiro virar uma forma de descobrir se ele já tem emissor
cadastrado em outro parceiro da plataforma, nem pela mensagem, nem pelo code.Códigos genéricos e operacionais
Estes slugs também pertencem ao catálogo público, mas ficam fora da tabela gerada de recusas de negócio. O Doc Contract compara esta lista com o registro que o filtro usa na saída.EMISSOR_INEXISTENTE é um desfecho FAILED da fila, em resultData.error.
Ele não é um slug de resposta HTTP: o emissor foi removido depois do
enfileiramento e nenhum número fiscal foi consumido.
GET /v1/queries/cnpj/:cnpj e GET /v1/queries/cpf/:cpf,
Receita Federal/SerPro) que não batem com nenhum code de negócio caem nos slugs
genéricos por status: NOT_FOUND (CNPJ/CPF não encontrado), BAD_GATEWAY (falha sem
categoria mais específica) ou SERVICE_UNAVAILABLE (provedor fora do ar).Rejeição SEFAZ/SEFIN (400): exemplos
Independente do módulo (NF-e, NFC-e, NFS-e), a rejeição fiscal chega como400 com
error.erros[]. Alguns códigos comuns:
Erros de Identificação do Documento
Erros de Identificação do Documento
Erros de Certificado Digital
Erros de Certificado Digital
Erros de Valores e Cálculos
Erros de Valores e Cálculos
Erros de Ambiente
Erros de Ambiente
Erros de Endereço
Erros de Endereço
Erros de Cancelamento
Erros de Cancelamento
Emissão assistida (422): quando aparece
Só ocorre comresolverTributacao: true no payload de NF-e/NFC-e/NFS-e. Se um campo fiscal
obrigatório (ex.: CSOSN, grupo IBS/CBS, cTribNac) não tiver fonte para ser resolvido
pelo Cérebro Fiscal, a API responde 422 e nada é emitido/persistido:
{index, motivo} por item não-resolvido; na NFS-e,
camposNaoResolvidos com {campo, motivo}. Corrija o cadastro do emissor
(servicoPadraoLc116/cTribNacPadrao) ou informe o campo manualmente, e reenvie.
Espelho fiscal divergente
Um dos motivos possíveis dentro dedetails.itensNaoResolvidos: a redução de IBS/CBS
que temos espelhada para o NCM não bate com a tabela oficial de classificação
tributária para a classe (cClassTrib) daquele mesmo NCM. Recusamos com este 422
antes de transmitir: a SEFAZ rejeitaria a mesma incoerência com cStat
1034/1046/1063 (IBS-UF/IBS-Municipal/CBS), só que sem contexto nenhum.
Como seguir agora: informe o grupo ibsCbs do item explicitamente (override do
parceiro, o motor não recalcula nem consulta o espelho para ele), ou emita esse item
sem resolverTributacao, com a tributação que o seu ERP já tem.
Exemplo de payload, o motivo completo de recusar antes de transmitir, e como um mesmo
NCM pode ter mais de um anexo de redução: Erros de
IBS/CBS.
NCM multiclasse
Outro motivo dentro dedetails.itensNaoResolvidos, e o mais comum em alimento: o NCM
aparece em mais de um anexo da LC 214/2025, com percentuais diferentes. Quem decide
qual vale é o produto real, não o código: a resposta traz candidatas[] com todas as
classes vigentes; informe ibsCbs.cClassTrib para desempatar.
Exemplo completo de payload/resposta, a tabela dos 4 codes irmãos
(NCM_MULTICLASSE, NCM_SEM_CLASSE_AUTOMATICA, CCLASSTRIB_INVALIDO_PARA_NCM,
CCLASSTRIB_INADMISSIVEL_NO_MODELO) e as três regras de informar só a classe:
Erros de IBS/CBS.
Pré-voo do emissor (422): quando aparece
Antes de acionar o worker de emissão, a engineAPI valida se o cadastro do emissor (NF-e e NFC-e, o mesmo cadastro) tem o que o documento fiscal exige. Duas checagens, mesmo contrato de resposta:CERTIFICADO_AUSENTE: certificado A1 não instalado
CERTIFICADO_AUSENTE: certificado A1 não instalado
CADASTRO_EMISSOR_INCOMPLETO: IE ou endereço faltando
CADASTRO_EMISSOR_INCOMPLETO: IE ou endereço faltando
"ISENTO", em MAIÚSCULAS, o
pattern da SEFAZ é case-sensitive) e endereço completo (logradouro, bairro,
município, UF, CEP). Sem eles, o schema local do motor fiscal reprovaria a nota; a
engineAPI barra ANTES, com a lista exata do que falta:camposFaltando[] lista
TODOS os campos ausentes de uma vez (não corrige um por vez).O mesmo pré-voo protege a fila de emissão (POST /v1/nfe/batch): o item
falha como FAILED permanente (sem retry, retry não completa cadastro) com
este mesmo envelope em resultData.error, e nenhum número da sequência
fiscal é consumido.CSC_AUSENTE: CSC/cscId não configurados (só NFC-e)
CSC_AUSENTE: CSC/cscId não configurados (só NFC-e)
csc (o token) e
cscId (o ID do token) precisam estar cadastrados no emissor:Outros códigos de negócio
NUMERO_JA_UTILIZADO: número fiscal já usado por outro documento
NUMERO_JA_UTILIZADO: número fiscal já usado por outro documento
POST /v1/nfe e POST /v1/nfce aceitam numero explícito no payload
(passthrough). Se aquele número (na mesma série e modelo do emissor) já foi
usado por outro documento, a resposta é 409 com code: NUMERO_JA_UTILIZADO:
a mensagem diz o número/série/modelo em conflito e os dois caminhos: usar outro
número, ou omitir o campo numero para a numeração automática do emissor
(recomendado, o motor mantém a sequência fiscal atômica por emissor+série).
Nada é emitido e nenhum número novo é consumido.PAGAMENTO_SEM_DADOS_DO_MEIO: cartão/PIX sem os dados do meio
PAGAMENTO_SEM_DADOS_DO_MEIO: cartão/PIX sem os dados do meio
POST /v1/nfe e POST /v1/nfce com pagamentos[].forma "03" (crédito),
"04" (débito) ou "17" (PIX) exigem o grupo pagamentos[].cartao com ao
menos tpIntegra (1 integrado ou 2 não integrado). Sem ele, ou com
tpIntegra=1 sem cnpjInstituicao, a SEFAZ rejeita com 391 depois de
consumir o número fiscal (NT 2023.004 v1.11, RV YA04-10; GO aplica). A API
recusa antes com 422 e code: PAGAMENTO_SEM_DADOS_DO_MEIO. PIX estático
(chave copia-e-cola) usa { "tpIntegra": 2 }; CNPJ da credenciadora, bandeira
e autorização são opcionais.PAGAMENTO_DIVERGENTE: pagamentos não fecham com o total
PAGAMENTO_DIVERGENTE: pagamentos não fecham com o total
pagamentos[].valor menos troco (se houver)
precisa bater no centavo com o total dos itens (a mesma conta do vNF
transmitido: soma dos vProd já arredondados a 2 casas). Divergência devolve
422 com code: PAGAMENTO_DIVERGENTE, citando os dois valores, antes de
qualquer chamada à SEFAZ e sem consumir número fiscal.Com desconto nos itens, o total esperado é o LÍQUIDO (vNF = produtos − desconto + IPI): o desconto agora vai no documento, então pagar o valor
bruto é divergência de verdade. Antes o motor aceitava os dois valores porque
o desconto era ignorado na emissão; hoje não é mais.Com valorFrete/valorSeguro/outrasDespesas nos itens, eles SOMAM ao
total (vNF = produtos − desconto + valorFrete + valorSeguro + outrasDespesas + IPI), o inverso do desconto. Não existe tolerância “sem
os acessórios”: se você informa frete no item, o pagamento tem que cobri-lo.DESCONTO_INVALIDO: desconto que o documento não consegue representar
DESCONTO_INVALIDO: desconto que o documento não consegue representar
items[].desconto é o desconto incondicional do item, em reais, o
vDesc do leiaute. Ele vai para o documento (no item e no total), reduz o
vNF e reduz a base de cálculo do ICMS e do IBS/CBS (LC 87/1996 art. 13,
§ 1º, II, “a”; LC 214/2025 art. 12, § 2º, III).Devolve 422 com code: DESCONTO_INVALIDO, antes de qualquer chamada à
SEFAZ e sem consumir número fiscal, quando:desconto igual ao valor do item é aceito (item integralmente
descontado: base 0, imposto 0). Desconto condicional (o que depende de
evento posterior, como pagamento antecipado) não deve ser informado aqui:
por lei ele integra a base de cálculo, e o leiaute do item não tem campo para
ele.A recusa vale igual com e sem resolverTributacao: true, e nos dois
caminhos de emissão (síncrono e lote); em nenhum deles o número fiscal é
consumido.No sandbox, o XML de demonstração sai com os mesmos valores que a
produção transmitiria (vDesc no item, vNF líquido): o que você testa é o
que a SEFAZ receberia.COBRANCA_INVALIDA: coerência da fatura e das duplicatas (422)
COBRANCA_INVALIDA: coerência da fatura e das duplicatas (422)
cobranca.fatura e cobranca.duplicatas[] (venda a prazo, Guia: Venda a
prazo) passam por 5 conferências antes de qualquer
chamada à SEFAZ, todas com code: COBRANCA_INVALIDA:FRETE_SEGURO_OUTRO_INVALIDO: valores inválidos de frete/seguro/outras despesas ou indTot
FRETE_SEGURO_OUTRO_INVALIDO: valores inválidos de frete/seguro/outras despesas ou indTot
items[].valorFrete, items[].valorSeguro e items[].outrasDespesas são
vFrete/vSeg/vOutro do leiaute, em reais. Ao contrário do desconto,
são campos aditivos: vão para o documento (no item e no total),
aumentam o vNF e aumentam a base de cálculo do ICMS e do IBS/CBS,
o mesmo mecanismo do desconto em sentido inverso (LC 87/1996 art. 13,
§ 1º, II, “a”/“b”; LC 214/2025 art. 12, § 1º, III).items[].indTot indica se o vProd do item entra no vProd/vNF do
total da nota: 1 (ausente = 1, default do leiaute) compõe; 0 não
compõe. Não muda a tributação do próprio item, só a composição do total.
Na NFC-e só 1 é aceito (ver tabela abaixo).Devolve 422 com code: FRETE_SEGURO_OUTRO_INVALIDO, antes de qualquer
chamada à SEFAZ e sem consumir número fiscal, quando:desconto e valorFrete/valorSeguro/outrasDespesas no
mesmo item (sem indTot: 0): a base de cálculo aplica os dois eixos
juntos (vProd − desconto + valorFrete + valorSeguro + outrasDespesas).VNF_INVALIDO: o total da nota ficaria negativo, ou nenhum item compõe o total
VNF_INVALIDO: o total da nota ficaria negativo, ou nenhum item compõe o total
[Total].vNF, sempre ANTES de qualquer chamada
à SEFAZ e sem consumir número fiscal:FRETE_SEGURO_OUTRO_INVALIDO (acima) já
impede a maioria dos casos que levariam a um vNF negativo: este código
é a rede de trás, para o caso de nenhum item compor o total.PIS/COFINS/IPI/CEST/ICMS-ST: recusa em vez de campo ignorado (422)
PIS/COFINS/IPI/CEST/ICMS-ST: recusa em vez de campo ignorado (422)
422 antes de qualquer chamada à SEFAZ (nenhum número fiscal
é consumido). Os valores informados de PIS/COFINS/IPI são transmitidos como
vieram: o motor é passthrough e não calcula tributo.valor: 0 (zero explícito) não é erro em nenhum desses grupos,
inclusive ICMS-ST e ipi: {}: o documento sai igual ao padrão zerado.
Formatação também não é motivo de recusa: cst de 1 dígito vira 2
("1" → "01") e cest com máscara é normalizado.Atenção ao IPI: ele compõe o total da nota (vNF = produtos + IPI).
Para pagamentos, aceitamos tanto o total dos produtos quanto
produtos + IPI: só o que não bate com nenhum dos dois devolve
422 PAGAMENTO_DIVERGENTE. O desconto dos itens, quando houver, é
descontado dos dois valores (o documento sai pelo líquido).Os mesmos 422 valem no lote (POST /v1/nfe/batch): o item da fila
falha no pré-voo, antes de consumir número fiscal, e sai como FAILED com
o code, sem retry (payload não muda entre tentativas).CST/CSOSN × regime do emissor (422 antes da SEFAZ)
CST/CSOSN × regime do emissor (422 antes da SEFAZ)
crt do cadastro):422 locais: nada chega à SEFAZ e nenhum número fiscal é consumido.Domínio efetivo de CSOSN, por (crt, modelo)
O motor não aceita todo código da Tabela CSOSN: só os que emite um documento correto de ponta a ponta, e isso depende do regime (crt) e do
documento (NF-e ou NFC-e), não é uma lista única:201, 202 e 203 (substituição tributária cobrada nesta operação)
emitem na NF-e do Simples Nacional pleno (crt: 1). Você informa o grupo
inteiro: modBCST, vBCST, pICMSST e vICMSST (mais pMVAST e
pRedBCST, opcionais, e o trio vBCFCPST/pFCPST/vFCPST, indivisível).
O 201 exige também pCredSN e vCredICMSSN, o crédito do artigo 23 da
LC 123/2006, que sai da sua apuração. O motor transcreve e valida: não
estima margem nem alíquota interna de ST, e não calcula o crédito. Grupo
incompleto recusa com 422 ICMS_ST_INCOMPLETO; campo que o código não
comporta (ICMS próprio, cst junto do csosn) recusa com
422 ICMS_ST_INVALIDO. pCredSN e vCredICMSSN só têm lugar no 201:
informá-los em qualquer outro código (um 202/203, um 102, ou um
icms.cst de Regime Normal) recusa com 422 ICMS_ST_INVALIDO em vez de
emitir sem eles. O leiaute não tem onde escrevê-los fora do grupo
ICMSSN201, e uma nota autorizada sem o crédito que você informou é um
crédito que o adquirente perde sem aviso. Na NFC-e os três continuam fora: a
regra de validação que lista os CSOSN aceitos no modelo 65 não traz os
códigos de ST, então emita uma NF-e para essa operação. No MEI também
não: o
domínio de CSOSN do MEI é mais estreito e não foi auditado para ST.101 (crédito) não emite em nenhum crt/modelo hoje: o leiaute exige
pCredSN/vCredICMSSN num grupo que este contrato ainda não escreve, e
emitir sem eles violaria o leiaute.500 (ICMS já cobrado por ST/antecipação) e 900 (categoria residual) são
válidos na forma do leiaute, mas a Regra de Validação da NT 2024.001 (MOC
7.0, Anexo I) exige mais do que a forma: 500 precisa do CEST do produto e,
na NFC-e, de um CFOP específico de retorno de ST; 900 depende do
destinatário e do modelo de um jeito que o motor ainda não resolve sozinho.
Emitir sem essas informações arriscaria um documento tecnicamente válido mas
faticamente errado: a mesma régua “ST nunca chuta, recusa” do Regime Normal.
Os dois recusam com 422 CSOSN_NAO_SUPORTADO hoje.MEI (crt: 4) com csosn: "102" exige CFOP específico: NF-e só 5102
ou 6102; NFC-e só 5102. Fora disso, 422 CSOSN_CFOP_MEI_INCOMPATIVEL
(a SEFAZ rejeitaria a combinação com 337). CFOP ausente usa o padrão
5102, dentro do domínio.Regime Normal emite: veja o guia Regime Normal (Lucro Real/Presumido).
O ICMS é calculado pelo motor fiscal a partir de uma base auditada, e o que
ele não cobre recusa com 422 TRIBUTACAO_NAO_RESOLVIDA e motivo por item,
inclusive produto sujeito a substituição tributária, detectado pelo NCM
(CEST do Convênio 142/2018) antes de qualquer cálculo.Nesta fase (N1), o motor calcula o CST 00 (tributação integral). ST,
benefícios fiscais e DIFAL têm caminhos manuais próprios: quem emite informa
os valores, e a API valida e transmite os grupos aplicáveis. Fora desses
caminhos, "cst" manual e "resolverTributacao": true recusam com motivo
específico. Confira o que está coberto hoje em Cobertura Fiscal.LGPD_CONSENT_REQUIRED / LGPD_PURPOSE_REQUIRED: consulta de CPF
LGPD_CONSENT_REQUIRED / LGPD_PURPOSE_REQUIRED: consulta de CPF
GET /v1/queries/cpf/:cpf exige dois headers de compliance LGPD antes de consultar a
Receita Federal (via SerPro). Sem X-LGPD-Consent: true:X-LGPD-Purpose (ou com valor fora de emissao_nfe, cadastro, cobranca,
obrigacao_legal, contrato, credito), o mesmo 422 sai com code
LGPD_PURPOSE_REQUIRED e detail citando a lista de valores aceitos. Toda consulta
de CPF (aceita ou recusada) é registrada em log de auditoria (Art. 37 LGPD).CNPJ_CONFLICT: cadastro de empresa
CNPJ_CONFLICT: cadastro de empresa
POST /v1/companies com um CNPJ que já existe como Issuer (o campo é único
globalmente na base, não por parceiro) sempre volta 409 com o mesmo code e
a mesma mensagem, não importa se o CNPJ já é seu ou de outro parceiro:GET /v1/companies.
Se é de outro parceiro, use POST /v1/companies/transfer-request para solicitar a
transferência (fila revisada manualmente pelo superadmin, com consentimento do dono
atual). Ver Transferência de emissor.PAYMENT_REQUIRED: assinatura com pagamento pendente
PAYMENT_REQUIRED: assinatura com pagamento pendente
PAST_DUE: requisições GET continuam funcionando (modo leitura),
qualquer outro método volta 402:CANCELED (ou sem nenhuma assinatura) responde 403 (Forbidden), não
402. A distinção: 402 tem saída óbvia (pague e volte a emitir), 403 exige
contratar/reativar um plano.TOO_MANY_REQUESTS: rate limit do provedor externo de CNPJ
TOO_MANY_REQUESTS: rate limit do provedor externo de CNPJ
GET /v1/queries/cnpj/:cnpj consulta um provedor externo (Receita Federal) que tem
seu próprio rate limit, independente do seu plano na engineAPI:429/RATE_LIMIT_EXCEEDED da tabela de planos abaixo:
ali é o teto do SEU plano na engineAPI; aqui é o teto do provedor de dados externo.Estratégia de Retry
Implementando Retry com Backoff Exponencial
Rate Limits
Limites por plano, headers e o429 (RFC 7807) estão em Rate Limits,
fonte única, não duplicada aqui.
Veja também
- Conceitos: CFOP e NCM: tabela de referência dos códigos fiscais mais usados.
- Status SEFAZ: monitorar disponibilidade dos servidores SEFAZ.