Ir al contenido
Menú

API y webhooks

Crea, envía, sigue y descarga solicitudes de firma desde tu propio software, y recibe avisos cuando cambian.

Actualizada el 15 de octubre de 2026 Ver como Markdown

La API de eSign permite que tu propio software envíe PDF a firmar y descargue el resultado sellado. eSign avisa a tu software (un webhook) cada vez que una solicitud cambia.

Dirección y clave

Todas las llamadas van a tu dirección de eSign seguida de /api/v1, por ejemplo https://esign.sapiensandmachines.com/api/v1, y llevan la clave de API de tu espacio:

HTTP
Authorization: Bearer YOUR_API_KEY
Accept: application/json

Las claves de API pertenecen al espacio, no a una persona, y no vencen. S+M las crea por ti; cada una se muestra una sola vez. Pídenos revocar una clave que ya no uses. Hasta 120 llamadas por minuto.

Envía un documento

POST /envelopes con el PDF y las personas que firman. Agrega send=1 para enviarlo de inmediato. En este ejemplo la clave está en la variable de entorno ESIGN_API_KEY.

Shell
curl -X POST https://esign.sapiensandmachines.com/api/v1/envelopes \
  -H "Authorization: Bearer $ESIGN_API_KEY" -H "Accept: application/json" \
  -F title="Contrato de servicio" \
  -F document=@contrato.pdf \
  -F "recipients[0][key]=cliente" \
  -F "recipients[0][name]=Ana García" \
  -F "recipients[0][email]=ana@example.com" \
  -F "recipients[0][role]=signer" \
  -F locale=es \
  -F send=1
Campo
title Obligatorio, hasta 255 caracteres.
document o document_base64 El PDF (hasta 25 MB, sin contraseña).
recipients[] De 1 a 20 personas: key (tu propio nombre para ella), name, email, role (signer o cc), routing_order (1–20; el mismo número firma a la vez), verification (none o email_code para un código de 6 dígitos por correo).
message Se muestra a los firmantes, hasta 5.000 caracteres.
locale en o es; si no, el idioma de los firmantes de tu espacio.
expires_in_days De 1 a 365; 30 si no se indica.
external_ref Tu propia referencia, para encontrar la solicitud después.
callback_url Adónde enviar los webhooks de esta solicitud, en lugar de la dirección de tu espacio.
send true para enviar ahora; si no, queda como borrador.
fields[] Opcional: coloca los campos por posición en lugar de con marcadores.

Los marcadores del PDF deciden dónde firma cada firmante: @2 en un marcador es el segundo firmante de recipients.

Otras llamadas

Llamada Hace
GET /envelopes Lista las solicitudes; filtra por status o external_ref; per_page hasta 100.
GET /envelopes/{id} Una solicitud, con el estado de cada destinatario.
POST /envelopes/{id}/send Envía un borrador.
POST /envelopes/{id}/void La cancela (reason); no una vez completada.
GET /envelopes/{id}/document El PDF sellado una vez completada (409 antes); su SHA-256 va en el encabezado X-Document-Sha256.
GET /envelopes/{id}/audit El historial, y si su cadena de registros está intacta (chain_intact).

El status de una solicitud es draft, sent, completed, declined, voided o expired. El estado de cada destinatario indica si ya vio o firmó.

Webhooks

eSign envía un POST con JSON al callback_url de la solicitud o, si no hay, a la dirección de webhooks de tu espacio, para:

Evento Cuándo
recipient.viewed Un firmante abrió el documento.
recipient.signed Un firmante firmó.
envelope.completed Todos firmaron; el PDF sellado está listo.
envelope.declined Un firmante lo rechazó.
envelope.expired La solicitud venció.
envelope.voided Se canceló.
JSON
{
  "event": "envelope.completed",
  "occurred_at": "2026-10-15T15:04:05Z",
  "recipient": null,
  "envelope": {
    "id": "…",
    "status": "completed",
    "title": "Contrato de servicio",
    "external_ref": "COT-1042",
    "sealed_sha256": "…",
    "completed_at": "2026-10-15T15:04:05Z",
    "document_url": "…"
  }
}

En los eventos de destinatario, recipient incluye su id, name, email, status, viewed_at, signed_at y, si rechazó, decline_reason.

Responde con cualquier estado 2xx. Si no, eSign lo reintenta a los 10 segundos, 1 minuto, 5 minutos, 15 minutos y 1 hora.

Comprueba que un webhook viene de eSign

Cada webhook lleva X-Esign-Event y X-Esign-Signature: sha256=…, un HMAC-SHA256 del cuerpo sin modificar con tu secreto de webhooks. Calcúlalo y compáralo antes de confiar en el contenido:

PHP
$body = file_get_contents('php://input');
$expected = 'sha256='.hash_hmac('sha256', $body, $webhookSecret);
if (! hash_equals($expected, $_SERVER['HTTP_X_ESIGN_SIGNATURE'] ?? '')) {
    http_response_code(401);
    exit;
}

Errores

Los errores vuelven como JSON con un estado HTTP: 401 si falta la clave o es incorrecta, 403 si el espacio está suspendido, 404 si la solicitud no existe, 409 si pides el documento antes de que esté completado, 422 con los motivos cuando algo de la solicitud está mal (por ejemplo, un marcador para un firmante que no se indicó, o enviar una solicitud que no es un borrador) y 429 si hay demasiadas llamadas.

¿Te resultó útil esta página?

Agregar un comentario (opcional)

Guardamos tu respuesta y tu comentario, nada sobre quién los envió.