Webhooks
Registrar webhook
Registra o actualiza la URL de callback que recibe los resultados de emisión y demás eventos.
/openapi/v1/webhookstoken, timestamp y sign, vea Autenticación.Una configuración de callback por aplicación: webHookId es el identificador de la aplicación y llamar de nuevo sobrescribe la configuración. Es la misma configuración que se edita en la consola: registrar aquí o guardar allí tiene el mismo efecto, prevalece el último guardado, y el formato de los callbacks depende solo del tipo de evento. Llamar de nuevo al registro también restaura la entrega después de que el cortacircuitos por fallos consecutivos apagó el webhook. El modelo de entrega, la verificación de la firma y la política de reintentos están en Webhooks.
Cuerpo de la petición
id*obligatorio para actualizar | string | Identificador del webhook |
uri* | string | URL de callback |
contentType* | string | Formato del cuerpo del callback |
token* | string | Token de verificación |
eventos | array | Eventos suscritos |
* Campo obligatorio
webHookId | string | Identificador del webhook |
La plataforma hace POST a uri con cuerpo JSON (Content-Type: application/json; charset=utf-8). Un HTTP 2xx en hasta 10 segundos cuenta como entregado; cualquier otra respuesta se reintenta tras 1 min, 5 min, 30 min, 2 h y 6 h. Diez fallos consecutivos apagan el webhook; llamar de nuevo a este registro restaura la entrega y pone el contador a cero. Ejemplos de verificación de la firma en Node.js y Java están en Webhooks.
Cabeceras de cada entrega
Deduplique por el id del evento y verifique la firma sobre los bytes originales del cuerpo.
{"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 del evento |
X-Tffiscal-Event-Id* | string | Id del evento |
X-Tffiscal-Delivery-Id* | string | Id de la entrega |
X-Tffiscal-Timestamp* | string | Timestamp de la firma |
X-Tffiscal-Signature* | string | Firma |
token*cuando hay token definido | string | Token de verificación |
x-token*cuando hay token definido | string | Copia del token |
* Campo obligatorio
Hay dos formas. El objeto de resultado es un JSON sin sobre cuyo primer campo es tipo (NF-e / NFC-e / CT-e / DC-e / NFS-e), usado por los eventos de autorización, rechazo y cancelación de cada documento; no tiene event_id, deduplique por la cabecera. El sobre de evento (version / event_id / event_type / occurred_at / data) lo usan invoice.canceled, invoice.cce.registered, invoice.verify.completed, cte.event.registered, los eventos nfse.inbound.* y email.sent / email.failed. Los campos sin valor aparecen como null.
Objeto de resultado de la NF-e
Eventos invoice.authorized e invoice.rejected. En el rechazo los enlaces, la fecha de autorización y el protocolo quedan vacíos.
{"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 de documento |
empresaId* | string | Identificador de la empresa |
nfeId* | string | Id de la factura |
nfeStatus* | string | Resultado |
nfeMotivoStatus | string | Motivo del rechazo |
nfeLinkDanfe | string | Enlace de la DANFE |
nfeLinkXml | string | Enlace del XML autorizado |
nfeNumero | string | Número de la factura |
nfeSerie | string | Serie |
nfeChaveAcesso | string | Clave de acceso |
nfeDataEmissao* | string | Fecha de emisión |
nfeDataAutorizacao | string | Fecha de autorización |
nfeNumeroProtocolo | string | Protocolo de autorización |
nfeDigestValue | string | Resumen de la firma |
* Campo obligatorio
Objeto de resultado de la NFS-e
Eventos nfse.authorized, nfse.rejected, nfse.canceled, nfse.cancel_requested, nfse.cancel_denied y nfse.substituted; el nfseStatus de cada uno está en la enumeración.
{"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 de documento |
empresaId* | string | Identificador de la empresa |
nfseId* | string | Id de la nota |
nfseStatus* | string | Resultado |
nfseMotivoStatus | string | Motivo |
nfseLinkDanfse | string | Enlace de la DANFSe |
nfseLinkXml | string | Enlace del XML oficial |
nfseNumero | string | Número de la NFS-e |
nfseSerie | string | Serie |
nfseChaveAcesso | string | Clave de acceso |
nfseIdentificacaoDps | string | Identificador de la DPS |
nfseDataEmissao* | string | Fecha de emisión |
nfseDataAutorizacao | string | Fecha de autorización |
nfseNumeroProtocolo | string | Protocolo de la autoridad |
nfseAtualizadoEm* | string | Momento de este cambio de estado |
nfseChaveSubstituta*solo en nfse.substituted | string | Clave de la nota sustituta |
* Campo obligatorio
Objeto de resultado del CT-e
Eventos cte.authorized, cte.rejected y cte.canceled. Un fallo final del lado de la plataforma no genera callback; use la consulta del 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 de documento |
empresaId* | string | Identificador de la empresa |
cteId* | string | Id del CT-e |
cteStatus* | string | Resultado |
cteMotivoStatus | string | Motivo del rechazo |
cteLinkDacte | string | Enlace del DACTE |
cteLinkXml | string | Enlace del XML autorizado |
cteNumero | string | Número del documento |
cteSerie | string | Serie |
cteChaveAcesso | string | Clave de acceso |
cteDataEmissao* | string | Fecha de emisión |
cteDataAutorizacao | string | Fecha de autorización |
cteNumeroProtocolo | string | Protocolo de autorización |
cteDigestValue | string | Resumen de la firma del XML autorizado |
* Campo obligatorio
Objeto de resultado del DC-e
Eventos dce.authorized, dce.rejected, dce.canceled y dce.cancel_rejected. Un fallo antes de la numeración también llega como dce.rejected, con los campos del documento en 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 de documento |
empresaId* | string | Identificador de la empresa |
dceId* | string | Id del DC-e |
dceStatus* | string | Resultado |
dceMotivoStatus | string | Motivo |
dceLinkDace | string | Enlace del DACE |
dceLinkXml | string | Enlace del XML autorizado |
dceNumero | string | Número del documento |
dceSerie | string | Serie |
dceChaveAcesso | string | Clave de acceso |
dceDataEmissao* | string | Fecha de emisión |
dceDataAutorizacao | string | Fecha de autorización |
dceNumeroProtocolo | string | Protocolo |
dceDigestValue | string | Resumen de la firma del XML autorizado |
* Campo obligatorio
Sobre de evento
Ejemplo de invoice.canceled: data trae invoice_id, chave y protocolo. En cte.event.registered, data trae event_code, n_seq y protocolo; en invoice.cce.registered (reservado, aún no enviado), invoice_id, chave y 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 | Versión del sobre |
event_id* | string | Id del evento |
event_type* | string | Código del evento |
occurred_at* | string | Momento del evento |
data* | object | Datos del evento |
* Campo obligatorio
Datos de NFS-e recibida
nfse.inbound.received, nfse.inbound.canceled y nfse.inbound.substituted exigen suscripción explícita. Los tres llevan inbound_id, chave y prestador_doc; el ejemplo es el de llegada.
{"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 de la nota recibida en la plataforma |
chave* | string | Clave de acceso |
prestador_doc* | string | Documento del prestador |
n_nfse*solo en nfse.inbound.received | string | Número de la NFS-e |
valor_servico*solo en nfse.inbound.received | string | Valor del servicio |
competencia*solo en nfse.inbound.received | string | Competencia |
evento*solo en nfse.inbound.canceled | string | Código oficial del evento de cancelación |
chave_substituta*solo en nfse.inbound.substituted | string | Clave de la nota sustituta |
* Campo obligatorio
Datos de manifestación
nfse.inbound.manifested llega cuando la manifestación fue registrada; nfse.inbound.manifest_failed cuando la tarea falló, así que repita la manifestación antes del plazo de confirmación tácita. Ambos exigen suscripción explícita; el ejemplo es el de éxito.
{"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*solo en nfse.inbound.manifested | string | Id de la nota recibida en la plataforma |
chave* | string | Clave de acceso |
tipo* | string | Tipo de manifestación |
evento*solo en nfse.inbound.manifested | string | Código oficial del evento registrado |
codigo_motivo*solo en nfse.inbound.manifested | string | Código del motivo del rechazo |
motivo* | string | Motivo |
protocolo*solo en nfse.inbound.manifested | string | Protocolo de la autoridad |
codigo*solo en nfse.inbound.manifest_failed | string | Código del fallo |
* Campo obligatorio
Datos del resultado de la verificación
invoice.verify.completed es el único canal que entrega el veredicto final de la verificación de NF-e; la consulta por clave sirve de 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 | Clave de la factura verificada |
validationStatus* | string | Veredicto final |
status* | string | Situación fiscal en la SEFAZ |
cStat | string | Código de retorno de la SEFAZ |
xMotivo | string | Descripción de retorno de la SEFAZ |
protocolo | object | Protocolo oficial |
dataAutorizacao | string | Fecha de autorización en la SEFAZ |
eventos* | array | Eventos fiscales registrados |
verifiedAt* | string | Momento de la verificación |
reason*solo en REJECTED / VALIDATION_ERROR | string | Explicación del veredicto |
* Campo obligatorio
Datos del resultado del e-mail de la factura
email.sent llega cuando el servicio de envío aceptó el mensaje; email.failed cuando el correo falló definitivamente (espera agotada, intentos agotados, documento que dejó de estar autorizado). Ambos exigen suscripción explícita y liberan el documento para un nuevo envío; el ejemplo es el de éxito. Vea E-mail de facturas.
{"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 del correo |
id* | string | Identificador de la solicitud |
tipo_documento* | string | Tipo de documento |
documento_id* | string | Identificador de la factura |
chave | string | Clave de acceso |
destinatarios* | array | Destinatarios efectivos |
status* | string | Resultado |
motivo_falha | string | Motivo del fallo |
* Campo obligatorio
eventos[]Códigos de evento
Omitido, suscribe solo invoice.authorized e invoice.rejected. La NFC-e no entra en ese valor por defecto: liste los eventos nfce.* para recibirlos. Los eventos nfse.inbound.* y email.* solo se entregan a quien los lista aquí.
| Valores | Significado |
|---|---|
| invoice.authorized | NF-e autorizada por la SEFAZ; objeto de resultado con nfeStatus = Autorizada |
| invoice.rejected | NF-e rechazada por la SEFAZ; nfeStatus = Negada, motivo en nfeMotivoStatus |
| invoice.canceled | Cancelación de la NF-e registrada en la SEFAZ; sobre con invoice_id, chave y protocolo |
| invoice.cce.registered | Carta de corrección de la NF-e registrada; reservado, aún no enviado |
| invoice.verify.completed | Veredicto final de la verificación de NF-e; sobre con validationStatus |
| cte.authorized | CT-e autorizado; cteStatus = Autorizada |
| cte.rejected | CT-e rechazado por la SEFAZ; cteStatus = Negada |
| cte.canceled | Cancelación del CT-e registrada; cteStatus = Cancelada |
| cte.event.registered | Otro evento del CT-e registrado (carta de corrección, comprobante de entrega, desacuerdo); sobre con event_code, n_seq y protocolo |
| dce.authorized | DC-e autorizado; dceStatus = Autorizada |
| dce.rejected | DC-e rechazado por la SEFAZ o fallo final de la emisión; dceStatus = Negada |
| dce.canceled | Cancelación del DC-e registrada; dceStatus = Cancelada |
| dce.cancel_rejected | Cancelación del DC-e rechazada por la SEFAZ o fallo final de la tarea; dceStatus = CancelamentoNegado, el documento sigue autorizado |
| nfce.authorized | NFC-e autorizada, incluida la nota offline autorizada tras la transmisión; objeto de resultado con tipo = NFC-e y nfeStatus = Autorizada |
| nfce.rejected | NFC-e rechazada por la SEFAZ o fallo del lado de la plataforma, incluida la nota offline rechazada en la transmisión; nfeStatus = Negada |
| nfce.canceled | Cancelación de la NFC-e registrada, incluida la cancelación por sustitución; nfeStatus = Cancelada |
| nfce.cancel_rejected | Cancelación de la NFC-e rechazada por la SEFAZ; nfeStatus = CancelamentoNegado, la nota sigue autorizada |
| nfce.contingency_issued | NFC-e emitida offline con la SEFAZ caída; nfeStatus = ContingenciaPendente, la transmisión posterior genera nfce.authorized o nfce.rejected |
| nfse.authorized | NFS-e emitida con éxito; nfseStatus = Autorizada |
| nfse.rejected | NFS-e rechazada por la autoridad o fallo del lado de la plataforma; nfseStatus = Negada |
| nfse.canceled | Cancelación de la NFS-e concluida, incluida la análisis concedida; nfseStatus = Cancelada |
| nfse.cancel_requested | Solicitud de análisis de cancelación aceptada; nfseStatus = EmProcessoDeCancelamento |
| nfse.cancel_denied | Cancelación no concluida y la nota sigue autorizada: rechazo síncrono, reintentos agotados o análisis denegada; nfseStatus = Autorizada |
| nfse.substituted | NFS-e sustituida por otra; nfseStatus = Substituida, más nfseChaveSubstituta |
| nfse.inbound.received | NFS-e recibida llegó, empresa como tomadora o intermediaria; sobre, suscripción explícita |
| nfse.inbound.canceled | NFS-e recibida cancelada; sobre, suscripción explícita |
| nfse.inbound.substituted | NFS-e recibida sustituida; sobre, suscripción explícita |
| nfse.inbound.manifested | Manifestación de esta empresa registrada, confirmación o rechazo; sobre, suscripción explícita |
| nfse.inbound.manifest_failed | Manifestación de esta empresa falló; repita antes de la confirmación tácita; sobre, suscripción explícita |
| email.sent | E-mail de la factura entregado al servicio de envío; sobre con data.status = Enviado, suscripción explícita |
| email.failed | E-mail de la factura falló definitivamente; sobre con data.status = Falha y data.motivo_falha, suscripción explícita |
nfeStatusResultado de la NF-e
| Valores | Significado |
|---|---|
| Autorizada | Autorizada por la SEFAZ |
| Negada | Rechazada por la SEFAZ |
nfseStatusResultado de la NFS-e
| Valores | Significado |
|---|---|
| Autorizada | Emitida (nfse.authorized) o cancelación rechazada (nfse.cancel_denied) |
| Negada | Rechazada o fallo de la plataforma (nfse.rejected) |
| Cancelada | Cancelada (nfse.canceled) |
| EmProcessoDeCancelamento | Análisis de cancelación en curso (nfse.cancel_requested) |
| Substituida | Sustituida por otra nota (nfse.substituted) |
cteStatusResultado del CT-e
| Valores | Significado |
|---|---|
| Autorizada | Autorizado (cte.authorized) |
| Negada | Rechazado por la SEFAZ (cte.rejected) |
| Cancelada | Cancelado (cte.canceled) |
dceStatusResultado del DC-e
| Valores | Significado |
|---|---|
| Autorizada | Autorizado (dce.authorized) |
| Negada | Rechazado o fallo final de la emisión (dce.rejected) |
| Cancelada | Cancelado (dce.canceled) |
| CancelamentoNegado | Cancelación rechazada, el documento sigue autorizado (dce.cancel_rejected) |
data.validationStatusVeredicto de la verificación
| Valores | Significado |
|---|---|
| VALIDATED | Nota válida; puede liberar |
| REJECTED | Nota inválida según la SEFAZ; reason lo explica |
| VALIDATION_ERROR | Fallo de la verificación del lado de la plataforma, no es veredicto sobre la nota; reenvíe con forceRevalidate |
data.statusResultado del e-mail de la factura
| Valores | Significado |
|---|---|
| Enviado | Entregado al servicio de envío (email.sent); el documento acepta un nuevo envío |
| Falha | Fallo definitivo (email.failed); motivo_falha lo explica y el documento acepta un nuevo envío |
| Código | HTTP | |
|---|---|---|
| 10009033 | 400 | Registro inválido: id no pertenece a la aplicación, contentType distinto de application/json o código desconocido en eventos; el mensaje indica cuál. |
| 10001001 | 400 | Falló la validación de campos: uri o token vacío o por encima del tamaño, token con un carácter fuera del ASCII visible (espacio, letra acentuada, salto de línea), eventos con un ítem en blanco o más de 64 ítems. |
