Conceitos
A emissão é assíncrona
POST /v1/nfe e POST /v1/nfse não esperam a SEFAZ ou o Sistema Nacional. Eles validam o pedido, calculam os impostos, guardam a nota e respondem 202 com "status": "queued". O envio acontece em segundo plano, com novas tentativas automáticas quando o órgão está fora do ar.
O resultado chega de duas formas:
- webhook (recomendado):
nfe.authorized,nfe.rejected,nfse.authorized... Veja Webhooks; - consulta:
GET /v1/nfe/{id}ouGET /v1/nfe?externalId=....
Situações da nota
| Situação | O que significa | O que fazer |
|---|---|---|
queued, sending, pending |
Na fila ou em envio | Esperar |
unknown |
A resposta do órgão se perdeu; a emitza está conferindo se a nota foi registrada | Esperar. Nunca emita de novo com outro externalId |
authorized |
Autorizada, com valor fiscal (em produção) | Baixar o XML e o PDF |
rejected |
Recusada pelo órgão, com o motivo em rejection |
Corrigir e reenviar com o mesmo externalId |
denied |
Uso denegado (NF-e): registrada, mas sem valor, por irregularidade do emitente ou do destinatário | Resolver a situação cadastral; o número fica consumido |
failed |
Parou sem resposta do órgão (ex.: certificado vencido) | Corrigir a causa e chamar POST /v1/nfe/{id}/retry |
cancelled |
Cancelada por evento | Nada |
Quando attention vem preenchido, a nota precisa de ação manual. O campo traz um código (por exemplo, reconcile_exhausted, quando a conferência com o órgão não fechou). Fale com o suporte da emitza informando o id da nota.
Idempotência: o externalId
O externalId é o seu identificador do pedido, e é ele que impede nota em dobro:
- repetir o mesmo pedido com o mesmo
externalIddevolve a nota que já existe, com status200, sem emitir outra. Use isso à vontade quando a sua requisição cair no meio; - enviar o mesmo
externalIdcom outro conteúdo devolve409, exceto quando a nota foi rejeitada; - nota
rejected: reenvie o pedido corrigido com o mesmoexternalId. Ela é reenviada com a mesma série e o mesmo número.
Use um externalId por documento fiscal, por exemplo o número do pedido ou da ordem de serviço.
Erros
Todo erro tem o mesmo formato:
{
"error": {
"code": "validation_failed",
"message": "Dados inválidos",
"details": [{ "path": "items[0].ncm", "message": "deve ter 8 dígitos" }]
}
}| Status | code |
Quando |
|---|---|---|
| 400 | bad_request |
JSON malformado |
| 401 | unauthorized |
Chave ausente, inválida ou no endereço errado |
| 404 | not_found |
Recurso inexistente ou de outro cliente |
| 409 | conflict |
externalId com outro conteúdo, nota em situação que não permite a ação |
| 422 | validation_failed e outros |
Campos inválidos (veja details) ou regra de negócio: series_missing, certificate_unavailable, sandbox_homologation_only... |
| 429 | rate_limited |
Limite de requisições; espere o tempo do cabeçalho Retry-After |
| 503 | busy |
Serviço ocupado; tente de novo depois do Retry-After |
Campos desconhecidos são recusados: um erro de digitação aparece na hora, em vez de ser ignorado em silêncio.
Rejeição da SEFAZ não é erro HTTP: a nota é aceita (202) e depois fica rejected, com rejection.cStat e rejection.reason.
Valores e formatos
- Decimais em texto, com ponto:
"1500.00","7.6". Nunca número JSON, para não perder centavos. - Datas no formato
AAAA-MM-DD; data e hora em ISO 8601. - CNPJ, CEP e códigos aceitam pontuação, que é removida.
Limites
- 20 requisições por segundo por cliente, com picos de até 40.
- Corpo de até 1 MB.
- Até 990 itens por NF-e.
Ambientes
Cada empresa tem um environment: homologation (testes, sem valor fiscal) ou production. Com a chave de teste, a empresa fica sempre em homologação. As séries e a numeração são separadas por ambiente: nota de teste nunca consome número de produção.
Esta página em Markdown, para IA: index.md