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?

  1. Tú registras una URL de tu servidor como destino de webhooks
  2. AllSign envía un POST a esa URL cada vez que ocurre un evento relevante
  3. 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).

Página de webhooks vacía — listo para crear tu primer destino

Paso 2: Crear un destino de eventos

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

Formulario para crear un webhook — nombre, URL, eventos, secreto y HMAC

Completa los campos:

CampoDescripción
Nombre del destinoUn nombre descriptivo para identificar este webhook (ej: "Mi integración", "n8n Producción")
URL del endpointLa URL HTTPS de tu servidor que recibirá los eventos
Eventos a notificarSelecciona 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.

Formulario llenado con datos de ejemplo — listo para guardar


Registrar por API (avanzado)

Si necesitas crear webhooks de forma programática (automatización, MCPs, setup multi-tenant), puedes usar la API directamente:

POST
/v2/webhooks
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..."
  }
}

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"
}

Headers incluidos

Cada notificación incluye estos headers:

HeaderSiempreDescripción
Content-TypeSiempre application/json
X-AllSign-EventTipo de evento (ej: document.completed)
X-AllSign-TimestampSolo HMACTimestamp ISO-8601 UTC de la solicitud
X-AllSign-SignatureSolo HMACFirma HMAC-SHA256 del payload

Recibir un webhook

Tu servidor debe responder con 200 OK en menos de 20 segundos.

POST
/tu-servidor/webhooks
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 payload
  • X-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

POST
Verificación HMAC
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:

  1. 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
  2. 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();
  1. Sin HMAC, simplemente conecta el nodo Webhook al resto de tu flujo — no necesitas verificación adicional.

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

Was this page helpful?