# Webhooks > Cómo recibir notificaciones en tiempo real de los eventos de tus documentos, y cómo verificar que vienen de Legaldoc. Los webhooks son notificaciones HTTP que Legaldoc.io envía a una URL de tu elección cada vez que ocurre un evento sobre un documento o plantilla — sin que tengas que consultar la API periódicamente para saber si algo cambió. Casos de uso típicos: sincronizar el estado de un documento con tu base de datos, disparar un flujo automatizado cuando se completa una firma, o integrar Legaldoc con tu CRM u otros sistemas de terceros. ## Cómo funcionan 1. Configuras una URL de webhook en Legaldoc. 2. Cuando ocurre un evento, Legaldoc envía un `POST` a esa URL con el tipo de evento y los datos del documento. 3. Tu servidor procesa el evento y responde `200 OK`. ## Eventos disponibles ### Eventos de documento | Evento | Se dispara cuando... | |---|---| | `DOCUMENT_CREATED` | Se crea un nuevo documento. | | `DOCUMENT_SENT` | El documento se envía a los destinatarios. | | `DOCUMENT_OPENED` | Un destinatario abre el documento por primera vez. | | `DOCUMENT_SIGNED` | Un destinatario firma. Se dispara por cada firma individual, no solo al completarse. | | `DOCUMENT_RECIPIENT_COMPLETED` | Un destinatario completa su acción requerida (firmar, aprobar o visar). | | `DOCUMENT_COMPLETED` | Todos los destinatarios completaron su acción. | | `DOCUMENT_REJECTED` | Un destinatario rechaza el documento. | | `DOCUMENT_CANCELLED` | El dueño del documento lo cancela o elimina. | | `DOCUMENT_REMINDER_SENT` | Se envía un recordatorio a un destinatario pendiente. | ### Eventos de plantilla | Evento | Se dispara cuando... | |---|---| | `TEMPLATE_CREATED` | Se crea una nueva plantilla. | | `TEMPLATE_UPDATED` | Se modifica una plantilla (configuración, destinatarios o campos). | | `TEMPLATE_DELETED` | Se elimina una plantilla. | | `TEMPLATE_USED` | Se crea un documento a partir de una plantilla — se dispara junto con `DOCUMENT_CREATED`. | Para el flujo de firma estándar, los eventos que casi siempre te interesan son `DOCUMENT_COMPLETED` y `DOCUMENT_REJECTED` — ver [Guía de Integración](/guides/integration-guide/#5-saber-cuándo-terminó). El resto sirve para trazabilidad más fina, por ejemplo notificar a un usuario interno cuando un destinatario específico firma dentro de un flujo secuencial con varios firmantes. Puedes suscribirte a todos los eventos o solo a los que necesites. ## Estructura del payload Toda notificación comparte esta forma: ```json { "event": "DOCUMENT_COMPLETED", "payload": { /* documento o plantilla, con sus destinatarios */ }, "createdAt": "2024-04-22T11:52:18.277Z", "webhookEndpoint": "https://tu-servidor.com/webhooks/legaldoc" } ``` | Campo | Descripción | |---|---| | `event` | Identificador del tipo de evento — uno de los listados arriba. | | `payload` | El documento o plantilla afectado, incluyendo su lista de destinatarios y el estado actual de cada uno. | | `createdAt` | Fecha y hora en que se generó la notificación. | | `webhookEndpoint` | La URL a la que se está entregando esta notificación. | Dentro de `payload`, cada destinatario trae su propio estado: `signingStatus` (`NOT_SIGNED`, `SIGNED`, `REJECTED`), `readStatus` (`NOT_OPENED`, `OPENED`) y, si rechazó, `rejectionReason`. El detalle completo de cada recurso está en la [Referencia de la API](/api/). ## Configurar un webhook Desde la configuración de tu cuenta o equipo, en la sección de Webhooks: 1. Indica la **URL** que va a recibir las notificaciones (debe ser HTTPS). 2. Elige a qué **eventos** te quieres suscribir. 3. Define, opcionalmente, un **secreto** — lo vas a necesitar para verificar la autenticidad de cada notificación (ver más abajo). Tu endpoint debe cumplir estos requisitos: | Requisito | Detalle | |---|---| | Protocolo | HTTPS | | Método | Acepta `POST` | | Content-Type | `application/json` | | Respuesta | `2xx` dentro de 30 segundos | | Disponibilidad | Accesible públicamente desde internet | Para desarrollo local, expón tu servidor con un túnel (por ejemplo [ngrok](https://ngrok.com)) para poder recibir notificaciones reales mientras pruebas. ## Verificar la autenticidad Si configuraste un secreto, cada notificación incluye el header `X-Legaldoc-Secret` con ese valor: ```http POST /webhooks/legaldoc HTTP/1.1 Content-Type: application/json X-Legaldoc-Secret: tu_secreto_configurado {"event": "DOCUMENT_COMPLETED", "payload": { /* ... */ }} ``` Antes de procesar cualquier notificación, compara ese header contra tu secreto guardado usando una comparación de tiempo constante (no `===` ni `==`), para no filtrar información del secreto a través de variaciones en el tiempo de respuesta: ```javascript const crypto = require('crypto'); function esValida(secretoRecibido, secretoEsperado) { if (!secretoEsperado) return true; // sin secreto configurado if (!secretoRecibido) return false; try { return crypto.timingSafeEqual( Buffer.from(secretoRecibido), Buffer.from(secretoEsperado), ); } catch { return false; // largos distintos } } app.post('/webhooks/legaldoc', (req, res) => { const secreto = req.headers['x-legaldoc-secret']; if (!esValida(secreto, process.env.LEGALDOC_WEBHOOK_SECRET)) { return res.status(401).json({ error: 'Firma inválida' }); } const { event, payload } = req.body; // procesar el evento... res.status(200).json({ received: true }); }); ``` Si la verificación falla, responde `401` sin detallar el motivo y registra el intento para monitoreo — nunca proceses el payload de una notificación que no verificó. ## Reintentos Si tu endpoint no responde `2xx` a tiempo, Legaldoc reintenta la entrega con backoff exponencial: | Intento | Espera | |---|---| | 1 | Inmediato | | 2 | 1 minuto | | 3 | 5 minutos | | 4 | 30 minutos | | 5 | 2 horas | Después del quinto intento fallido, la notificación queda marcada como fallida y no se reintenta automáticamente. Por eso conviene diseñar tu handler así: - **Responde rápido**: confirma con `200 OK` de inmediato y procesa el evento de forma asíncrona, en vez de hacer todo el trabajo dentro del mismo request. - **Procesa de forma idempotente**: una misma notificación puede llegar más de una vez (por reintentos, o por un reenvío manual) — que procesarla dos veces no debe causar efectos duplicados en tu sistema. ## Disponibilidad Los webhooks están disponibles para usuarios individuales y equipos.