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.
Registrar por API (avanzado)
Si necesitas crear webhooks de forma programática (automatización, MCPs, setup multi-tenant), puedes usar la API directamente:
curl -X POST "https://api.allsign.io/v2/webhooks" \
-H "Authorization: Bearer allsign_live_sk_TU_API_KEY_AQUI" \
-H "Content-Type: application/json" \
-d '{
"url": "https://tu-servidor.com/webhooks/allsign",
"events": ["signer.signed", "document.completed"],
"secret": "mi-clave-secreta",
"hmac_enabled": true
}'
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. Incluye el PDF final con evidencia criptográfica.
{
"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": "[PDF en base64 — incluye evidencia criptográfica]",
"mime_type": "application/pdf",
"size_bytes": 245780,
"s3_presigned_url": "https://allsign-documents.s3.amazonaws.com/documentos/550e8400/pdf/evidence_Contrato.pdf?X-Amz-Signature=abc123..."
}
}
La URL pre-firmada (s3_presigned_url) es válida por 24 horas. Si necesitas acceso permanente, descarga el PDF inmediatamente usando pdf.content (base64) o la URL pre-firmada.
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

