Webhooks
Registrar webhook
Registra ou atualiza a URL de callback que recebe os resultados de emissão e demais eventos.
/openapi/v1/webhookstoken, timestamp e sign, veja Autenticação.Uma configuração de callback por aplicação: webHookId é o identificador da aplicação e chamar novamente sobrescreve a configuração. É a mesma configuração editada no console: registrar aqui ou salvar lá tem efeito idêntico, vale o último salvamento, e o formato dos callbacks depende só do tipo de evento. Chamar o registro de novo também restaura a entrega depois que o disjuntor de falhas consecutivas desligou o webhook. O modelo de entrega, a verificação da assinatura e a política de retentativa estão em Webhooks.
Corpo da requisição
id*obrigatório para atualizar | string | Identificador do webhook |
uri* | string | URL de callback |
contentType* | string | Formato do corpo do callback |
token* | string | Token de verificação |
eventos | array | Eventos assinados |
* Campo obrigatório
webHookId | string | Identificador do webhook |
A plataforma faz POST para uri com corpo JSON (Content-Type: application/json; charset=utf-8). Um HTTP 2xx em até 10 segundos conta como entregue; qualquer outra resposta é reenviada com espera de 1 min, 5 min, 30 min, 2 h e 6 h. Dez falhas consecutivas desligam o webhook; chamar este registro de novo restaura a entrega e zera o contador. Exemplos de verificação da assinatura em Node.js e Java estão em Webhooks.
Cabeçalhos de cada entrega
Deduplique pelo id do evento e verifique a assinatura sobre os bytes originais do corpo.
{"Content-Type": "application/json; charset=utf-8","X-Tffiscal-Event": "invoice.authorized","X-Tffiscal-Event-Id": "1950000000000001","X-Tffiscal-Delivery-Id": "1950000000000002","X-Tffiscal-Timestamp": "1758200000","X-Tffiscal-Signature": "9f2c...e1","token": "dGt6eXp5ZGRra2tzc3Nra2hoaGFha2tha2FhamFoaGFoNzc3Nz","x-token": "dGt6eXp5ZGRra2tzc3Nra2hoaGFha2tha2FhamFoaGFoNzc3Nz"}
X-Tffiscal-Event* | string | Código do evento |
X-Tffiscal-Event-Id* | string | Id do evento |
X-Tffiscal-Delivery-Id* | string | Id da entrega |
X-Tffiscal-Timestamp* | string | Timestamp da assinatura |
X-Tffiscal-Signature* | string | Assinatura |
token*quando há token definido | string | Token de verificação |
x-token*quando há token definido | string | Cópia do token |
* Campo obrigatório
Há duas formas. O objeto de resultado é um JSON sem envelope cujo primeiro campo é tipo (NF-e / NFC-e / CT-e / DC-e / NFS-e), usado pelos eventos de autorização, rejeição e cancelamento de cada documento; ele não tem event_id, deduplique pelo cabeçalho. O envelope de evento (version / event_id / event_type / occurred_at / data) é usado por invoice.canceled, invoice.cce.registered, invoice.verify.completed, cte.event.registered, pelos eventos nfse.inbound.* e por email.sent / email.failed. Campos sem valor aparecem como null.
Objeto de resultado da NF-e
Eventos invoice.authorized e invoice.rejected. Na rejeição os links, a data de autorização e o protocolo ficam vazios.
{"tipo": "NF-e","empresaId": "1934811222334455","nfeId": "NFe-000014553","nfeStatus": "Autorizada","nfeMotivoStatus": null,"nfeLinkDanfe": "https://api.v2.tffiscal.com/openapi/files/danfe/35241204893402000113650010000117691017244265?token=...","nfeLinkXml": "https://api.v2.tffiscal.com/openapi/files/xml/8801?token=...","nfeNumero": "11769","nfeSerie": "10","nfeChaveAcesso": "35241204893402000113650010000117691017244265","nfeDataEmissao": "2024-12-04T17:44:26Z","nfeDataAutorizacao": "2024-12-04T17:44:26Z","nfeNumeroProtocolo": "135240002599237","nfeDigestValue": null}
tipo* | string | Tipo do documento |
empresaId* | string | Identificador da empresa |
nfeId* | string | Id da nota |
nfeStatus* | string | Resultado |
nfeMotivoStatus | string | Motivo da rejeição |
nfeLinkDanfe | string | Link da DANFE |
nfeLinkXml | string | Link do XML autorizado |
nfeNumero | string | Número da nota |
nfeSerie | string | Série |
nfeChaveAcesso | string | Chave de acesso |
nfeDataEmissao* | string | Data de emissão |
nfeDataAutorizacao | string | Data de autorização |
nfeNumeroProtocolo | string | Protocolo de autorização |
nfeDigestValue | string | Resumo da assinatura |
* Campo obrigatório
Objeto de resultado da NFS-e
Eventos nfse.authorized, nfse.rejected, nfse.canceled, nfse.cancel_requested, nfse.cancel_denied e nfse.substituted; o valor de nfseStatus de cada um está na enumeração.
{"tipo": "NFS-e","empresaId": "1001","nfseId": "PED-20260918-001","nfseStatus": "Autorizada","nfseMotivoStatus": null,"nfseLinkDanfse": "https://api.v2.tffiscal.com/openapi/files/danfse/35503082406730610001340000000000000000000000000077?token=...","nfseLinkXml": "https://api.v2.tffiscal.com/openapi/files/xml/9001?token=...","nfseNumero": "1287","nfseSerie": "1","nfseChaveAcesso": "35503082406730610001340000000000000000000000000077","nfseIdentificacaoDps": "DPS355030824067306100013400001000000000000042","nfseDataEmissao": "2026-09-18T13:00:00Z","nfseDataAutorizacao": "2026-09-18T13:00:03Z","nfseNumeroProtocolo": null,"nfseAtualizadoEm": "2026-09-18T13:00:03Z"}
tipo* | string | Tipo do documento |
empresaId* | string | Identificador da empresa |
nfseId* | string | Id da nota |
nfseStatus* | string | Resultado |
nfseMotivoStatus | string | Motivo |
nfseLinkDanfse | string | Link da DANFSe |
nfseLinkXml | string | Link do XML oficial |
nfseNumero | string | Número da NFS-e |
nfseSerie | string | Série |
nfseChaveAcesso | string | Chave de acesso |
nfseIdentificacaoDps | string | Identificador da DPS |
nfseDataEmissao* | string | Data de emissão |
nfseDataAutorizacao | string | Data de autorização |
nfseNumeroProtocolo | string | Protocolo da autoridade |
nfseAtualizadoEm* | string | Momento desta mudança de status |
nfseChaveSubstituta*só em nfse.substituted | string | Chave da nota substituta |
* Campo obrigatório
Objeto de resultado do CT-e
Eventos cte.authorized, cte.rejected e cte.canceled. Uma falha final do lado da plataforma não gera callback; use a consulta do CT-e.
{"tipo": "CT-e","empresaId": "1934811222334455","cteId": "CTe-000000321","cteStatus": "Autorizada","cteMotivoStatus": null,"cteLinkDacte": "https://api.v2.tffiscal.com/openapi/files/dacte/35260940673061000134570010000003211000000321?token=...","cteLinkXml": "https://api.v2.tffiscal.com/openapi/files/xml/7701?token=...","cteNumero": "321","cteSerie": "1","cteChaveAcesso": "35260940673061000134570010000003211000000321","cteDataEmissao": "2026-09-06T12:00:00Z","cteDataAutorizacao": "2026-09-06T12:00:04Z","cteNumeroProtocolo": "135260000000321","cteDigestValue": "tasG40Ic6Zh7PIBiLEEH7Hb940Y="}
tipo* | string | Tipo do documento |
empresaId* | string | Identificador da empresa |
cteId* | string | Id do CT-e |
cteStatus* | string | Resultado |
cteMotivoStatus | string | Motivo da rejeição |
cteLinkDacte | string | Link do DACTE |
cteLinkXml | string | Link do XML autorizado |
cteNumero | string | Número do documento |
cteSerie | string | Série |
cteChaveAcesso | string | Chave de acesso |
cteDataEmissao* | string | Data de emissão |
cteDataAutorizacao | string | Data de autorização |
cteNumeroProtocolo | string | Protocolo de autorização |
cteDigestValue | string | Resumo da assinatura do XML autorizado |
* Campo obrigatório
Objeto de resultado do DC-e
Eventos dce.authorized, dce.rejected, dce.canceled e dce.cancel_rejected. Uma falha antes da numeração também chega como dce.rejected, com os campos do documento em null.
{"tipo": "DC-e","empresaId": "1934811222334455","dceId": "DCe-000012333","dceStatus": "Autorizada","dceMotivoStatus": null,"dceLinkDace": "https://api.v2.tffiscal.com/openapi/files/dace/41260940673061000134990010000000011101234565?token=...","dceLinkXml": "https://api.v2.tffiscal.com/openapi/files/xml/7?token=...","dceNumero": "1","dceSerie": "1","dceChaveAcesso": "41260940673061000134990010000000011101234565","dceDataEmissao": "2026-09-06T12:00:00Z","dceDataAutorizacao": "2026-09-06T12:00:03Z","dceNumeroProtocolo": "141260000000001","dceDigestValue": "tasG40Ic6Zh7PIBiLEEH7Hb940Y="}
tipo* | string | Tipo do documento |
empresaId* | string | Identificador da empresa |
dceId* | string | Id do DC-e |
dceStatus* | string | Resultado |
dceMotivoStatus | string | Motivo |
dceLinkDace | string | Link do DACE |
dceLinkXml | string | Link do XML autorizado |
dceNumero | string | Número do documento |
dceSerie | string | Série |
dceChaveAcesso | string | Chave de acesso |
dceDataEmissao* | string | Data de emissão |
dceDataAutorizacao | string | Data de autorização |
dceNumeroProtocolo | string | Protocolo |
dceDigestValue | string | Resumo da assinatura do XML autorizado |
* Campo obrigatório
Envelope de evento
Exemplo de invoice.canceled: data traz invoice_id, chave e protocolo. Em cte.event.registered, data traz event_code, n_seq e protocolo; em invoice.cce.registered (reservado, ainda não enviado), invoice_id, chave e n_seq.
{"version": "1.0","event_id": "1950000000000001","event_type": "invoice.canceled","occurred_at": "2026-09-06T13:00:00Z","data": {"invoice_id": "1934811222330001","chave": "35241204893402000113650010000117691017244265","protocolo": "135260000000099"}}
version* | string | Versão do envelope |
event_id* | string | Id do evento |
event_type* | string | Código do evento |
occurred_at* | string | Momento do evento |
data* | object | Dados do evento |
* Campo obrigatório
Dados de NFS-e recebida
nfse.inbound.received, nfse.inbound.canceled e nfse.inbound.substituted exigem assinatura explícita. Os três levam inbound_id, chave e prestador_doc; o exemplo é o de chegada.
{"version": "1.0","event_id": "1950000000000003","event_type": "nfse.inbound.received","occurred_at": "2026-09-21T12:15:41Z","data": {"inbound_id": "1950000000000777","chave": "35095022112223330001810000100000000000007710001234","prestador_doc": "40673061000134","n_nfse": "77","valor_servico": "1000.00","competencia": "2026-09-01"}}
inbound_id* | string | Id da nota recebida na plataforma |
chave* | string | Chave de acesso |
prestador_doc* | string | Documento do prestador |
n_nfse*só em nfse.inbound.received | string | Número da NFS-e |
valor_servico*só em nfse.inbound.received | string | Valor do serviço |
competencia*só em nfse.inbound.received | string | Competência |
evento*só em nfse.inbound.canceled | string | Código oficial do evento de cancelamento |
chave_substituta*só em nfse.inbound.substituted | string | Chave da nota substituta |
* Campo obrigatório
Dados de manifestação
nfse.inbound.manifested chega quando a manifestação foi registrada; nfse.inbound.manifest_failed quando a tarefa falhou, e então repita a manifestação antes do prazo de confirmação tácita. Ambos exigem assinatura explícita; o exemplo é o de sucesso.
{"version": "1.0","event_id": "1950000000000004","event_type": "nfse.inbound.manifested","occurred_at": "2026-09-21T14:00:05Z","data": {"inbound_id": "1950000000000777","chave": "35095022112223330001810000100000000000007710001234","tipo": "Rejeicao","evento": "203206","codigo_motivo": "3","motivo": "Servico nao prestado ao tomador","protocolo": "3550308000000000000000000000000000000000000000000001"}}
inbound_id*só em nfse.inbound.manifested | string | Id da nota recebida na plataforma |
chave* | string | Chave de acesso |
tipo* | string | Tipo da manifestação |
evento*só em nfse.inbound.manifested | string | Código oficial do evento registrado |
codigo_motivo*só em nfse.inbound.manifested | string | Código do motivo da rejeição |
motivo* | string | Motivo |
protocolo*só em nfse.inbound.manifested | string | Protocolo da autoridade |
codigo*só em nfse.inbound.manifest_failed | string | Código da falha |
* Campo obrigatório
Dados do resultado da verificação
invoice.verify.completed é o único canal que entrega o veredito final da verificação de NF-e; a consulta por chave serve como reserva.
{"version": "1.0","event_id": "1950000000000005","event_type": "invoice.verify.completed","occurred_at": "2026-07-23T17:16:23Z","data": {"chaveAcesso": "35260764962869000108550990001366171195929648","validationStatus": "VALIDATED","status": "Autorizada","cStat": "100","xMotivo": "Autorizado o uso da NF-e","protocolo": { "numero": "135262955451772", "digestValue": "oAEE...HwY=" },"dataAutorizacao": "2026-07-23T14:30:09Z","eventos": [],"verifiedAt": "2026-07-23T17:16:23Z"}}
chaveAcesso* | string | Chave da nota verificada |
validationStatus* | string | Veredito final |
status* | string | Situação fiscal na SEFAZ |
cStat | string | Código de retorno da SEFAZ |
xMotivo | string | Descrição de retorno da SEFAZ |
protocolo | object | Protocolo oficial |
dataAutorizacao | string | Data de autorização na SEFAZ |
eventos* | array | Eventos fiscais registrados |
verifiedAt* | string | Momento da verificação |
reason*só em REJECTED / VALIDATION_ERROR | string | Explicação do veredito |
* Campo obrigatório
Dados do resultado do e-mail da nota
email.sent chega quando o serviço de envio aceitou a mensagem; email.failed quando o e-mail falhou de forma definitiva (espera esgotada, tentativas esgotadas, nota que deixou de estar autorizada). Os dois exigem assinatura explícita e liberam a nota para um novo envio; o exemplo é o de sucesso. Veja E-mail de notas.
{"version": "1.0","event_id": "1950000000000006","event_type": "email.sent","occurred_at": "2026-09-28T12:00:31Z","data": {"email_id": "2103160000000000001","id": "email-pedido-8842-1","tipo_documento": "NFe","documento_id": "pedido-8842","chave": "35241204893402000113650010000117691017244265","destinatarios": ["comprador@exemplo.com"],"status": "Enviado","motivo_falha": null}}
email_id* | string | Identificador do e-mail |
id* | string | Identificador da requisição |
tipo_documento* | string | Tipo de documento |
documento_id* | string | Identificador da nota |
chave | string | Chave de acesso |
destinatarios* | array | Destinatários efetivos |
status* | string | Resultado |
motivo_falha | string | Motivo da falha |
* Campo obrigatório
eventos[]Códigos de evento
Omitido, assina só invoice.authorized e invoice.rejected. A NFC-e não entra nesse padrão: liste os eventos nfce.* para recebê-los. Os eventos nfse.inbound.* e email.* só são entregues a quem os lista aqui.
| Valores | Significado |
|---|---|
| invoice.authorized | NF-e autorizada pela SEFAZ; objeto de resultado com nfeStatus = Autorizada |
| invoice.rejected | NF-e rejeitada pela SEFAZ; nfeStatus = Negada, motivo em nfeMotivoStatus |
| invoice.canceled | Cancelamento da NF-e registrado na SEFAZ; envelope com invoice_id, chave e protocolo |
| invoice.cce.registered | Carta de correção da NF-e registrada; reservado, ainda não enviado |
| invoice.verify.completed | Veredito final da verificação de NF-e; envelope com validationStatus |
| cte.authorized | CT-e autorizado; cteStatus = Autorizada |
| cte.rejected | CT-e rejeitado pela SEFAZ; cteStatus = Negada |
| cte.canceled | Cancelamento do CT-e registrado; cteStatus = Cancelada |
| cte.event.registered | Outro evento do CT-e registrado (carta de correção, comprovante de entrega, desacordo); envelope com event_code, n_seq e protocolo |
| dce.authorized | DC-e autorizado; dceStatus = Autorizada |
| dce.rejected | DC-e rejeitado pela SEFAZ ou falha final da emissão; dceStatus = Negada |
| dce.canceled | Cancelamento do DC-e registrado; dceStatus = Cancelada |
| dce.cancel_rejected | Cancelamento do DC-e recusado pela SEFAZ ou falha final da tarefa; dceStatus = CancelamentoNegado, documento segue autorizado |
| nfce.authorized | NFC-e autorizada, inclusive nota offline autorizada após a transmissão; objeto de resultado com tipo = NFC-e e nfeStatus = Autorizada |
| nfce.rejected | NFC-e rejeitada pela SEFAZ ou falha do lado da plataforma, inclusive nota offline rejeitada na transmissão; nfeStatus = Negada |
| nfce.canceled | Cancelamento da NFC-e registrado, inclusive por substituição; nfeStatus = Cancelada |
| nfce.cancel_rejected | Cancelamento da NFC-e recusado pela SEFAZ; nfeStatus = CancelamentoNegado, a nota segue autorizada |
| nfce.contingency_issued | NFC-e emitida offline com a SEFAZ indisponível; nfeStatus = ContingenciaPendente, a transmissão depois gera nfce.authorized ou nfce.rejected |
| nfse.authorized | NFS-e emitida com sucesso; nfseStatus = Autorizada |
| nfse.rejected | NFS-e recusada pela autoridade ou falha do lado da plataforma; nfseStatus = Negada |
| nfse.canceled | Cancelamento da NFS-e concluído, inclusive análise deferida; nfseStatus = Cancelada |
| nfse.cancel_requested | Pedido de análise de cancelamento aceito; nfseStatus = EmProcessoDeCancelamento |
| nfse.cancel_denied | Cancelamento não concluído e nota segue autorizada: recusa síncrona, tentativas esgotadas ou análise indeferida; nfseStatus = Autorizada |
| nfse.substituted | NFS-e substituída por outra; nfseStatus = Substituida, mais nfseChaveSubstituta |
| nfse.inbound.received | NFS-e recebida chegou, empresa como tomadora ou intermediária; envelope, assinatura explícita |
| nfse.inbound.canceled | NFS-e recebida cancelada; envelope, assinatura explícita |
| nfse.inbound.substituted | NFS-e recebida substituída; envelope, assinatura explícita |
| nfse.inbound.manifested | Manifestação desta empresa registrada, confirmação ou rejeição; envelope, assinatura explícita |
| nfse.inbound.manifest_failed | Manifestação desta empresa falhou; repita antes da confirmação tácita; envelope, assinatura explícita |
| email.sent | E-mail da nota entregue ao serviço de envio; envelope com data.status = Enviado, assinatura explícita |
| email.failed | E-mail da nota falhou de forma definitiva; envelope com data.status = Falha e data.motivo_falha, assinatura explícita |
nfeStatusResultado da NF-e
| Valores | Significado |
|---|---|
| Autorizada | Autorizada pela SEFAZ |
| Negada | Rejeitada pela SEFAZ |
nfseStatusResultado da NFS-e
| Valores | Significado |
|---|---|
| Autorizada | Emitida (nfse.authorized) ou cancelamento recusado (nfse.cancel_denied) |
| Negada | Recusada ou falha da plataforma (nfse.rejected) |
| Cancelada | Cancelada (nfse.canceled) |
| EmProcessoDeCancelamento | Análise de cancelamento em andamento (nfse.cancel_requested) |
| Substituida | Substituída por outra nota (nfse.substituted) |
cteStatusResultado do CT-e
| Valores | Significado |
|---|---|
| Autorizada | Autorizado (cte.authorized) |
| Negada | Rejeitado pela SEFAZ (cte.rejected) |
| Cancelada | Cancelado (cte.canceled) |
dceStatusResultado do DC-e
| Valores | Significado |
|---|---|
| Autorizada | Autorizado (dce.authorized) |
| Negada | Rejeitado ou falha final da emissão (dce.rejected) |
| Cancelada | Cancelado (dce.canceled) |
| CancelamentoNegado | Cancelamento recusado, documento segue autorizado (dce.cancel_rejected) |
data.validationStatusVeredito da verificação
| Valores | Significado |
|---|---|
| VALIDATED | Nota válida; pode liberar |
| REJECTED | Nota inválida segundo a SEFAZ; reason explica |
| VALIDATION_ERROR | Falha da verificação do lado da plataforma, não é veredito sobre a nota; reenvie com forceRevalidate |
data.statusResultado do e-mail da nota
| Valores | Significado |
|---|---|
| Enviado | Entregue ao serviço de envio (email.sent); a nota aceita um novo envio |
| Falha | Falha definitiva (email.failed); motivo_falha explica e a nota aceita um novo envio |
| Código | HTTP | |
|---|---|---|
| 10009033 | 400 | Registro inválido: id não pertence à aplicação, contentType diferente de application/json ou código desconhecido em eventos; a mensagem diz qual. |
| 10001001 | 400 | Falha de validação de campos: uri ou token vazio ou acima do tamanho, token com caractere fora do ASCII visível (espaço, acento, quebra de linha), eventos com item em branco ou mais de 64 itens. |
