Webhooks
Register webhook
Registers or updates the callback URL that receives issuance results and other events.
/openapi/v1/webhookstoken, timestamp and sign signature headers, see Authentication.One callback configuration per application: webHookId is the application identifier and calling again overwrites the configuration. It is the same configuration edited in the console: registering here or saving there has the same effect, the latest save wins, and the callback format depends only on the event type. Calling the registration again also restores delivery after the consecutive-failure circuit breaker switched the webhook off. The delivery model, signature verification and retry policy are in Webhooks.
Request body
id*required for update | string | Webhook identifier |
uri* | string | Callback URL |
contentType* | string | Callback body format |
token* | string | Verification token |
eventos | array | Subscribed events |
* Required field
webHookId | string | Webhook identifier |
The platform POSTs to uri with a JSON body (Content-Type: application/json; charset=utf-8). An HTTP 2xx within 10 seconds counts as delivered; anything else is retried after 1 min, 5 min, 30 min, 2 h and 6 h. Ten consecutive failures switch the webhook off; calling this registration again restores delivery and resets the counter. Signature verification samples in Node.js and Java are in Webhooks.
Headers on every delivery
Deduplicate on the event id and verify the signature over the raw body bytes.
{"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 | Event code |
X-Tffiscal-Event-Id* | string | Event id |
X-Tffiscal-Delivery-Id* | string | Delivery id |
X-Tffiscal-Timestamp* | string | Signature timestamp |
X-Tffiscal-Signature* | string | Signature |
token*when a token is set | string | Verification token |
x-token*when a token is set | string | Token copy |
* Required field
There are two shapes. The result object is a bare JSON whose first field is tipo (NF-e / NFC-e / CT-e / DC-e / NFS-e), used by the authorization, rejection and cancellation events of each document; it has no event_id, deduplicate on the header. The event envelope (version / event_id / event_type / occurred_at / data) is used by invoice.canceled, invoice.cce.registered, invoice.verify.completed, cte.event.registered, the nfse.inbound.* events and email.sent / email.failed. Fields without a value appear as null.
NF-e result object
Events invoice.authorized and invoice.rejected. On rejection the links, authorization time and protocol are empty.
{"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 | Document type |
empresaId* | string | Company identifier |
nfeId* | string | Invoice id |
nfeStatus* | string | Outcome |
nfeMotivoStatus | string | Rejection reason |
nfeLinkDanfe | string | DANFE link |
nfeLinkXml | string | Authorized XML link |
nfeNumero | string | Invoice number |
nfeSerie | string | Series |
nfeChaveAcesso | string | Access key |
nfeDataEmissao* | string | Issue time |
nfeDataAutorizacao | string | Authorization time |
nfeNumeroProtocolo | string | Authorization protocol |
nfeDigestValue | string | Signature digest |
* Required field
NFS-e result object
Events nfse.authorized, nfse.rejected, nfse.canceled, nfse.cancel_requested, nfse.cancel_denied and nfse.substituted; the nfseStatus of each is in the enumeration.
{"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 | Document type |
empresaId* | string | Company identifier |
nfseId* | string | Invoice id |
nfseStatus* | string | Outcome |
nfseMotivoStatus | string | Reason |
nfseLinkDanfse | string | DANFSe link |
nfseLinkXml | string | Official XML link |
nfseNumero | string | NFS-e number |
nfseSerie | string | Series |
nfseChaveAcesso | string | Access key |
nfseIdentificacaoDps | string | DPS identifier |
nfseDataEmissao* | string | Issue time |
nfseDataAutorizacao | string | Authorization time |
nfseNumeroProtocolo | string | Authority protocol |
nfseAtualizadoEm* | string | Time of this status change |
nfseChaveSubstituta*nfse.substituted only | string | Replacing invoice key |
* Required field
CT-e result object
Events cte.authorized, cte.rejected and cte.canceled. A final platform-side failure sends no callback; use the CT-e query.
{"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 | Document type |
empresaId* | string | Company identifier |
cteId* | string | CT-e id |
cteStatus* | string | Outcome |
cteMotivoStatus | string | Rejection reason |
cteLinkDacte | string | DACTE link |
cteLinkXml | string | Authorized XML link |
cteNumero | string | Document number |
cteSerie | string | Series |
cteChaveAcesso | string | Access key |
cteDataEmissao* | string | Issue time |
cteDataAutorizacao | string | Authorization time |
cteNumeroProtocolo | string | Authorization protocol |
cteDigestValue | string | Signature digest of the authorized XML |
* Required field
DC-e result object
Events dce.authorized, dce.rejected, dce.canceled and dce.cancel_rejected. A failure before numbering also arrives as dce.rejected, with the document fields set to 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 | Document type |
empresaId* | string | Company identifier |
dceId* | string | DC-e id |
dceStatus* | string | Outcome |
dceMotivoStatus | string | Reason |
dceLinkDace | string | DACE link |
dceLinkXml | string | Authorized XML link |
dceNumero | string | Document number |
dceSerie | string | Series |
dceChaveAcesso | string | Access key |
dceDataEmissao* | string | Issue time |
dceDataAutorizacao | string | Authorization time |
dceNumeroProtocolo | string | Protocol |
dceDigestValue | string | Signature digest of the authorized XML |
* Required field
Event envelope
Example of invoice.canceled: data carries invoice_id, chave and protocolo. In cte.event.registered, data carries event_code, n_seq and protocolo; in invoice.cce.registered (reserved, not sent yet), invoice_id, chave and 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 | Envelope version |
event_id* | string | Event id |
event_type* | string | Event code |
occurred_at* | string | Event time |
data* | object | Event data |
* Required field
Received NFS-e data
nfse.inbound.received, nfse.inbound.canceled and nfse.inbound.substituted require an explicit subscription. All three carry inbound_id, chave and prestador_doc; the example is the arrival one.
{"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 | Platform id of the received invoice |
chave* | string | Access key |
prestador_doc* | string | Provider document |
n_nfse*nfse.inbound.received only | string | NFS-e number |
valor_servico*nfse.inbound.received only | string | Service amount |
competencia*nfse.inbound.received only | string | Competence month |
evento*nfse.inbound.canceled only | string | Official code of the cancellation event |
chave_substituta*nfse.inbound.substituted only | string | Replacing invoice key |
* Required field
Manifestation data
nfse.inbound.manifested arrives when the manifestation was registered; nfse.inbound.manifest_failed when the task failed, so repeat the manifestation before the tacit confirmation deadline. Both require an explicit subscription; the example is the success one.
{"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*nfse.inbound.manifested only | string | Platform id of the received invoice |
chave* | string | Access key |
tipo* | string | Manifestation type |
evento*nfse.inbound.manifested only | string | Official code of the registered event |
codigo_motivo*nfse.inbound.manifested only | string | Rejection reason code |
motivo* | string | Reason |
protocolo*nfse.inbound.manifested only | string | Authority protocol |
codigo*nfse.inbound.manifest_failed only | string | Failure code |
* Required field
Verification outcome data
invoice.verify.completed is the only channel that delivers the final NF-e verification verdict; the key query is the fallback.
{"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 | Key of the verified invoice |
validationStatus* | string | Final verdict |
status* | string | Tax status at SEFAZ |
cStat | string | SEFAZ return code |
xMotivo | string | SEFAZ return description |
protocolo | object | Official protocol |
dataAutorizacao | string | SEFAZ authorization time |
eventos* | array | Registered tax events |
verifiedAt* | string | Verification time |
reason*REJECTED / VALIDATION_ERROR only | string | Verdict explanation |
* Required field
Invoice e-mail outcome data
email.sent arrives when the mail service accepted the message; email.failed when the e-mail failed for good (exhausted wait, exhausted attempts, document no longer authorized). Both require an explicit subscription and release the document for a new send; the example is the success one. See Invoice e-mail.
{"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 | E-mail identifier |
id* | string | Request identifier |
tipo_documento* | string | Document type |
documento_id* | string | Document identifier |
chave | string | Access key |
destinatarios* | array | Effective recipients |
status* | string | Outcome |
motivo_falha | string | Failure reason |
* Required field
eventos[]Event codes
Omitted, subscribes only to invoice.authorized and invoice.rejected. NFC-e is not part of that default: list the nfce.* events to receive them. The nfse.inbound.* and email.* events are only delivered to applications that list them here.
| Values | Meaning |
|---|---|
| invoice.authorized | NF-e authorized by SEFAZ; result object with nfeStatus = Autorizada |
| invoice.rejected | NF-e rejected by SEFAZ; nfeStatus = Negada, reason in nfeMotivoStatus |
| invoice.canceled | NF-e cancellation registered at SEFAZ; envelope with invoice_id, chave and protocolo |
| invoice.cce.registered | NF-e correction letter registered; reserved, not sent yet |
| invoice.verify.completed | Final NF-e verification verdict; envelope with validationStatus |
| cte.authorized | CT-e authorized; cteStatus = Autorizada |
| cte.rejected | CT-e rejected by SEFAZ; cteStatus = Negada |
| cte.canceled | CT-e cancellation registered; cteStatus = Cancelada |
| cte.event.registered | Other CT-e event registered (correction letter, delivery proof, service disagreement); envelope with event_code, n_seq and protocolo |
| dce.authorized | DC-e authorized; dceStatus = Autorizada |
| dce.rejected | DC-e rejected by SEFAZ or final issuance failure; dceStatus = Negada |
| dce.canceled | DC-e cancellation registered; dceStatus = Cancelada |
| dce.cancel_rejected | DC-e cancellation refused by SEFAZ or final task failure; dceStatus = CancelamentoNegado, document stays authorized |
| nfce.authorized | NFC-e authorized, including an offline invoice authorized after transmission; result object with tipo = NFC-e and nfeStatus = Autorizada |
| nfce.rejected | NFC-e rejected by SEFAZ or platform-side failure, including an offline invoice rejected on transmission; nfeStatus = Negada |
| nfce.canceled | NFC-e cancellation registered, including by substitution; nfeStatus = Cancelada |
| nfce.cancel_rejected | NFC-e cancellation refused by SEFAZ; nfeStatus = CancelamentoNegado, the invoice stays authorized |
| nfce.contingency_issued | NFC-e issued offline while SEFAZ was down; nfeStatus = ContingenciaPendente, the later transmission produces nfce.authorized or nfce.rejected |
| nfse.authorized | NFS-e issued successfully; nfseStatus = Autorizada |
| nfse.rejected | NFS-e refused by the authority or platform-side failure; nfseStatus = Negada |
| nfse.canceled | NFS-e cancellation completed, including a granted review; nfseStatus = Cancelada |
| nfse.cancel_requested | Cancellation review request accepted; nfseStatus = EmProcessoDeCancelamento |
| nfse.cancel_denied | Cancellation not completed and invoice stays authorized: synchronous refusal, retries exhausted or review refused; nfseStatus = Autorizada |
| nfse.substituted | NFS-e replaced by another; nfseStatus = Substituida, plus nfseChaveSubstituta |
| nfse.inbound.received | Received NFS-e arrived, company as recipient or intermediary; envelope, explicit subscription |
| nfse.inbound.canceled | Received NFS-e cancelled; envelope, explicit subscription |
| nfse.inbound.substituted | Received NFS-e replaced; envelope, explicit subscription |
| nfse.inbound.manifested | This company manifestation registered, confirmation or rejection; envelope, explicit subscription |
| nfse.inbound.manifest_failed | This company manifestation failed; repeat before the tacit confirmation; envelope, explicit subscription |
| email.sent | Invoice e-mail handed to the mail service; envelope with data.status = Enviado, explicit subscription |
| email.failed | Invoice e-mail failed for good; envelope with data.status = Falha and data.motivo_falha, explicit subscription |
nfeStatusNF-e outcome
| Values | Meaning |
|---|---|
| Autorizada | Authorized by SEFAZ |
| Negada | Rejected by SEFAZ |
nfseStatusNFS-e outcome
| Values | Meaning |
|---|---|
| Autorizada | Issued (nfse.authorized) or cancellation refused (nfse.cancel_denied) |
| Negada | Refused or platform failure (nfse.rejected) |
| Cancelada | Cancelled (nfse.canceled) |
| EmProcessoDeCancelamento | Cancellation review in progress (nfse.cancel_requested) |
| Substituida | Replaced by another invoice (nfse.substituted) |
cteStatusCT-e outcome
| Values | Meaning |
|---|---|
| Autorizada | Authorized (cte.authorized) |
| Negada | Rejected by SEFAZ (cte.rejected) |
| Cancelada | Cancelled (cte.canceled) |
dceStatusDC-e outcome
| Values | Meaning |
|---|---|
| Autorizada | Authorized (dce.authorized) |
| Negada | Rejected or final issuance failure (dce.rejected) |
| Cancelada | Cancelled (dce.canceled) |
| CancelamentoNegado | Cancellation refused, document stays authorized (dce.cancel_rejected) |
data.validationStatusVerification verdict
| Values | Meaning |
|---|---|
| VALIDATED | Invoice valid; may release |
| REJECTED | Invoice invalid per SEFAZ; reason explains |
| VALIDATION_ERROR | Platform-side verification failure, not a verdict on the invoice; resubmit with forceRevalidate |
data.statusInvoice e-mail outcome
| Values | Meaning |
|---|---|
| Enviado | Handed to the mail service (email.sent); the document accepts a new send |
| Falha | Final failure (email.failed); motivo_falha explains and the document accepts a new send |
| Code | HTTP | |
|---|---|---|
| 10009033 | 400 | Invalid registration: id does not belong to the application, contentType other than application/json or unknown code in eventos; the message says which. |
| 10001001 | 400 | Field validation failed: uri or token empty or over the length limit, token with a character outside visible ASCII (space, accented letter, line break), eventos with a blank item or more than 64 items. |
