Webhooks
Recibe notificaciones automáticas en tu servidor cuando algo importante sucede en AllSign — sin necesidad de hacer polling. Ideal para actualizar tu sistema cuando un documento se firma o se completa.
¿Cómo funcionan?
- Tú registras una URL de tu servidor como destino de webhooks
- AllSign envía un POST a esa URL cada vez que ocurre un evento relevante
- Tu servidor procesa el evento y responde con
200 OK
Tu servidor ← POST (evento) ← AllSign
Configurar desde el Dashboard
La forma más fácil de crear un webhook es desde el Dashboard de AllSign.
Paso 1: Ir a la sección de Webhooks
Navega a Settings → Developers → Webhooks en el sidebar. Verás la lista de webhooks configurados (o un estado vacío si es tu primer webhook).

Paso 2: Crear un destino de eventos
Haz clic en "Añadir un destino". Se abrirá el formulario de configuración:

Completa los campos:
| Campo | Descripción |
|---|---|
| Nombre del destino | Un nombre descriptivo para identificar este webhook (ej: "Mi integración", "n8n Producción") |
| URL del endpoint | La URL HTTPS de tu servidor que recibirá los eventos |
| Eventos a notificar | Selecciona los eventos que quieres recibir (puedes elegir uno o varios) |
| Secreto | (Opcional) Una clave compartida para verificar que las notificaciones provienen de AllSign |
| Firmar con HMAC-SHA256 | (Requiere secreto) Agrega un header X-AllSign-Signature para verificación criptográfica |
Paso 3: Guardar
Llena los datos y haz clic en "Guardar". Tu webhook quedará activo inmediatamente.

La URL debe comenzar con https://. AllSign no enviará webhooks a endpoints HTTP sin encriptación.
Eventos disponibles
Suscríbete solo a los eventos que necesitas:
Documentos
- Name
document.created- Description
Un nuevo documento fue creado vía API. Incluye información del documento, firmantes configurados y validaciones.
- Name
document.completed- Description
Todos los participantes firmaron — el documento está completo. Incluye el PDF firmado en base64 y una URL pre-firmada de descarga.
- Name
document.expired- Description
El documento alcanzó su fecha límite sin completarse. Incluye resumen de firmantes pendientes.
Firmantes
- Name
signer.signed- Description
Un participante completó su firma. Incluye progreso (cuántos han firmado vs total) y lista de firmantes pendientes.
Onboarding (KYC)
- Name
onboarding.completed- Description
Una sesión de verificación de identidad fue completada exitosamente. Incluye datos extraídos del documento de identidad.
Payloads por evento
Cada evento tiene una estructura de payload específica. A continuación se documenta cada uno tal como lo envía el backend.
Payload: document.created
Se dispara cuando un documento es creado vía la API V2 (POST /v2/documents).
{
"event_id": "evt_550e8400-e29b-41d4-a716-446655440000",
"event": "document.created",
"api_version": "2024-01-01",
"created_at": "2026-01-15T14:30:00+00:00",
"data": {
"document": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"name": "Contrato de servicios",
"created_at": "2026-01-15T14:30:00+00:00",
"created_by": "api",
"api_key_id": "7c9e6679-7425-40de-944b-e07fc1f90ae7"
},
"signers": [
{
"name": "Juan García",
"email": "juan@empresa.com",
"phone": null
}
],
"validations": {
"autografa": true,
"nom151": false,
"identity_verification": {
"enabled": true,
"document_scan": true,
"selfie_capture": true,
"biometric_face_match": false
}
},
"expiration": {
"enabled": true,
"expires_at": "2026-02-15T14:30:00+00:00"
}
}
}
Payload: signer.signed
Se dispara cuando un participante completa su firma. Incluye progreso y firmantes pendientes.
{
"event_id": "evt_a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"event": "signer.signed",
"api_version": "2024-01-01",
"created_at": "2026-01-16T10:00:00+00:00",
"data": {
"document": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"name": "Contrato de servicios"
},
"signer": {
"signature_id": "9a8b7c6d-5e4f-3210-fedc-ba0987654321",
"name": "Juan García",
"email": "juan@empresa.com",
"phone": null,
"signed_at": "2026-01-16T10:00:00+00:00",
"auth_method": "autografa"
},
"progress": {
"completed": 1,
"total": 2,
"pending_signers": [
{
"name": "María López",
"email": "maria@empresa.com",
"phone": null
}
]
}
}
}
Payload: document.completed
Se dispara cuando todos los participantes han firmado y el PDF de evidencia ha sido generado. Incluye el PDF en base64 y una presigned URL de descarga válida por 24 horas.
{
"event": "document.completed",
"document": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"name": "Contrato de servicios",
"all_signed_at": "2026-01-17T09:15:00+00:00"
},
"pdf": {
"content": "JVBERi0xLjQK...",
"mime_type": "application/pdf",
"size_bytes": 204800,
"s3_presigned_url": "https://allsign-documents.s3.amazonaws.com/documentos/550e8400/pdf/evidence_Contrato.pdf?X-Amz-Signature=abc123..."
}
}
La s3_presigned_url es válida por 24 horas. Descarga y archiva el PDF en tu propio storage dentro de esa ventana si necesitas retención a largo plazo. El campo pdf.content contiene el mismo archivo en base64 para procesamiento inmediato.
Para documentos con un solo firmante, document.completed se dispara segundos después de que el firmante termina. Para documentos con múltiples firmantes, se dispara solo cuando el último firma — usa signer.signed (ver arriba) para saber cuándo cada firmante individual termina.
Payload: document.expired
Se dispara cuando un documento alcanza su fecha de expiración sin que todos los participantes hayan firmado.
{
"event_id": "evt_b2c3d4e5-f6a7-8901-bcde-f12345678901",
"event": "document.expired",
"api_version": "2024-01-01",
"created_at": "2026-02-15T14:30:00+00:00",
"data": {
"document": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"name": "Contrato de servicios",
"created_at": "2026-01-15T14:30:00+00:00",
"expired_at": "2026-02-15T14:30:00+00:00"
},
"summary": {
"total": 2,
"signed": 1,
"pending": 1
},
"signers": [
{
"name": "Juan García",
"email": "juan@empresa.com",
"phone": null,
"status": "SIGNED",
"signed_at": "2026-01-16T10:00:00+00:00"
},
{
"name": "María López",
"email": "maria@empresa.com",
"phone": null,
"status": "PENDING",
"signed_at": null
}
]
}
}
Payload: onboarding.completed
Se dispara cuando un usuario completa su verificación de identidad (KYC).
{
"event": "onboarding.completed",
"session_id": "550e8400-e29b-41d4-a716-446655440000",
"target_email": "persona@ejemplo.com",
"target_name": "Juan Pérez",
"result_data": {
"full_name": "Juan Carlos Pérez López",
"curp": "PELJ900101HDFRPN09",
"document_type": "ine"
},
"completed_at": "2026-11-25T18:30:00+00:00"
}
El evento onboarding.completed se envía tanto a los webhooks configurados en el dashboard como al callback_url de la sesión (si se configuró al crearla). Puedes usar uno o ambos mecanismos.
Headers incluidos
Cada notificación incluye estos headers:
| Header | Siempre | Descripción |
|---|---|---|
Content-Type | ✅ | Siempre application/json |
X-AllSign-Event | ✅ | Tipo de evento (ej: document.completed) |
X-AllSign-Timestamp | Solo HMAC | Timestamp ISO-8601 UTC de la solicitud |
X-AllSign-Signature | Solo HMAC | Firma HMAC-SHA256 del payload |
Recibir un webhook
Tu servidor debe responder con 200 OK en menos de 20 segundos.
app.post('/webhooks/allsign', (req, res) => {
const event = req.body.event;
switch (event) {
case 'document.created':
// Payload usa campo "data" con document, signers, validations
const { document, signers } = req.body.data;
console.log(`Documento creado: ${document.name} con ${signers.length} firmantes`);
break;
case 'signer.signed':
// Payload usa campo "data" con signer y progress
const { signer, progress } = req.body.data;
console.log(`${signer.name} firmó — ${progress.completed}/${progress.total}`);
break;
case 'document.completed':
// Payload tiene document y pdf en el nivel raíz
console.log(`Documento completado: ${req.body.document.name}`);
console.log(`PDF disponible: ${req.body.pdf.s3_presigned_url}`);
break;
case 'document.expired':
// Payload usa campo "data" con summary y signers
const { summary } = req.body.data;
console.log(`Documento expirado: ${summary.signed}/${summary.total} firmaron`);
break;
case 'onboarding.completed':
// Payload tiene session_id, target_email, result_data en el nivel raíz
console.log(`KYC completado: ${req.body.target_email}`);
console.log('Datos extraídos:', req.body.result_data);
break;
}
res.status(200).json({ received: true });
});
Seguridad
AllSign ofrece dos modos de seguridad para webhooks. Configúralos desde el Dashboard al crear o editar un webhook.
Modo 1: Secreto simple (sin HMAC)
Si configuras un secreto sin activar HMAC, tu secreto se almacena pero no se firma el payload. Puedes usarlo como referencia interna o comparación manual.
Modo 2: Firma HMAC-SHA256 (recomendado)
Si configuras un secreto y activas la casilla "Firmar con HMAC-SHA256", cada notificación incluye:
X-AllSign-Signature— Firma HMAC-SHA256 del payloadX-AllSign-Timestamp— Timestamp UTC de cuando se generó la firma
La firma se calcula así:
firma = HMAC-SHA256(secreto, "{timestamp}.{json_body}")
Donde {timestamp} es el valor de X-AllSign-Timestamp y {json_body} es el body JSON completo de la solicitud.
Verificar la firma en tu servidor
import crypto from 'crypto';
const WEBHOOK_SECRET = process.env.ALLSIGN_WEBHOOK_SECRET;
function verifyAllSignWebhook(req) {
const signature = req.headers['x-allsign-signature'];
const timestamp = req.headers['x-allsign-timestamp'];
if (!signature || !timestamp) return false;
const body = JSON.stringify(req.body);
const signPayload = `${timestamp}.${body}`;
const expected = crypto
.createHmac('sha256', WEBHOOK_SECRET)
.update(signPayload)
.digest('hex');
return crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(expected)
);
}
// Middleware de Express
app.post('/webhooks/allsign', (req, res) => {
if (!verifyAllSignWebhook(req)) {
return res.status(401).json({ error: 'Invalid signature' });
}
// Procesar evento...
res.status(200).json({ received: true });
});
Usar webhooks con n8n
Para recibir webhooks de AllSign en n8n:
-
Crea un nodo Webhook en tu flujo
- Método:
POST - Copia la URL generada por n8n (ej:
https://tu-n8n.com/webhook/abc123) - Pega esta URL al crear tu webhook en el Dashboard de AllSign
- Método:
-
Si activaste HMAC, agrega un nodo Code después del Webhook para verificar la firma:
Nodo Code en n8n
const crypto = require('crypto');
const secret = 'tu-secreto-aqui'; // Usa $env si está configurado
const signature = $input.first().headers['x-allsign-signature'];
const timestamp = $input.first().headers['x-allsign-timestamp'];
const body = JSON.stringify($input.first().json);
const signPayload = `${timestamp}.${body}`;
const expected = crypto
.createHmac('sha256', secret)
.update(signPayload)
.digest('hex');
if (signature !== expected) {
throw new Error('Firma HMAC inválida — solicitud rechazada');
}
// Pasar los datos al siguiente nodo
return $input.all();
- Sin HMAC, simplemente conecta el nodo Webhook al resto de tu flujo — no necesitas verificación adicional.
Tu webhook secret está disponible en el Dashboard. Nunca compartas este valor públicamente.
Buenas prácticas
- Responde rápido — Procesa el evento en background y responde 200 inmediatamente
- Sé idempotente — Puede que recibas el mismo evento más de una vez
- Usa HTTPS — AllSign solo envía webhooks a URLs
https:// - Activa HMAC — Si necesitas verificar la autenticidad de las notificaciones
- Registra todo — Guarda los payloads para debugging

