Receta
Varios firmantes, uno después de otro
Objetivo: Un contrato que firma primero la vendedora y después el comprador, con el comprador sin poder firmar antes de su turno.
Grabado en el entorno interno de AllSign con una key de sandbox · backend 24c0469 · · test docs-checks-v3/tests/recetas/varios-firmantes-en-orden.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 Registra tu endpoint de webhooks
POST /webhooks ver en la referencia
Qué haces
Con dos firmantes, cada firma te llega como signer.signed y el cierre como document.completed.
Qué mirar
id="whe_f3ae04f2292e4bb78fc753c4229ba55e"secret="whsec_…"
2 Crea el documento con el orden de firma
POST /documents ver en la referencia
Qué haces
signingOrder: sequential exige routingOrder en cada firmante: la etapa 1 firma primero y la 2 no recibe nada hasta que la 1 termina. Firmantes con el mismo número firman a la vez. Cualquier correo de @sandbox.allsign.io que no sea signer-success@ ni signer-declined@ se queda pendiente y no recibe correo; aquí usamos dos.
Qué mirar en sandbox
id="doc_c0d4a131b744480689aa24b2f39215cf"signingOrder="sequential"signerCount=2
3 Envíalo a firma
POST /documents/{document_id}/send ver en la referencia
Qué haces
Solo la etapa activa recibe su invitación: por ahora, la vendedora.
Qué mirar
status="awaiting_signatures"currentStage=1
En producción
Con una key live el envío consume créditos de tu saldo; en sandbox no se cobra nada.
4 Revisa a quién le toca
GET /documents/{document_id}/signers ver en la referencia
Qué haces
El comprador está en waiting_turn: existe, pero todavía no tiene liga ni puede firmar.
Qué mirar
data.0.status="waiting_turn"data.0.routingOrder=2data.1.status="sent"data.1.routingOrder=1
5 Intenta firmar por el comprador antes de su turno
POST /sandbox/signers/{signer_id}/sign ver en la referencia
Qué haces
Mientras su etapa no abre, nadie firma por el comprador: el orden lo hace cumplir la API, no tu interfaz.
6 Firma por la vendedora (solo en sandbox)
POST /sandbox/signers/{signer_id}/sign ver en la referencia
Qué haces
Al terminar la etapa 1, AllSign abre la 2 e invita al comprador.
Qué mirar
status="signed"signedAt="2026-07-11T18:00:05.610000Z"
En producción
Aquí firma la vendedora desde su correo o WhatsApp. Esta operación solo funciona en sandbox.
7 Recuérdale al comprador que ya le toca
POST /documents/{document_id}/signers/{signer_id}/remind ver en la referencia
Qué haces
La etapa 2 se abrió en la misma llamada en que firmó la vendedora. Si el comprador tarda, recuérdale: le reenvía su invitación. En sandbox ningún mensaje sale a @sandbox.allsign.io: delivered viene en false y nextAllowedAt es el mismo instante.
Qué mirar
delivered=falsenextAllowedAt="2026-07-11T18:00:06.241000Z"
En producción
Le llega de nuevo el correo o el WhatsApp y delivered viene en true. El siguiente recordatorio a esa persona espera 4 horas: antes de nextAllowedAt la API responde 429.
8 Firma por el comprador (solo en sandbox)
POST /sandbox/signers/{signer_id}/sign ver en la referencia
Qué haces
Era la última firma: el documento se cierra y su evidencia se genera.
Qué mirar
status="signed"
En producción
Aquí firma el comprador desde su invitación.
9 Espera el webhook document.completed
POST tu endpoint · evento document.completed
Qué haces
Llega cuando firmó la última etapa y la evidencia ya está lista.
AllSign le hace POST a la URL que registraste, con el evento document.completed. 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.status="completed"
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.
VALIDATION_ERROR · 422 · en el paso 2 (Crea el documento con el orden de firma)
{
"type": "https://allsign.io/developers/docs/errors#VALIDATION_ERROR",
"title": "Validation failed",
"status": 422,
"detail": "One or more fields are invalid.",
"instance": "/v3/documents",
"code": "VALIDATION_ERROR",
"requestId": "req_6a8f96e3b2cc40ffa35ad785489ef781",
"errors": [
{
"code": "INVALID_VALUE",
"detail": "signingOrder='sequential' requires 'routingOrder' on every signer; missing at signers[1]."
}
]
}Grabado en el entorno interno de AllSign con una key de sandbox · backend 24c0469 · · test docs-checks-v3/tests/recetas/varios-firmantes-en-orden.receta.spec.ts
NOT_YOUR_TURN · 409 · en el paso 7 (Recuérdale al comprador que ya le toca)
{
"type": "https://allsign.io/developers/docs/errors#NOT_YOUR_TURN",
"title": "Conflict",
"status": 409,
"detail": "Signer belongs to stage 2 and stage 1 has not finished — nothing to remind yet.",
"instance": "/v3/documents/doc_0b2b0e22e2f74967b71978464dc385c7/signers/sgr_9986142474b44b3782418f09da8b366f/remind",
"code": "NOT_YOUR_TURN",
"requestId": "req_f75b6541f8f540aaa398ccc8c4e240f8",
"reason": "not_your_turn"
}Grabado en el entorno interno de AllSign con una key de sandbox · backend 24c0469 · · test docs-checks-v3/tests/recetas/varios-firmantes-en-orden.receta.spec.ts
Siguiente
- Recuerda, reasigna o anula un documento que nadie firma — Destrabar un documento enviado: recordarle al firmante, pasarle su lugar a otra persona y, si ya no procede, anularlo dejando la razón.
- Recibe y verifica los webhooks de AllSign — 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.