Primeiros passos
Convenções gerais
Os dois formatos de resposta (respostas simples vs. envelope da plataforma), formatos de erro, tipificação de erros, referência de status HTTP, idempotência, limites de taxa, localização, tipos de dados, a estrutura da chave de acesso da NF-e e os links de download de arquivos.
Convenções compartilhadas pelos endpoints da Open API da TF Fiscal.
Formatos de resposta
A API tem dois formatos de resposta, e qual deles você recebe depende do endpoint e da camada que produziu a resposta.
Respostas simples (endpoints padrão)
Todos os endpoints padrão (empresas, NF-e, CT-e, DC-e, verificação, consulta cadastral, registro de webhook) respondem sem envelope:
| Grupo de endpoints | Formato de sucesso |
|---|---|
| Cadastro de empresa, registro de webhook | Objeto simples ({ "empresaId": ... }, { "webHookId": ... }) |
| Vinculação de certificado, emissão e cancelamento de NF-e / CT-e / DC-e | HTTP 200 sem corpo; o resultado chega de forma assíncrona |
| Consulta de NF-e / CT-e / DC-e, registro de carta de correção e de eventos | Objeto simples: o documento, o protocolo ou a lista de eventos |
| Verificação por XML, consulta por chave | Objeto simples: a nota interpretada (a verificação por XML acrescenta o bloco validation) |
| Consulta de CNPJ, consulta de CPF | Objeto simples: o registro cadastral |
Os erros de negócio e de requisição dos endpoints padrão vêm em dois formatos de erro, conforme a família do endpoint.
Família de emissão (empresas, NF-e, CT-e, DC-e, registro de webhook; HTTP 400 / 404): um array de erros, cada um com codigo e mensagem. Falhas de validação do corpo produzem uma entrada por campo:
[{ "codigo": "NFe0001", "mensagem": "A Nota fiscal nao foi encontrada. Por favor, verifique se o id foi informado corretamente" }]
codigo é uma string: os três códigos GW001 (cidade / estado inválido), CER0005 (senha do certificado incorreta) e NFe0001 (nota não encontrada) mantêm os seus valores alfanuméricos, assim como os códigos DCe* da família DC-e; todas as demais entradas carregam o código de erro da plataforma como string numérica.
Famílias de verificação e consulta cadastral (HTTP 400, e 422 / 428 / 451 / 503 na consulta cadastral): um objeto simples com code e message:
{ "code": 10015004, "message": "Invoice not found" }
| Campo | Tipo | Descrição |
|---|---|---|
code | integer | Código de erro da plataforma |
message | string | Explicação legível, localizada |
Envelope da plataforma
Usado pelo endpoint de echo (POST /openapi/demo/echo) em toda resposta, pelo endpoint de download de arquivos nas suas falhas e pelo gateway da plataforma para os erros da camada de autenticação em todo endpoint (HTTP 401 / 403 / 429), produzidos antes de a requisição chegar ao endpoint:
{ "success": true, "message": "OK", "data": { } }
{ "success": false, "errorType": 1, "code": 10009003, "message": "Signature error" }
| Campo | Tipo | Presença | Descrição |
|---|---|---|---|
success | boolean | sempre | false em todo erro |
errorType | integer | em erro | Classe do erro, veja Tipificação de erros |
code | integer | em erro | Código de erro da plataforma, veja Códigos de erro |
message | string | sempre | Explicação legível, localizada |
data | object | null | em sucesso | Carga do endpoint; não preenchida em erros |
Tratando os dois formatos
O seu tratador de erros deve aceitar o envelope e os formatos de erro simples. Uma regra robusta:
- Trate HTTP 400 ou superior como falha e, adicionalmente,
success: falsequando o corpo for um envelope. - Interprete o corpo como JSON. Se for um array, leia
codigode cada entrada; se for um objeto, leiacode. - Ramifique pelo código, nunca pelo texto de
message/mensagem(eles são localizados).
Tipificação de erros (errorType)
Os erros em envelope carregam um campo errorType que classifica a origem da falha:
| errorType | Classe | Significado |
|---|---|---|
| 1 | Erro de API | Rejeição de autenticação, autorização ou de negócio pela TF Fiscal |
| 2 | Rejeição da SEFAZ | A autoridade fiscal brasileira rejeitou a operação |
| 3 | Falha de sistema | Falha inesperada da plataforma; seguro repetir com backoff |
| 4 | Falha de validação | A validação dos campos da requisição falhou |
Referência rápida de status HTTP
| HTTP | Cenário | Formato do corpo |
|---|---|---|
| 200 | Requisição aceita; na verificação por XML isso inclui uma validação reprovada (verifique o bloco validation) | Dados simples, ou sem corpo |
| 400 | Requisição inválida ou regra de negócio violada | [{codigo, mensagem}] (emissão) ou {code, message} (verificação / consulta cadastral) |
| 404 | empresaId / id do documento não encontrado (família de emissão) | [{codigo, mensagem}] |
| 401 | Falha de autenticação (token / sign / timestamp), ou link de download inválido ou vencido | Envelope da plataforma |
| 403 | Aplicação desativada / não vigente / integrador desativado / não subscrito | Envelope da plataforma |
| 422 / 428 / 451 | Consulta de CPF retida por lei (titular de 16 a 17 anos / idade não verificável / titular menor de 16); não repita | {code, message}, sem campos pessoais |
| 429 | Limite de taxa excedido | Envelope da plataforma |
| 503 | Fonte de dados upstream indisponível (consulta cadastral, 10016020) ou arquivo ainda não renderizado (download, 10009037); repita após Retry-After | {code, message} ou envelope da plataforma |
| 5xx | Falha do lado da plataforma | Repita com backoff; se persistir, contate a plataforma com o timestamp e o caminho da falha |
Idempotência
- A emissão de NF-e é idempotente pelo
idda requisição que você gera: reenviar o mesmoidreutiliza a tarefa original. Se a tentativa anterior foi negada (Negada), reenviar o mesmoidcom os campos corrigidos emite de novo com a nova carga, sem necessidade de novo id. Alterar campos-chave como o destinatário enquanto a tentativa anterior ainda está em processamento ou já foi autorizada é rejeitado comcodigo10004032. - A emissão de CT-e e DC-e também é idempotente pelo
id: uma mensagem idêntica reutiliza a tarefa original, uma mensagem diferente sob o mesmoidé rejeitada (10017030para CT-e,10019030para DC-e), e uma falha terminal (Falha) reabre a tarefa com a nova mensagem. - A verificação por XML é idempotente pela chave de acesso (
chave): reenviar enquanto uma verificação está em andamento devolve o progresso atual, e vereditos terminais são reutilizados por 24 horas. Para forçar uma nova verificação, envie o cabeçalhoforceRevalidate: trueno endpoint de XML (o cabeçalho não faz parte da assinatura). A consulta por chave é um GET fixo e não tem canal de reverificação; para forçar uma nova verificação, reenvie pelo endpoint de XML. UmREJECTEDda camada 1 não tem registro de camada 2; a reverificação exige reenviar o XML. - As entregas de webhook são idempotentes por
event_id: toda tentativa e todo destino de um mesmo evento carregam o mesmo valor, então deduplique por ele. Veja Webhooks.
Limite de taxa e backoff
- Cota por aplicação: excedê-la devolve HTTP 429 com o código
10009006. Os limites são aplicados por aplicação e por grupo de endpoints. Recue e repita (comece em 1 s, dobre até 30 s, adicione jitter) e suavize a sua taxa de chamadas. - Anti-flood por CNPJ: se uma empresa acumular tarefas de emissão pendentes demais, novos envios são rejeitados com
codigo10004002até a fila esvaziar; repita mais tarde. - Janela do timestamp: requisições com
timestampfora de ±300 s do relógio do servidor são rejeitadas (10009001), o que também limita o replay de requisições capturadas. - 401 e 403 são erros de configuração; repeti-los sem corrigir só consome cota.
- Downloads de arquivos contam no limite da aplicação em grupo próprio e não são cobrados.
Localização das respostas
Os campos message, mensagem e *Description seguem o idioma da requisição: o cabeçalho Language (zh / en / pt / es) tem precedência, depois Accept-Language (aceita pt-BR e valores q). Sem cabeçalho de idioma, as respostas usam por padrão português (pt). Os cabeçalhos de idioma não fazem parte da assinatura.
As cargas de webhook carregam apenas valores de enumeração independentes de idioma; não há campos *Description nelas. Para decisões programáticas, use sempre códigos e campos de enumeração (code, codigo, status, validationStatus, errors[].code, situacao.codigo), nunca texto descritivo.
Horários e tipos de dados
- Horários produzidos pela plataforma (
dataCriacao,dataAutorizacaodos documentos emitidos,occurred_atde webhook,verifiedAt,serverTimedo echo) são ISO-8601 UTC com o sufixoZ, em todo ambiente. - Horários extraídos de um documento de terceiros pela API de verificação (
dataEmissao,dataAutorizacao) são devolvidos sem alteração, com o fuso do documento, por exemplo2026-07-23T11:20:05-03:00. - O cabeçalho
timestampda requisição é tempo Unix em segundos, não milissegundos. - Identificadores são strings mesmo quando numéricos (
empresaId,webHookId,event_id), para evitar perda de precisão numérica em JavaScript. Trate todos os ids como strings opacas; oidde documento que você gera também é uma string. - Números de documento (
numero) e séries (serie) são strings. Valores e quantidades são números JSON. - Variáveis de caminho como
cnpj,cpfechavesão strings só de dígitos, sem caracteres de formatação; a data de nascimento do CPF (nascimento) éDDMMYYYY.
A chave de acesso da NF-e (chave)
A chave de acesso é o identificador nacionalmente único de 44 dígitos de uma NF-e. Ela aparece como chaveAcesso nas respostas de consulta e verificação e como variável de caminho da consulta por chave. Sua estrutura:
| Posições | Tamanho | Campo | Significado |
|---|---|---|---|
| 1 a 2 | 2 | cUF | Código IBGE do estado emissor (ex.: 35 = SP) |
| 3 a 6 | 4 | AAMM | Ano e mês de emissão (AAMM) |
| 7 a 20 | 14 | CNPJ | CNPJ do emitente |
| 21 a 22 | 2 | mod | Modelo do documento fiscal (55 = NF-e) |
| 23 a 25 | 3 | serie | Série da nota |
| 26 a 34 | 9 | nNF | Número da nota |
| 35 | 1 | tpEmis | Tipo de emissão |
| 36 a 43 | 8 | cNF | Código numérico aleatório |
| 44 | 1 | cDV | Dígito verificador (módulo 11) |
Observações:
- Armazene e transmita sempre a chave como uma string de 44 caracteres (zeros à esquerda são significativos).
- A consulta por chave valida tamanho, caracteres e dígito verificador localmente antes de qualquer consulta; uma chave malformada devolve HTTP 400 com o código
10015104. - As chaves de CT-e (modelo 57) e DC-e (modelo 99) compartilham o mesmo layout de 44 dígitos com o seu próprio valor de
mod.
Links de download de arquivos
Os links de download nas respostas de consulta e nas cargas de callback (linkDanfe, linkDownloadXml, linkDacce e seus equivalentes de CT-e / DC-e) têm o formato https://api.v2.tffiscal.com/openapi/files/{kind}/{ref}?token=.... Eles não precisam de cabeçalhos de assinatura: basta um GET simples que siga o redirecionamento 302. O token é vinculado ao caminho, ao integrador e à aplicação, então use o link exatamente como devolvido. Os links valem por 7 dias por padrão e toda consulta emite links novos; um link vencido devolve 401 com 10009036. Detalhes: Download de arquivos.
