Lista los endpoints de webhook de la cuenta
GET /v1/webhooks
Suscripciones de la cuenta. Nunca incluye el secret: se muestra una sola vez, al crear.
Catálogo de eventos suscribibles
| Evento | Qué significa |
|---|---|
cfe.emitido | CFE emitido |
cfe.actualizado | Cambió el estado de un CFE en DGI |
cfe_recibido.creado | Llegó un CFE de otro emisor |
cfe_recibido.actualizado | Cambió un CFE recibido |
reporte_diario.aceptado | Reporte diario aceptado por DGI |
reporte_diario.rechazado | Reporte diario RECHAZADO por DGI |
reporte_diario.error | El reporte diario falló antes de llegar a DGI |
cae.por_vencer | Un CAE está por vencer |
cae.por_agotarse | Un CAE está por agotar su numeración |
certificado.por_vencer | El certificado digital está por vencer |
recurrente.emitido | Se emitió una factura recurrente |
pago.confirmado | El cobro se confirmó: la plata entró |
pago.fallido | El cobro fue rechazado de forma definitiva |
pago.anulado | El cobro se anuló (total o parcialmente) |
pago.facturado | Se emitió el comprobante fiscal del cobro |
pago.pendiente_facturacion | Plata cobrada SIN comprobante |
pago.en_verificacion | Estado AMBIGUO del cobro: puede estar cobrado |
link.anulado | El link de cobro se anuló antes de pagarse |
link.expirado | El link de cobro venció sin pagarse |
suscripcion.cobro_exitoso | Se cobró un período de la suscripción |
suscripcion.cobro_fallido | Declinó el cobro de un período |
suscripcion.cancelada | Se dio de baja la suscripción |
suscripcion.pausada | La suscripción se pausó |
suscripcion.reanudada | La suscripción volvió a cobrar |
tarjeta.enrolada | Se enroló una tarjeta del cliente |
tarjeta.baja | Se dio de baja una tarjeta |
El envelope es { id, tipo, creadoEn, cuentaId, sucursalId, datos } y la firma viaja en X-HostFactura-Signature: t=<epoch>,v1=<hmac_sha256 de "<t>.<cuerpo raw>">. Deduplicá por X-HostFactura-Event-Id: el mismo evento puede entregarse más de una vez.
El payload (datos) de cada tipo está en la extensión x-webhooks de este spec (components/schemas/WebhookEvento_<tipo>), con un ejemplo por evento.
Alcance requerido:
webhooks:gestionar. Si la credencial no lo tiene, la respuesta es403 API_ALCANCE_INSUFICIENTEcon la lista enerror.requerido. Las credenciales creadas antes del modelo de alcances (alcances: null) conservan acceso total.
La empresa sale de la credencial. No hay ningún parámetro ni campo de cuerpo que la elija: cada API_KEY opera sobre su propia
EFacturaCuenta. La ÚNICA excepción es la cabecerax-cuenta-idde una credencial de revendedor, que apunta a una subcuenta de su cartera. Si integrás empresas que no son de tu cartera, usá una API_KEY por empresa.
Revendedores: una credencial de una cuenta proveedora puede operar sobre una subcuenta de su cartera mandando
x-cuenta-id: <uuid de la subcuenta>. Si la subcuenta no está en la cartera, la respuesta es403 API_CUENTA_FUERA_DE_CARTERA.
Autorizaciones
Sección titulada «Autorizaciones »Parámetros
Sección titulada « Parámetros »Parámetros de header
Sección titulada «Parámetros de header »Ejemplo
0199d1b0-0000-7000-8000-000000000000Sólo para credenciales de cuenta proveedora (revendedor). UUID de la subcuenta de la cartera sobre la que se quiere operar: la cuenta efectiva del request pasa a ser esa.
Una credencial que no es de proveedor, o una subcuenta que no está en su cartera, recibe 403 API_CUENTA_FUERA_DE_CARTERA. Sin la cabecera, la cuenta es siempre la de la credencial.
Sucursal contra la que operar, cuando la credencial es global. Si la credencial está fijada a una sucursal y esta cabecera indica otra, la respuesta es 403 API_ACCESS_BRANCH_MISMATCH. Sin la cabecera se asume la casa central.
Punto de emisión dentro de la sucursal resuelta. Obligatorio cuando la sucursal tiene 2 o más puntos activos (400 PUNTO_EMISION_REQUERIDO si falta); con uno solo se selecciona automáticamente.
Respuestas
Sección titulada « Respuestas »Suscripciones de la cuenta
object
Ejemplos
{ "data": [ { "id": "0199d1b0-0000-7000-8000-000000000000", "url": "https://integrador.ejemplo.com/hooks/hostfactura", "eventos": [ "pago.confirmado", "pago.facturado" ], "activo": true, "sucursalId": null } ], "meta": { "total": 1 }}No autenticado. La API_KEY no fue enviada, no es válida o la credencial está desactivada.
Códigos posibles: API_AUTH_HEADER_MISSING, API_AUTH_HEADER_INVALID, API_ACCESS_INVALID.
object
object
Identificador estable del error en SCREAMING_SNAKE_CASE
Mensaje legible en español. No parsearlo: puede cambiar
object
object
Sólo en 403 API_ALCANCE_INSUFICIENTE: alcances que habilitan la operación
UUID de correlación; mismo valor que el header X-Request-ID
Ejemplos
Falta header Authorization
{ "error": { "code": "API_AUTH_HEADER_MISSING", "message": "Se esperaba la cabecera Authorization con esquema Bearer" }, "requestId": "5b2c7c8a-1f6e-4d29-9a0b-7c3a8d1e2f4c"}Secret key inválida o revocada
{ "error": { "code": "API_ACCESS_INVALID", "message": "Acceso no autorizado" }, "requestId": "5b2c7c8a-1f6e-4d29-9a0b-7c3a8d1e2f4c"}El módulo de cobros no está habilitado para esta cuenta, o la credencial no tiene el alcance que la operación exige. Son dos cosas distintas y se corrigen distinto:
| Code | Qué pasó | Cómo se corrige |
|---|---|---|
PAGOS_NO_HABILITADO | La cuenta no tiene el módulo de cobros | Es una habilitación comercial: la hace administración, no se activa desde la API |
API_ALCANCE_INSUFICIENTE | La credencial no tiene el alcance (va en error.requerido) | Editar la credencial en Integraciones → API |
API_CUENTA_FUERA_DE_CARTERA | x-cuenta-id apunta a una cuenta ajena a la cartera | Revisar el UUID de la subcuenta |
Ninguno se arregla reintentando.
object
object
Identificador estable del error en SCREAMING_SNAKE_CASE
Mensaje legible en español. No parsearlo: puede cambiar
object
object
Sólo en 403 API_ALCANCE_INSUFICIENTE: alcances que habilitan la operación
UUID de correlación; mismo valor que el header X-Request-ID
Ejemplos
La cuenta no tiene el módulo de cobros
{ "error": { "code": "PAGOS_NO_HABILITADO", "message": "El módulo de pagos no está habilitado para esta cuenta. Es una habilitación comercial: la hace administración, no se activa desde la API." }, "requestId": "4c5d6e7f-8a9b-4c0d-1e2f-3a4b5c6d7e8f"}Falta el alcance
{ "error": { "code": "API_ALCANCE_INSUFICIENTE", "message": "La credencial de API no tiene ninguno de los alcances necesarios para esta operación (pagos:cobrar)", "requerido": [ "pagos:cobrar" ] }, "requestId": "7a8b9c0d-1e2f-3a4b-5c6d-7e8f9a0b1c2d"}Rate limit excedido. Esperá los segundos del header Retry-After. La cuota va por credencial: 60 req/min en cuentas estándar, 600 en cuentas proveedor.
object
object
Identificador estable del error en SCREAMING_SNAKE_CASE
Mensaje legible en español. No parsearlo: puede cambiar
object
object
Sólo en 403 API_ALCANCE_INSUFICIENTE: alcances que habilitan la operación
UUID de correlación; mismo valor que el header X-Request-ID
Ejemplos
Excediste el rate limit
{ "error": { "code": "API_RATE_LIMITED", "message": "Se superó el límite de requests para esta API key" }, "requestId": "5b2c7c8a-1f6e-4d29-9a0b-7c3a8d1e2f4c"}Headers
Sección titulada «Headers »Ejemplo
42Segundos hasta que se libera la ventana de rate limit
No se pudo verificar la habilitación del módulo (PAGOS_ESTADO_INDETERMINADO), o falta la clave maestra de cifrado de secretos (PAGOS_CLAVE_MAESTRA_AUSENTE). Nada que corregir del lado del integrador: reintentar.
object
object
Identificador estable del error en SCREAMING_SNAKE_CASE
Mensaje legible en español. No parsearlo: puede cambiar
object
object
Sólo en 403 API_ALCANCE_INSUFICIENTE: alcances que habilitan la operación
UUID de correlación; mismo valor que el header X-Request-ID
Ejemplos
No se pudo leer el flag de pagos
{ "error": { "code": "PAGOS_ESTADO_INDETERMINADO", "message": "No se pudo verificar si el módulo de pagos está habilitado para esta cuenta. Reintentá." }, "requestId": "0f4a1c2e-5b6d-4e7f-8a9b-0c1d2e3f4a5b"}Clave maestra ausente
{ "error": { "code": "PAGOS_CLAVE_MAESTRA_AUSENTE", "message": "No está configurada la clave maestra de secretos de pagos" }, "requestId": "0f4a1c2e-5b6d-4e7f-8a9b-0c1d2e3f4a5b"}