Receta
Recibe y verifica los webhooks de AllSign
Objetivo: Un endpoint que recibe los eventos de AllSign, comprueba que de verdad los firmó AllSign y sobrevive a sus propias caídas y a la rotación del secreto.
Grabado en el entorno interno de AllSign con una key de sandbox · backend 24c0469 · · test docs-checks-v3/tests/recetas/recibe-y-verifica-webhooks.receta.spec.ts
Los ejemplos usan $ALLSIGN_API_KEY. Defínela una vez con tu key de sandbox: export ALLSIGN_API_KEY="allsign_test_sk_…" (en PowerShell: $env:ALLSIGN_API_KEY="allsign_test_sk_…").
1 Consulta qué eventos puedes recibir
GET /webhooks/events ver en la referencia
Qué haces
Suscribe tu endpoint solo a los eventos que vas a procesar: cada uno es una llamada a tu servidor.
Qué mirar
data.0.event="document.created"data.0.description="A document was created via the API."
2 Registra tu endpoint
POST /webhooks ver en la referencia
Qué haces
La respuesta trae el secreto whsec_… una sola vez: guárdalo como secreto de tu servidor, nunca en el frontend. Con él vas a comprobar que cada entrega viene de AllSign.
Qué mirar
id="whe_27226709c9124d798a44032672fe2c9a"secret="whsec_…"status="enabled"
3 Crea un documento para que haya un evento
POST /documents ver en la referencia
Qué haces
Cualquier documento sirve: al crearlo, AllSign le avisa a tu endpoint con document.created.
Qué mirar en sandbox
id="doc_8a9708721fb54fcfabc32715b87f5518"
4 Recibe la entrega y verifica su firma
POST tu endpoint · evento document.created
Qué haces
Antes de creerle al cuerpo, verifica la firma: webhook-signature trae v1,<HMAC-SHA256 en base64> de webhook-id.webhook-timestamp.cuerpo crudo, con tu secreto sin el prefijo whsec_ y decodificado de base64. Rechaza timestamps de más de 5 minutos y usa webhook-id para descartar duplicados. Responde 2xx en cuanto la guardes y procésala después.
AllSign le hace POST a la URL que registraste, con el evento document.created. Responde 2xx rápido y, antes de confiar en el cuerpo, verifica la firma: webhook-signature es un HMAC-SHA256 de webhook-id.webhook-timestamp.cuerpo con el secreto del webhook (Webhooks).
Esta entrega llegó de verdad al receptor del test y su firma se verificó con el secreto del webhook.
Qué mirar
eventType="document.created"data.documentId="doc_8a9708721fb54fcfabc32715b87f5518"
En producción
Igual con una key live. La cabecera allsign-livemode y el campo livemode te dicen si el evento es de producción o de sandbox.
5 Registra un endpoint que falla
POST /webhooks ver en la referencia
Qué haces
Para ver qué pasa cuando tu servidor falla, este segundo endpoint de pruebas responde 500 a propósito.
Qué mirar
id="whe_67554d50996d47b9b68963f6cb2fffac"
6 Revisa las entregas que fallaron
GET /webhooks/{webhook_id}/deliveries ver en la referencia
Qué haces
Cada entrega guarda sus intentos en attemptHistory, con el status que respondió tu servidor. Un 5xx, un timeout o un error de red se reintentan con espera creciente durante 3 días, y mientras tanto la entrega sigue en PENDING; un 4xx la deja en FAILED de inmediato, porque AllSign entiende que tu servidor la rechazó a propósito. Tu endpoint recibe los eventos de toda tu cuenta, no solo del documento que acabas de crear, así que esta lista también puede traer entregas de otros documentos. Es lo primero que revisas cuando «no llegan los webhooks».
Qué mirar
data.0.status="PENDING"data.0.attempts=1data.0.attemptHistory.0.statusCode=500data.0.attemptHistory.0.outcome="TRANSIENT"
7 Rota el secreto
POST /webhooks/{webhook_id}/rotate-secret ver en la referencia
Qué haces
Rota en cuanto sospeches que el secreto se filtró. La respuesta trae el secreto nuevo una sola vez; el anterior sigue valiendo 24 horas para que despliegues el cambio sin perder entregas.
Qué mirar
secret="whsec_…"
8 Reintenta la rotación con la misma Idempotency-Key
POST /webhooks/{webhook_id}/rotate-secret ver en la referencia
Reúsa la Idempotency-Key del paso 7: córrelo justo después de ese paso, en la misma terminal o el mismo script.
Qué haces
Si se cae la red y reintentas con la misma llave, no rota dos veces: recibes el mismo secreto y la cabecera Idempotency-Replayed: true.
Qué mirar
secret="whsec_…"
9 Verifica una entrega con el secreto nuevo
POST tu endpoint · evento document.created
Qué haces
Durante esas 24 horas webhook-signature trae dos firmas separadas por espacio, una por secreto. Acepta la entrega si cualquiera cuadra con el secreto que tienes.
AllSign le hace POST a la URL que registraste, con el evento document.created. Responde 2xx rápido y, antes de confiar en el cuerpo, verifica la firma: webhook-signature es un HMAC-SHA256 de webhook-id.webhook-timestamp.cuerpo con el secreto del webhook (Webhooks).
Esta entrega llegó de verdad al receptor del test y su firma se verificó con el secreto del webhook.
Qué mirar
data.documentId="doc_47e66108a3c64e1385ff314c388b7d6b"
10 Borra el endpoint cuando ya no lo uses
DELETE /webhooks/{webhook_id} ver en la referencia
Qué haces
Borrarlo detiene las entregas de inmediato; si solo quieres pausarlo, usa PATCH con disabled: true.
Errores comunes de esta receta
Errores reales que el test de esta receta provocó a propósito en sandbox, sobre sus mismos pasos. Cada uno enlaza a su explicación en Errores.
WEBHOOK_URL_INVALID · 422 · en el paso 2 (Registra tu endpoint)
{
"type": "https://allsign.io/developers/docs/errors#WEBHOOK_URL_INVALID",
"title": "Unprocessable Entity",
"status": 422,
"detail": "The webhook url must be an absolute https:// URL.",
"instance": "/v3/webhooks",
"code": "WEBHOOK_URL_INVALID",
"requestId": "req_b2c680669f144fcc806cb8366bae5594",
"errors": [
{
"field": "url",
"code": "INVALID_VALUE",
"detail": "Must start with https://"
}
]
}Grabado en el entorno interno de AllSign con una key de sandbox · backend 24c0469 · · test docs-checks-v3/tests/recetas/recibe-y-verifica-webhooks.receta.spec.ts
UNKNOWN_EVENT_TYPE · 422 · en el paso 2 (Registra tu endpoint)
{
"type": "https://allsign.io/developers/docs/errors#UNKNOWN_EVENT_TYPE",
"title": "Unprocessable Entity",
"status": 422,
"detail": "One or more event types are not in the v3 catalog.",
"instance": "/v3/webhooks",
"code": "UNKNOWN_EVENT_TYPE",
"requestId": "req_45571c3852cb4ac6bae34f64dc886a28",
"errors": [
{
"field": "events[0]",
"code": "UNKNOWN_EVENT_TYPE",
"detail": "'documento.firmado' is not a valid v3 event type."
}
]
}Grabado en el entorno interno de AllSign con una key de sandbox · backend 24c0469 · · test docs-checks-v3/tests/recetas/recibe-y-verifica-webhooks.receta.spec.ts
WEBHOOK_NOT_FOUND · 404 · en GET /v3/webhooks/whe_54c1d95de8c64a369095bc044665b5b3
{
"type": "https://allsign.io/developers/docs/errors#WEBHOOK_NOT_FOUND",
"title": "Not Found",
"status": 404,
"detail": "No webhook endpoint was found with that id.",
"instance": "/v3/webhooks/whe_54c1d95de8c64a369095bc044665b5b3",
"code": "WEBHOOK_NOT_FOUND",
"requestId": "req_e424fdd005fc4298b0231312f2126597"
}Grabado en el entorno interno de AllSign con una key de sandbox · backend 24c0469 · · test docs-checks-v3/tests/recetas/recibe-y-verifica-webhooks.receta.spec.ts
Siguiente
- Lleva tu primer documento a firma — Un documento firmado de punta a punta en sandbox, con el aviso de cada firma y el de cierre llegando a tu servidor.
- Descarga el PDF firmado y su evidencia — El PDF firmado y el PDF de evidencia de un documento completado, con su huella sha256 para archivarlos.