Ir al Panel →

🔔 Webhook de Firmas

Recibe notificaciones HTTP automáticas cuando todos los firmantes completan el proceso de firma biométrica.

MétodoPOST
FormatoJSON
Intentos1 (sin reintentos)
📡Cómo funciona
sequenceDiagram participant B as Tu Backend participant A as API Manyao participant U as Firmantes B->>A: POST /documents (con callback_url) A-->>B: document_uuid + webhook_token U->>A: Proceso de firma biométrica Note over A: Todos los firmantes completaron A->>B: POST callback_url (Authorization: Bearer webhook_token) Note over B: ⚠️ Descarga el PDF y ZIP ANTES de responder 200 B->>A: GET /documents/{uuid}/certificate/download_url B->>A: GET /documents/{uuid}/certificate/download_zip_url B-->>A: HTTP 200 { "received": true } Note over A: 🗑️Planificar purga automática de datos sensibles
Campo download_log_url

URL para descargar el ZIP de trazabilidad WORM con selfies, fotos, analisis biometrico, sesiones y logs de cada firmante. Mismo token Bearer. null si no hay logs disponibles.

⚙️Cómo Activarcallback_url
⚠️ El webhook_token solo se muestra una vez — al crear el documento. Guárdalo en una variable de entorno o almacén de secretos.
Crear documento con callback_url
curl -X POST 'https://api.manyao.pe/v1/documents' \
  -H 'Authorization: Bearer {{token}}' \
  -H 'Content-Type: application/json' \
  -d '{
    "title": "Contrato",
    "content_type": "PDF",
    "content_base64": "JVBERi0x...",
    "content_hash": "sha256:...",
    "signers": [{"dni": "12345678", "doc_type": "dni-pe"}],
    "callback_url": "https://tu-app.com/webhooks/manyao"
  }' 
Respuesta — guarda el webhook_token
{
  "document_uuid": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "webhook_token": "4a7f2b9c1e3d8a0f...",
  "callback_url": "https://tu-app.com/webhooks/manyao"
}
🔐Autenticación del WebhookAuthorization header

Cada notificación incluye el header Authorization: Bearer {webhook_token}. Valida este token antes de procesar el payload.

POST /webhooks/manyao HTTP/1.1
Content-Type: application/json
Authorization: Bearer 4a7f2b9c1e3d8a0f...
X-Manyao-Event: document.completed
Se debe considerar que cuando se crea un documento con v1/documents/ se recibe el webhook_token que no es el mismo que el access_token. Usted debe guardarlo en su plataforma de registro de secretos asociado al webhook_token.
Si recibes un webhook sin el token correcto, responde con HTTP 401 y no proceses el payload.
El WEBHOOK que implemente el cliente DEBE verificar que el token bearer que es enviado por manyao DEBE ser el mismo que se usó para crear el documento, caso contrario DEBERÁ ser rechazado.
📋Eventos
EventoDescripciónEstado
document.completedTodos los firmantes completaron — PDF final generado✅ Implementado
signer.completedUn firmante individual completó su firma🔜 Próximamente
document.expiredEl documento expiró sin completarse🔜 Próximamente
signer.rejectedUn firmante fue rechazado por validación biométrica🔜 Próximamente
📦Payload — document.completed

Evento document.completed — enviado cuando el PDF final ha sido generado:

{
  "event": "document.completed",
  "document_uuid": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "title": "Contrato de Servicios",
  "status": "completed",
  "pdf_hash": "sha256:e3b0c44298fc1c149afb...",
  "signers_completed": 2,
  "signers_total": 2,
  "signers": [
    {
      "id": 1, "dni": "12345678", "doc_type": "dni-pe",
      "status": "completed", "score": 98.5,
      "signed_at": "2026-03-22T10:30:00",
      "verified_name": "JUAN PEREZ GARCIA"
    },
    {
      "id": 2, "dni": "87654321", "doc_type": "dni-pe",
      "status": "completed", "score": 96.2,
      "signed_at": "2026-03-22T10:45:00",
      "verified_name": "MARIA LOPEZ TORRES"
    }
  ],
  "completed_at": "2026-03-22T10:45:01",
  "download_url": "https://api.manyao.pe/v1/documents/a1b2c3d4.../download",
  "download_log_url": "https://api.manyao.pe/v1/documents/a1b2c3d4.../log-download"
}
Campos del payload
CampoTipoDescripción
eventstringSiempre document.completed
document_uuidstringUUID único del documento
titlestringTítulo del documento tal como fue creado
statusstringSiempre completed en este evento
pdf_hashstringHash SHA-256 del PDF firmado (sha256:...). Úsalo para verificar integridad
signers_completedintegerNúmero de firmantes que completaron
signers_totalintegerTotal de firmantes requeridos
signersarrayLista de objetos firmante (ver tabla abajo)
completed_atdatetimeFecha y hora de finalización (ISO 8601)
download_urlstringURL del PDF firmado. Requiere Bearer token del documento
download_log_urlstring | nullURL del ZIP de trazabilidad WORM. Requiere Bearer token. null si no disponible
Objeto signer (dentro del array)
CampoTipoDescripción
idintegerID interno del firmante
dnistringNúmero de documento enviado al crear el firmante
doc_typestringdni-pe, dni-pa o ci-pe
statusstringSiempre completed en este evento
scorefloat | nullPuntuación biométrica 0–100. Valores ≥ 75 son aceptados
signed_atdatetime | nullFecha y hora en que el firmante completó (ISO 8601)
verified_namestring | nullNombre completo verificado por biometría
⬇️Descarga del Documento y Log

El payload incluye download_url (PDF firmado) y download_log_url (ZIP de trazabilidad WORM). Ambas URLs se autentican con el mismo Bearer token con el que se creó el documento.

⚠️ Descarga ANTES de responder HTTP 200. Al confirmar recepción, Manyao programa la purga permanentemente los datos sensibles y el ZIP de trazabilidad.
Descargar el PDF firmado
curl -L '{{download_url}}' \
  -H 'Authorization: Bearer {{access_token}}' \
  -o documento-firmado.pdf
Descargar el log de trazabilidad (ZIP WORM)

El ZIP contiene todos los archivos de auditoría del proceso: hashes, registros de validación biométrica, tiempos y evidencias de cada paso. Es inmutable y puede usarse como prueba legal.

curl -L '{{download_log_url}}' \
  -H 'Authorization: Bearer {{access_token}}' \
  -o trazabilidad.zip
ℹ️ Token de acceso: El access_token es el Bearer token recibido al crear el documento (campo access_token en la respuesta del POST /v1/documents). Guárdalo junto con el webhook_token.
Respuesta y Purga de Datos
⚠️ Descarga el PDF firmado ANTES de responder 200. Una vez respondido, los archivos son eliminados de forma permanente e irrecuperable.
Respuesta esperada
HTTP/1.1 200 OK
Content-Type: application/json

{"received": true}

Al recibir una respuesta HTTP 2xx, Manyao elimina permanentemente todos los datos sensibles: PDF original, imágenes de firma, datos biométricos, fotos del documento y selfies de verificación.

💻Ejemplo Node.js (Express)
app.post('/webhooks/manyao', async (req, res) => {
  // 1. Validar el Bearer token
  const auth = req.headers['authorization'] || '';
  const token = auth.replace('Bearer ', '');
  if (token !== process.env.MANYAO_WEBHOOK_TOKEN) {
    return res.status(401).json({ error: 'Unauthorized' });
  }

  const { event, document_uuid, title, signers, pdf_hash } = req.body;

  if (event === 'document.completed') {
    // IMPORTANTE: descarga el PDF ANTES de responder 200
    await downloadSignedPdf(document_uuid);

    console.log('Documento completado:', title);
    console.log('Firmantes:', signers.map(s => s.verified_name).join(', '));
    console.log('Hash del PDF:', pdf_hash);
  }

  // Responder 200 — confirma recepción y activa la purga en Manyao
  res.status(200).json({ received: true });
});
🐘Ejemplo PHP
// webhooks/manyao.php

// 1. Validar el Bearer token
$auth = $_SERVER['HTTP_AUTHORIZATION'] ?? '';
$token = str_replace('Bearer ', '', $auth);
if ($token !== getenv('MANYAO_WEBHOOK_TOKEN')) {
    http_response_code(401);
    echo json_encode(['error' => 'Unauthorized']);
    exit;
}

$payload = json_decode(file_get_contents('php://input'), true);

if ($payload['event'] === 'document.completed') {
    // IMPORTANTE: descarga el PDF ANTES de responder 200
    downloadSignedPdf($payload['document_uuid']);

    foreach ($payload['signers'] as $signer) {
        // $signer['verified_name'], $signer['score'], $signer['signed_at']
    }
}

// Responder 200 — confirma recepción y activa la purga en Manyao
http_response_code(200);
echo json_encode(['received' => true]);
manyao.pe — Firma digital con validación biométrica