Quickstart: de cero a firma en 5 pasos
Vas a crear tu primer documento, enviarlo a firma y firmarlo en el sandbox,
sin cobros ni correos reales. Todo corre contra https://api.allsign.io/v3 con una key de prueba
(prefijo allsign_test_sk_ o allsign_dev_sk_, según tu panel): los documentos se crean, los firmantes existen y los webhooks se
disparan, pero nada sale al mundo real. La base URL es la misma en sandbox y en
producción — la key decide el entorno (ver Entornos). Cuando tu
integración funcione aquí, solo cambias la key — el contrato es idéntico.
Las respuestas de esta página son las que dio la API en la última corrida de sus tests, en el entorno interno de AllSign con una key de sandbox. La receta Lleva tu primer documento a firma hace este mismo recorrido paso a paso, en cURL, Node y Python.
Grabado en el entorno interno de AllSign con una key de sandbox · backend 24c0469 · · test docs-checks-v3/tests/ejemplos/usuarios.ejemplos.spec.ts
Paso 1 · Obtén tu API key de prueba
Entra a tu panel de AllSign, ve a Developers → API Keys y genera una key de
entorno de prueba. Reconócela porque el prefijo no es
live: allsign_test_sk_ o allsign_dev_sk_ (según tu panel) —
ambas operan en sandbox. Guárdala como secreto (nunca la subas a
tu repo ni la pegues en el front); se envía en cada petición como Authorization: Bearer.
# Guárdala en una variable de entorno, no en el código
export ALLSIGN_API_KEY="allsign_test_sk_tu_key_de_prueba"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_…").
Paso 2 · Verifica tu conexión y registra tu webhook
Antes de crear nada, confirma que tu key es válida con una llamada barata:
GET /v3/users/me. Devuelve tu usuario y tu tenant. Este endpoint es tu ping de
autenticación:
- 200 — la key sirve; ya estás dentro.
- 401
AUTHENTICATION_REQUIRED— falta la key o está mal escrita.
/v3/users/me nunca responde 403: cualquier key
autenticada puede leer su propio usuario, sin importar sus scopes. Si ves 403 aquí, es un bug, no un
problema de permisos.
curl https://api.allsign.io/v3/users/me \
-H "Authorization: Bearer $ALLSIGN_API_KEY" \
-H "AllSign-Version: 2026-07-11"{
"livemode": false,
"id": "usr_1fac1e055ae544ac9f9620b42b5ad98d",
"email": "ana@ejemplo.com",
"fullName": "Ana Torres",
"tenantId": "ten_0831aa4e33224c3bbc71f396d736d34c",
"orgId": "org_8f4afda0323e478985538d5ccee18821",
"scopes": [
"document:read",
"document:write",
"document:delete",
"signature:read",
"webhook:read",
"webhook:write",
"webhook:delete",
"constancia:read",
"constancia:write",
"embedded:write",
"analytics:read",
"user:read"
],
"environment": "test",
"authMode": "api_key"
}
Registra tu endpoint de webhooks
Para enterarte de cada firma y del cierre sin consultar en bucle, registra una URL HTTPS pública de
tu servidor con POST /v3/webhooks y los eventos que quieres recibir. Hazlo antes de enviar
el documento: el paso 5 espera los avisos en este endpoint.
curl https://api.allsign.io/v3/webhooks \
-H "Authorization: Bearer $ALLSIGN_API_KEY" \
-H "AllSign-Version: 2026-07-11" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{
"url": "https://tu-servidor.com/webhooks/allsign",
"events": ["signer.signed", "document.completed"]
}'{
"livemode": false,
"id": "whe_faed666bbdc5444693acfac1655160a6",
"object": "webhook_endpoint",
"url": "https://ejemplo.com/webhooks/allsign",
"events": [
"signer.signed",
"document.completed"
],
"description": "Mi primer contrato",
"status": "enabled",
"apiVersion": "2026-07-11",
"environment": "test",
"secretLast4": "S5w=",
"createdAt": "2026-07-11T18:00:00.000000Z",
"secret": "whsec_…"
}
Guarda el secret (whsec_…): solo viene en esta respuesta y con él verificas
cada entrega.
Paso 3 · Crea un documento con sus firmantes
Un documento nace en estado draft: existe, pero todavía no se envía a nadie. Lo creas
con POST /v3/documents y, en la misma petición, le dices quién firma con
signers[]: cada firmante lleva name y un canal de contacto,
email o phone (para invitación por WhatsApp). Los firmantes
se adjuntan al crear: la API v3 no tiene una operación para agregarlos después, así que un documento
creado sin signers[] no se puede enviar.
El documento sale de una de dos fuentes (source):
source | Qué mandas | Notas |
|---|---|---|
template |
templateId + templateValues (los valores de las variables) |
El más rápido: reusas una plantilla ya diseñada. Si la plantilla define roles, agrega
roleName a cada firmante para que herede los campos de su rol. |
file |
El PDF en base64 (content + name) |
El archivo pesa ≤ 10 MB; si lo excedes → 413 DOCUMENT_TOO_LARGE. |
Desde plantilla (rellenas templateValues):
curl https://api.allsign.io/v3/documents \
-H "Authorization: Bearer $ALLSIGN_API_KEY" \
-H "AllSign-Version: 2026-07-11" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{
"source": "template",
"templateId": "tmpl_...",
"name": "Mi primer contrato (sandbox)",
"templateValues": { "arrendatario": "Ana Torres", "monto": "12000" },
"signers": [
{ "name": "Ana Torres", "email": "signer-pending@sandbox.allsign.io" }
]
}'Desde archivo (este comando lee contrato.pdf de tu carpeta y lo manda en base64):
curl https://api.allsign.io/v3/documents \
-H "Authorization: Bearer $ALLSIGN_API_KEY" \
-H "AllSign-Version: 2026-07-11" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d @- <<EOF
{
"source": "file",
"name": "Mi primer contrato (sandbox)",
"file": { "name": "contrato.pdf", "content": "$(base64 < contrato.pdf | tr -d '\n')" },
"signers": [
{ "name": "Ana Torres", "email": "signer-pending@sandbox.allsign.io" }
]
}
EOFsigner-pending@sandbox.allsign.io es un firmante de prueba: no recibe correo y nunca firma
solo. En el paso 4 firmas tú por él.
La respuesta trae el documento en borrador:
{
"livemode": false,
"id": "doc_fdde14eeff0b4444acec4d6b10736068",
"object": "document",
"name": "Mi primer contrato (sandbox)",
"status": "draft",
"documentType": "EDITABLE",
"signerCount": 1,
"signedCount": 0,
"ownerId": "usr_08f394a003014001b429ca03db05b7f7",
"orgId": "f4d8bad5-5bb0-451c-a917-2ae6b489d38f",
"folderId": null,
"expiresAt": null,
"signingOrder": "parallel",
"currentStage": null,
"expirationReminders": null,
"templateId": null,
"templateVersionId": null,
"parentDocumentId": null,
"createdAt": "2026-07-11T18:01:02.144000Z",
"updatedAt": "2026-07-11T18:01:02.144000Z"
}
¿Dónde firma cada quien? Si el documento no trae cajas de firma propias (no
mandas fields[] y la plantilla no las define), AllSign coloca una caja por firmante al pie
de la página 1. En firma simple (sin firma autógrafa en signatureValidation) no se pone
ninguna, porque no hace falta. Para ponerla en otro lugar, manda
fields[] con el email del firmante y un anchorString: un texto
que aparece en tu PDF y junto al que va la firma (detalle en
Create document).
Paso 4 · Envíalo a firma
Con el documento en draft, lo envías con POST /v3/documents/{id}/send.
No hace falta cuerpo: se invita a los firmantes que adjuntaste al crearlo. El documento pasa a
awaiting_signatures y cada firmante queda invitado.
curl -X POST https://api.allsign.io/v3/documents/doc_.../send \
-H "Authorization: Bearer $ALLSIGN_API_KEY" \
-H "AllSign-Version: 2026-07-11" \
-H "Idempotency-Key: $(uuidgen)"{
"livemode": false,
"id": "doc_fdde14eeff0b4444acec4d6b10736068",
"object": "document",
"name": "Mi primer contrato (sandbox)",
"status": "awaiting_signatures",
"documentType": "EDITABLE",
"signerCount": 1,
"signedCount": 0,
"ownerId": "usr_08f394a003014001b429ca03db05b7f7",
"orgId": "f4d8bad5-5bb0-451c-a917-2ae6b489d38f",
"folderId": null,
"expiresAt": null,
"signingOrder": "parallel",
"currentStage": null,
"expirationReminders": null,
"templateId": null,
"templateVersionId": null,
"parentDocumentId": null,
"createdAt": "2026-07-11T18:01:02.144000Z",
"updatedAt": "2026-07-11T18:01:05.421000Z"
}
recipients[] es opcional y solo sirve para invitar a algunos de los
firmantes ya adjuntos (por su email o su phone). No agrega personas: si
nombras a alguien que no es firmante del documento, la respuesta es
422 RECIPIENT_NOT_SIGNER y no se cobra ni se invita a nadie. Repetir send en un
documento ya enviado no vuelve a cobrar y solo invita a quien no tiene una invitación vigente; para
insistirle a quien ya la tiene, usa Remind signer.
¿Por qué ese correo? En sandbox los correos no salen al mundo real, así que un
firmante normal nunca firma — y el paso 5 no llegaría jamás. Por eso usas
signer-pending@sandbox.allsign.io: se queda pendiente, como un firmante real, hasta que
firmas por él. El sandbox tiene tres firmantes mágicos (estilo Twilio; cuándo conviene
cada uno, en Entornos):
| Dirección | Qué hace |
|---|---|
signer-pending@sandbox.allsign.io | No firma solo: espera a que firmes por él. Es el que usa este Quickstart. |
signer-success@sandbox.allsign.io | Firma automáticamente en cuanto recibe la invitación. |
signer-declined@sandbox.allsign.io | Rechaza automáticamente. Dispara el webhook signer.declined. |
Firma por tu firmante (solo en sandbox)
En sandbox no hay nadie del otro lado, así que firmas tú por tu firmante. Primero consulta su id
(sgr_…) con GET /v3/documents/{id}/signers; la respuesta de crear no lo trae.
curl https://api.allsign.io/v3/documents/doc_.../signers \
-H "Authorization: Bearer $ALLSIGN_API_KEY" \
-H "AllSign-Version: 2026-07-11"{
"object": "list",
"data": [
{
"livemode": false,
"id": "sgr_d64e1ca6bcf64eebac2d35da21d23c88",
"object": "signer",
"documentId": "doc_fdde14eeff0b4444acec4d6b10736068",
"email": "signer-pending@sandbox.allsign.io",
"phone": null,
"name": "Ana Torres",
"status": "sent",
"signedAt": null,
"routingOrder": null,
"delivery": null
}
],
"hasMore": false,
"nextCursor": null,
"previousCursor": null,
"limit": null
}
Luego firma por él con
POST /v3/sandbox/signers/{signerId}/sign.
Responde en el momento con el firmante ya signed y, como es el único, el documento queda
completed en la misma llamada.
curl -X POST https://api.allsign.io/v3/sandbox/signers/sgr_.../sign \
-H "Authorization: Bearer $ALLSIGN_API_KEY" \
-H "AllSign-Version: 2026-07-11" \
-H "Idempotency-Key: $(uuidgen)"{
"livemode": false,
"id": "sgr_d64e1ca6bcf64eebac2d35da21d23c88",
"object": "signer",
"documentId": "doc_fdde14eeff0b4444acec4d6b10736068",
"email": "signer-pending@sandbox.allsign.io",
"phone": null,
"name": "Ana Torres",
"status": "signed",
"signedAt": "2026-07-11T18:01:06.969000Z",
"routingOrder": null,
"delivery": null
}
Paso 5 · Recibe el webhook de completado
No hagas polling. Con la firma del paso 4, AllSign le envía a tu endpoint del paso 2 un
signer.signed por esa firma y, como era el último firmante, un document.completed.
El cuerpo es un sobre (envelope) v3: el tipo de evento viaja en eventType
(no event), y el PDF de evidencia llega por URL, nunca embebido inline en
el JSON.
Así llega signer.signed:
{
"data": {
"name": "Mi primer contrato (sandbox)",
"signer": {
"name": "Ana Torres",
"email": "signer-pending@sandbox.allsign.io",
"phone": null,
"signedAt": "2026-07-11T18:01:06.969000Z",
"signerId": "sgr_d64e1ca6bcf64eebac2d35da21d23c88",
"authMethod": "POR_DEFINIR"
},
"documentId": "doc_fdde14eeff0b4444acec4d6b10736068",
"signedCount": 1,
"totalSigners": 1
},
"eventId": "evt_b65f702e300448f9906987d0e9aa0ec0",
"livemode": false,
"tenantId": "d521e797-924d-41c6-be8b-a3dcd62f5b6f",
"eventType": "signer.signed",
"apiVersion": "2026-07-11",
"occurredAt": "2026-07-11T18:01:07.025Z"
}
Y así document.completed:
{
"data": {
"name": "Mi primer contrato (sandbox)",
"nom151": null,
"status": "completed",
"signers": [
{
"name": "Ana Torres",
"email": "signer-pending@sandbox.allsign.io",
"signedAt": "2026-07-11T18:01:06.969000Z",
"signerId": "sgr_d64e1ca6bcf64eebac2d35da21d23c88",
"authMethod": "POR_DEFINIR"
}
],
"documentId": "doc_fdde14eeff0b4444acec4d6b10736068",
"completedAt": "2026-07-11T18:01:08.816000Z",
"evidencePdf": {
"url": "https://api.allsign.io/v3/documents/doc_fdde14eeff0b4444acec4d6b10736068/evidence",
"sha256": "ed345419cea24ebbee27d9226b383468c70176e89b2391c5dec89bd4b7df4682",
"mimeType": "application/pdf",
"sizeBytes": 81606
}
},
"eventId": "evt_118e25115c1c4b0b859b732e5ca40301",
"livemode": false,
"tenantId": "d521e797-924d-41c6-be8b-a3dcd62f5b6f",
"eventType": "document.completed",
"apiVersion": "2026-07-11",
"occurredAt": "2026-07-11T18:01:08.818Z"
}
Tu endpoint debe responder 2xx rápido y, en segundo plano, pedir
data.evidencePdf.url con tu API key. Es GET /v3/documents/{id}/evidence:
curl https://api.allsign.io/v3/documents/doc_.../evidence \
-H "Authorization: Bearer $ALLSIGN_API_KEY" \
-H "AllSign-Version: 2026-07-11"{
"livemode": false,
"documentId": "doc_c18e3aaf505d4e8aa839591f6d38f7b9",
"available": true,
"evidencePdf": {
"url": "<url-firmada>",
"sha256": "8a6bf4a711f5204bcce37981400b4a4030d969b33d24e7f2ad78748ca1e68725"
},
"nom151": null,
"reason": null,
"signedCount": 1,
"totalSigners": 1
}
Responde available: true y, en evidencePdf.url, un enlace temporal para
descargar el PDF con su sha256; mientras el documento no termina, available
es false y reason dice por qué. Verifica la firma del webhook (Standard
Webhooks) antes de confiar en el cuerpo (ver Webhooks).
Qué sigue
- Autenticación — prefijos de key, scopes por recurso y el contrato de errores 401/403.
- Paginación — cómo recorrer listas con cursores opacos.
- Idempotencia — qué POST la requieren y cómo reintentar sin duplicar.
- Errores — el contrato
problem+jsony el catálogo de códigos. - Endpoints de Documents — la referencia completa de cada operación.