Códigos de status interno
A API do FazNota adota uma convenção de canal único de status: enquanto a aplicação
processar a requisição (passar autenticação e parser), a resposta é sempre HTTP 200,
e o resultado real fica em body.status (3 dígitos, 001–999).
Esse código distingue sucesso, pendência, erro de validação, rejeição da SEFAZ e erros internos. Apenas falhas estruturais (auth, rate limit, URL errada) retornam HTTP ≠ 200 — veja Estrutura de resposta para o detalhe.
Tabela completa
| Código | Significado | Quando aparece |
|---|---|---|
001 | Registrado. A operação foi recebida e está na fila para processamento. | Resposta imediata de qualquer emissão/cancelamento/CC-e. |
002 | Pendente de processamento. Na fila, ainda não começou. | Polling do recibo logo após emissão. |
003 | Em processo de emissão. Está sendo processada agora. | Polling enquanto SEFAZ ainda não respondeu. |
004 | Documento emitido. Status terminal de sucesso. | Polling após autorização SEFAZ. |
005 | Consulta realizada. Status para endpoints GET de listagem/busca. | Listagens, buscas por documento/nome/referência. |
010 | Documento cancelado. Status terminal após cancelamento. | Polling após processamento de cancelamento. |
050 | Duplicidade de numero-origem. A operação não criou nova nota; retorna o recibo da emissão original. | Emissão com numero-origem já usado. Veja Idempotência. |
500 | Recibo não existe. O recibo informado não está na base. | GET /<recurso>/<recibo> com recibo inválido. |
900 | Rejeição pela SEFAZ — verifique sefaz.codigo antes de tratar como terminal. Se sefaz.codigo for 217/105, é transitório (SEFAZ lenta), não rejeição real. Veja SEFAZ lenta ou instável. | Polling após SEFAZ recusar a nota (CST inválido, NCM errado, etc.) ou SEFAZ lenta/instável. |
999 | Erro interno. Erro de validação do payload OU erro inesperado. Veja data.erro. | Imediatamente após qualquer requisição com erro. |
Códigos por tipo de operação
Emissão (POST)
Imediatamente após enviar uma emissão (NFe, NFCe, NFSe):
| Código | Cenário |
|---|---|
001 | OK, processando. Comece o polling. |
050 | numero-origem duplicado; use o recibo retornado. |
999 | Erro de validação (veja data.erro). |
Consulta de recibo (GET)
Durante o polling do recibo:
| Código | Cenário | Ação |
|---|---|---|
001 | Acabou de ser registrada. | Aguarde, consulte novamente. |
002 | Pendente. | Aguarde, consulte novamente. |
003 | Emitindo. | Aguarde, consulte novamente. |
004 | Emitida ✅ | Pegue data.sefaz.url-danfe e data.sefaz.url-xml. |
010 | Cancelada | Não emita de novo. |
500 | Recibo inválido. | Verifique se o recibo foi salvo corretamente. |
900 | Rejeitada SEFAZ — ou SEFAZ lenta | Veja data.sefaz.codigo. Se for 217/105: aguarde e consulte de novo, não reemita (veja SEFAZ lenta ou instável). Qualquer outro código: corrija o dado indicado em data.sefaz.mensagem e emita nova nota. |
999 | Erro interno. | Cite meta.request_id no suporte. |
Listagem (GET)
| Código | Cenário |
|---|---|
005 | OK. data traz a lista. |
999 | Erro interno. |
Cancelamento / Carta de correção (POST)
Imediatamente após enviar:
| Código | Cenário |
|---|---|
001 | OK, processando. Comece o polling em GET /<recurso>/cancelamento/{recibo} ou GET /<recurso>/correcao/{recibo}. |
999 | Erro de validação. |
Padrão para clientes
const TERMINAIS_SUCESSO = ['004', '010'];const TERMINAIS_FALHA = ['500', '999']; // "900" tratado à parte — veja abaixoconst PENDENTES = ['001', '002', '003'];const SEFAZ_CODIGO_TRANSITORIO = ['217', '105']; // SEFAZ lenta: não é rejeição definitiva
function classificar(json: { status: string; data?: { sefaz?: { codigo?: string } } }): 'sucesso' | 'falha' | 'pendente' { const { status, data } = json;
if (status === '900') { const codigoSefaz = data?.sefaz?.codigo; // SEFAZ lenta/instável: ainda não é definitivo, continue consultando o mesmo recibo if (codigoSefaz && SEFAZ_CODIGO_TRANSITORIO.includes(codigoSefaz)) return 'pendente'; return 'falha'; // rejeição real — corrija o dado e emita nova nota }
if (TERMINAIS_SUCESSO.includes(status)) return 'sucesso'; if (TERMINAIS_FALHA.includes(status)) return 'falha'; if (PENDENTES.includes(status)) return 'pendente'; if (status === '050') return 'sucesso'; // duplicidade é retorno controlado if (status === '005') return 'sucesso'; // consulta OK return 'falha';}