Ir al contenido

Webhooks

Ver MarkdownAbrir en ClaudeAbrir en ChatGPT

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.

  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.
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.
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. 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.

Toda notificación comparte esta forma:

{
"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.

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) para poder recibir notificaciones reales mientras pruebas.

Si configuraste un secreto, cada notificación incluye el header X-Legaldoc-Secret con ese valor:

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:

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ó.

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.

Los webhooks están disponibles para usuarios individuales y equipos.