Webhooks
Reciba eventos de firma en tiempo real a través de HTTP con entregas firmadas por HMAC, reintentos automáticos y una red de seguridad de reproducción desde la consola.
SHA-256 firma de solicitud
Per-webhook secreto, enviado como X-Endorsed-Signature
Tiempo de espera de entrega
Devuelve 2xx dentro de la ventana o el intento falla
Reintentos después del primer intento
60s, 5m, 15m, 1h, luego 6h
Desde la consola de desarrollador
Inspecciona cada intento y repite eventos individuales
Qué puedes hacer con los eventos webhook
Cada transición importante del ciclo de vida emite un evento escrito. Úselos para actualizar sus propios registros sin realizar encuestas.
Activar acciones posteriores
Cuando un sobre esté completamente firmado, actualice su CRM, libere un recurso aprovisionado o envíe una confirmación dentro de su propio producto, todo sin sondear el API.
Sincronizar estado del documento
Mantenga su base de datos sincronizada con el ciclo de vida de la firma: enviado, abierto, firmado, rechazado, vencido, anulado. Un evento por transición, no se requiere bucle de sondeo.
Registro de auditoría y cumplimiento
Alimenta eventos webhook en tu propio almacén de auditoría. Los ID de correlación vinculan cada evento con la solicitud API de origen para una trazabilidad completa.
Reproducir entregas fallidas
Los eventos que agotan la escala de reintentos terminan en una cola de mensajes fallidos que puede inspeccionar en la consola del desarrollador y reproducir intencionalmente.
Webhook referencia de evento
Registre un webhook, elija los eventos que desee y EndorsedSign entrega una carga útil JSON con "evento", "inquilinoId", "marca de tiempo" y "datos". Los nombres de los eventos coinciden con las cadenas que envía en la llamada de creación webhook.
| Tipo de evento | Cuando se dispara | Campos clave de "datos" |
|---|---|---|
| document.created | Subes un documento a través del API | Id de documento, Id de cliente, Id de documento externo |
| document.sent | Enlace de firma enviado al primer destinatario | documentId, customerId, canal |
| document.viewed | El firmante abre el enlace de firma | documentId, firmanteEmail, visto en |
| document.signed | El firmante individual completa su paso | documentId, signerEmail, firmadoEn |
| document.completed | Todas las partes han firmado | documentId, completado en, downloadUrl |
| document.declined | Un firmante rechaza explícitamente | documentId, firmanteEmail, motivo |
| document.expired | El documento llega a su fecha de caducidad sin firmar | documentId, caducado en |
| signing.started | Se canjea el token de sesión de firma | ID de documento, ID de sesión, correo electrónico del firmante |
| signing.completed | La sesión de firma finaliza (firmada o rechazada) | documentId, sessionId, resultado |
| cliente.creado / .actualizado / .eliminado | Mutas un registro de cliente | Id. de cliente, Id. de cliente externo |
| plantilla.creada/.actualizada | Mutas una plantilla | ID de plantilla, nombre |
La lista completa se encuentra en el backend `WEBHOOK_EVENTS`. Agregue o limite suscripciones por webhook: el canal de entrega distribuye una llamada HTTP por punto final registrado.
Verificando firmas webhook (Node.js)
Cada entrega incluye un encabezado `X-Endorsed-Signature`: `t={unix_seconds},v1={hex}`. `v1` es HMAC-SHA256 de`{timestamp}.{rawBody}` usando el secreto devuelto cuando se creó el webhook. Rechazar marcas de tiempo fuera de ±5 minutos. Es posible que `X-Webhook-Signature` aún aparezca en las entregas de prueba del portal de desarrolladores como un alias obsoleto de solo cuerpo; verifique `X-Endorsed-Signature`. Requisitos previos: su secreto webhook en una var env, una ruta Express que mantiene el cuerpo sin procesar. Resultado esperado: las cargas útiles no reconocidas o manipuladas se rechazan con 401 antes de que se ejecute cualquier controlador.
import crypto from 'node:crypto';
import express from 'express';
const WEBHOOK_SECRET = process.env.ENDORSED_WEBHOOK_SECRET!;
const TOLERANCE_SECONDS = 5 * 60;
export function verifyWebhookSignature(
rawBody: string,
header: string | undefined,
nowSeconds = Math.floor(Date.now() / 1000),
): boolean {
if (!header) return false;
let timestamp: number | null = null;
let v1 = '';
for (const part of header.split(',')) {
const eq = part.indexOf('=');
if (eq === -1) continue;
const key = part.slice(0, eq).trim();
const value = part.slice(eq + 1).trim();
if (key === 't' && /^\d+$/.test(value)) timestamp = Number.parseInt(value, 10);
if (key === 'v1' && /^[a-f0-9]{64}$/i.test(value)) v1 = value.toLowerCase();
}
if (timestamp === null || !v1) return false;
if (Math.abs(nowSeconds - timestamp) > TOLERANCE_SECONDS) return false;
const expected = crypto
.createHmac('sha256', WEBHOOK_SECRET)
.update(timestamp + '.' + rawBody)
.digest('hex');
const a = Buffer.from(expected, 'hex');
const b = Buffer.from(v1, 'hex');
return a.length === b.length && crypto.timingSafeEqual(a, b);
}
app.post(
'/webhooks/endorsed',
express.json({ verify: (req, _res, buf) => { (req as any).rawBody = buf.toString('utf8'); } }),
(req, res) => {
const sig = req.header('X-Endorsed-Signature');
if (!verifyWebhookSignature((req as any).rawBody, sig)) {
return res.status(401).send('Invalid signature');
}
res.sendStatus(200);
},
);Devuelve 2xx dentro de los 30 segundos o la entrega se marca como fallida. Los intentos fallidos se vuelven a intentar con la escalera de arriba y se pueden reproducir desde la consola del desarrollador.
Cómo configurar un punto final webhook
- 1
Crea el punto final en tu aplicación
Agregue una ruta que acepte solicitudes POST y devuelva HTTP 200 en 10 segundos. Cualquier respuesta 2xx cuenta como entrega exitosa.
- 2
Registre el punto final en la configuración de su inquilino
Vaya a Administrador → Configuración → Webhooks. Ingrese la URL de su punto final y seleccione los tipos de eventos que desee. Se genera un secreto de firma por punto final.
- 3
Verificar la firma en cada solicitud
Lea `X-Endorsed-Signature`. Vuelva a calcular HMAC-SHA256 sobre `{timestamp}.{rawBody}` y comparación de tiempo constante con `v1` (consulte el ejemplo de código anterior). Rechace un encabezado faltante, un valor hexadecimal incorrecto, una marca de tiempo fuera de ±5 minutos o una discrepancia en HMAC. `X-Webhook-Signature` es un alias obsoleto en algunas entregas de prueba; no lo trate como el contrato activo.
- 4
Devuelve 2xx rápidamente, procesa asíncrono
Reconocer la entrega con 200 en 10 segundos y poner en cola el cuerpo del evento para el procesamiento asíncrono. La consola del desarrollador muestra cada intento (encabezados, cuerpo, estado, tiempo) y le permite reproducir cualquier entrega; no es necesario volver a activar el flujo de firma de origen solo para probar su controlador.
Preguntas comunes
Una carga útil webhook real: documento completado
Cuando todas las partes hayan firmado, EndorsedSign PUBLICA esta carga útil en su punto final registrado. Verifique la firma HMAC, ponga en cola y reconozca con 200.

Conecta tu primer webhook
Reclame una zona de pruebas, registre el punto final en Administrador → Desarrollador → Webhooks e inspeccione o reproduzca cada entrega desde la consola del desarrollador.