Documents
Un documento representa un archivo listo para firma electrónica con biometría, anti-deepfake y NOM-151. En la API v3 un solo endpoint (POST /v3/documents) crea el documento a partir de una plantilla o de un PDF subido en base64 — tú eliges la fuente con el campo source.
Todas las respuestas usan camelCase en el wire, ids opacos con prefijo (doc_, tmpl_, fld_, sgr_, evt_) y livemode para distinguir entorno live de test. Los errores siguen problem+json (RFC 9457) con un campo code en UPPER_SNAKE. Las listas paginan por cursor (startingAfter / endingBefore + hasMore) y las respuestas traen headers RateLimit-*.
List documents
GET /documents
Lista tus documentos con paginación por cursor y filtros. El cursor viaja en startingAfter (avanzar) o endingBefore (retroceder); usa el id del último elemento de la página como cursor de la siguiente.
Parámetros
limit query |
Resultados por página (1–100, default 20). |
startingAfter query |
Cursor: devuelve la página que sigue a este id de documento. |
endingBefore query |
Cursor: devuelve la página anterior a este id de documento. |
status query |
Filtra por estado: draft, collecting_data, awaiting_signatures, correcting, processing, completed, expired, voided. |
sort query |
Orden. Solo createdAt / updatedAt, ascendente o descendente con el prefijo -. Valores: createdAt, -createdAt, updatedAt, -updatedAt (default -createdAt). Otro valor es un 422 VALIDATION_ERROR. |
scope query |
Alcance: owner (default), org, tenant, accessible. |
folderId query |
Filtra por carpeta (fld_…). |
search query |
Búsqueda por texto libre en el nombre (1–255 caracteres). |
createdAt[gte] query |
Solo documentos creados en o después de esta fecha (ISO 8601). |
createdAt[lte] query |
Solo documentos creados en o antes de esta fecha (ISO 8601). |
includeTotal query |
Si es true, la respuesta incluye totalCount. Default false (más rápido). |
Ejemplo (cURL)
curl "https://api.allsign.io/v3/documents?status=awaiting_signatures&limit=20" \
-H "Authorization: Bearer allsign_live_sk_..."
Respuestas
200 Sobre de paginación por cursor (object: "list") con objetos Document. — DocumentList
{
"object": "list",
"data": [
{
"object": "document",
"id": "doc_3Nk8sZ2eZvKYlo2C0aBcDeF",
"livemode": true,
"name": "Contrato de arrendamiento 2026.pdf",
"status": "awaiting_signatures",
"documentType": "editable",
"signerCount": 2,
"signedCount": 1,
"ownerId": "usr_1a2b3c4d5e6f7g8h",
"orgId": "org_9i8u7y6t5r4e3w2q",
"folderId": "fld_c0ffeec0ffeec0ff",
"expiresAt": "2026-08-01T23:59:59Z",
"expirationReminders": [
72,
24
],
"createdAt": "2026-07-11T18:04:00Z",
"updatedAt": "2026-07-11T20:15:00Z"
}
],
"hasMore": true,
"limit": 20,
"nextCursor": "doc_3Nk8sZ2eZvKYlo2C0aBcDeF",
"previousCursor": null,
"totalCount": null
}
Get aggregate statistics
GET /documents/stats
Conteos agregados en el mismo scope que GET /documents. Sin rango de fechas, usa los últimos 365 días por default; recentCount siempre son los últimos 7 días dentro de esa ventana, no de todo el histórico. No es un objeto recurso (sin livemode) — es un resumen, como List documents pero contado en vez de listado.
Parámetros
scope query |
Alcance: owner (default), org, tenant, accessible. |
createdAt[gte] query |
Solo cuenta documentos creados en o después de esta fecha (ISO 8601). |
createdAt[lte] query |
Solo cuenta documentos creados en o antes de esta fecha (ISO 8601). |
Ejemplo (cURL)
curl "https://api.allsign.io/v3/documents/stats?scope=tenant" \
-H "Authorization: Bearer allsign_live_sk_..."
Respuestas
200 Los 5 conteos agregados. — DocumentStats
{
"totalDocuments": 128,
"totalCompleted": 94,
"totalPending": 22,
"totalConfiguring": 12,
"recentCount": 7
}
Create document
POST /documents
Crea un documento a partir de una plantilla (source: "template") o de un archivo subido en base64 (source: "file") — nunca ambos. El campo source es un discriminador explícito; si lo omites, se infiere de cuál de templateId / file mandaste, pero cuando lo incluyes debe coincidir con el campo presente. Efectos en entorno live: consume 1 o más créditos, arranca un workflow de Temporal y sube el archivo a S3. Con una key test el documento es livemode: false y no factura.
Cuerpo de la petición
{
"source": "template",
"templateId": "tmpl_7h6g5f4e3d2c1b0a",
"templateValues": {
"nombre_completo": "Juan Pérez",
"monto": "$150,000.00 MXN"
},
"signers": [
{
"email": "juan@ejemplo.com",
"name": "Juan Pérez"
}
]
}
Ejemplo (cURL)
curl "https://api.allsign.io/v3/documents" \
-H "Authorization: Bearer allsign_live_sk_..." \
-H "Content-Type: application/json" \
-d '{
"source": "template",
"templateId": "tmpl_7h6g5f4e3d2c1b0a",
"templateValues": {
"nombre_completo": "Juan Pérez",
"monto": "$150,000.00 MXN"
},
"signers": [
{ "email": "juan@ejemplo.com", "name": "Juan Pérez" }
]
}'
Respuestas
201 Documento creado (mismo shape que Retrieve document). — Document
{
"object": "document",
"id": "doc_5Qr9tA3fZwLZmp3D1bCdEfG",
"livemode": true,
"name": "contrato.pdf",
"status": "draft",
"documentType": "editable",
"signerCount": 1,
"signedCount": 0,
"ownerId": "usr_1a2b3c4d5e6f7g8h",
"orgId": "org_9i8u7y6t5r4e3w2q",
"folderId": null,
"expiresAt": null,
"expirationReminders": null,
"createdAt": "2026-07-12T15:00:00Z",
"updatedAt": "2026-07-12T15:00:00Z"
}
Retrieve document
GET /documents/{document_id}
Consulta un documento por su id.
Parámetros
document_id path · requerido |
ID del documento (doc_…). |
expand query |
Lista separada por comas de sub-recursos a expandir en línea. Si se omite, la respuesta trae solo los campos del propio documento. |
Ejemplo (cURL)
curl "https://api.allsign.io/v3/documents/doc_5Qr9tA3fZwLZmp3D1bCdEfG" \
-H "Authorization: Bearer allsign_live_sk_..."
Respuestas
200 El objeto Document. — Document
{
"object": "document",
"id": "doc_5Qr9tA3fZwLZmp3D1bCdEfG",
"livemode": true,
"name": "Contrato de arrendamiento 2026.pdf",
"status": "awaiting_signatures",
"documentType": "editable",
"signerCount": 2,
"signedCount": 1,
"ownerId": "usr_1a2b3c4d5e6f7g8h",
"orgId": "org_9i8u7y6t5r4e3w2q",
"folderId": "fld_c0ffeec0ffeec0ff",
"expiresAt": "2026-08-01T23:59:59Z",
"expirationReminders": [
72,
24
],
"createdAt": "2026-07-11T18:04:00Z",
"updatedAt": "2026-07-11T20:15:00Z"
}
Update document
PATCH /documents/{document_id}
Merge-patch parcial: solo se modifican los campos que envías. Los únicos campos mutables son name y folderId. Enviar cualquier otro campo (status, ownerId, id, createdAt, …) se rechaza al parsear con 422 VALIDATION_ERROR nombrando el campo ofensor — así se protege un campo inmutable.
Parámetros
document_id path · requerido |
ID del documento (doc_…). |
Cuerpo de la petición
{
"name": "Contrato final v2.pdf",
"folderId": "fld_c0ffeec0ffeec0ff"
}
Ejemplo (cURL)
curl -X PATCH "https://api.allsign.io/v3/documents/doc_5Qr9tA3fZwLZmp3D1bCdEfG" \
-H "Authorization: Bearer allsign_live_sk_..." \
-H "Content-Type: application/json" \
-d '{ "name": "Contrato final v2.pdf", "folderId": "fld_c0ffeec0ffeec0ff" }'
Respuestas
200 El objeto Document actualizado. — Document
{
"object": "document",
"id": "doc_5Qr9tA3fZwLZmp3D1bCdEfG",
"livemode": true,
"name": "Contrato final v2.pdf",
"status": "awaiting_signatures",
"documentType": "editable",
"signerCount": 2,
"signedCount": 1,
"ownerId": "usr_1a2b3c4d5e6f7g8h",
"orgId": "org_9i8u7y6t5r4e3w2q",
"folderId": "fld_c0ffeec0ffeec0ff",
"expiresAt": "2026-08-01T23:59:59Z",
"expirationReminders": [
72,
24
],
"createdAt": "2026-07-11T18:04:00Z",
"updatedAt": "2026-07-12T16:20:00Z"
}
Send document
POST /documents/{document_id}/send
Cobra los créditos, avanza el estado del documento y despacha las invitaciones de firma (email o WhatsApp vía Temporal). Si omites recipients, se invita a los firmantes ya adjuntos al documento; si los incluyes, defines a quién invitar. La idempotencia llega en una fase posterior, así que un reintento ingenuo hoy puede volver a invitar.
Parámetros
document_id path · requerido |
ID del documento (doc_…). |
Cuerpo de la petición
{
"recipients": [
{
"email": "juan@ejemplo.com",
"name": "Juan Pérez"
}
]
}
Ejemplo (cURL)
curl "https://api.allsign.io/v3/documents/doc_5Qr9tA3fZwLZmp3D1bCdEfG/send" \
-H "Authorization: Bearer allsign_live_sk_..." \
-H "Content-Type: application/json" \
-d '{
"recipients": [
{ "email": "juan@ejemplo.com", "name": "Juan Pérez" }
]
}'
Respuestas
200 El Document; su status avanza (típicamente a awaiting_signatures). — Document
{
"object": "document",
"id": "doc_5Qr9tA3fZwLZmp3D1bCdEfG",
"livemode": true,
"name": "Contrato de arrendamiento 2026.pdf",
"status": "awaiting_signatures",
"documentType": "editable",
"signerCount": 1,
"signedCount": 0,
"ownerId": "usr_1a2b3c4d5e6f7g8h",
"orgId": "org_9i8u7y6t5r4e3w2q",
"folderId": null,
"expiresAt": null,
"expirationReminders": null,
"createdAt": "2026-07-12T15:00:00Z",
"updatedAt": "2026-07-12T15:05:00Z"
}
Void document
POST /documents/{document_id}/void
Anula (invalida) un documento. No es un DELETE: la retención NOM-151 conserva el registro, por eso anular es una operación explícita que deja el documento en voided. Puedes incluir una reason opcional. Una anulación legítima puede cancelar cero firmas — el resultado se decide por el status, no por cuántas firmas se cancelaron.
Parámetros
document_id path · requerido |
ID del documento (doc_…). |
Cuerpo de la petición
{
"reason": "Cliente canceló la operación"
}
Ejemplo (cURL)
curl "https://api.allsign.io/v3/documents/doc_5Qr9tA3fZwLZmp3D1bCdEfG/void" \
-H "Authorization: Bearer allsign_live_sk_..." \
-H "Content-Type: application/json" \
-d '{ "reason": "Cliente canceló la operación" }'
Respuestas
200 El Document; su status queda en voided. — Document
{
"object": "document",
"id": "doc_5Qr9tA3fZwLZmp3D1bCdEfG",
"livemode": true,
"name": "Contrato de arrendamiento 2026.pdf",
"status": "voided",
"documentType": "editable",
"signerCount": 2,
"signedCount": 1,
"ownerId": "usr_1a2b3c4d5e6f7g8h",
"orgId": "org_9i8u7y6t5r4e3w2q",
"folderId": null,
"expiresAt": null,
"expirationReminders": null,
"createdAt": "2026-07-11T18:04:00Z",
"updatedAt": "2026-07-12T16:20:00Z"
}
List signers
GET /documents/{document_id}/signers
Lista los firmantes de un documento. Es una colección acotada (no paginada por cursor).
Parámetros
document_id path · requerido |
ID del documento (doc_…). |
Ejemplo (cURL)
curl "https://api.allsign.io/v3/documents/doc_5Qr9tA3fZwLZmp3D1bCdEfG/signers" \
-H "Authorization: Bearer allsign_live_sk_..."
Respuestas
200 Colección acotada (object: "list", hasMore siempre false) con los firmantes. — SignerList
{
"object": "list",
"data": [
{
"object": "signer",
"id": "sgr_a1b2c3d4e5f6a7b8",
"livemode": true,
"documentId": "doc_5Qr9tA3fZwLZmp3D1bCdEfG",
"name": "Juan Pérez",
"email": "juan@ejemplo.com",
"phone": null,
"status": "signed",
"signedAt": "2026-07-11T20:15:00Z"
},
{
"object": "signer",
"id": "sgr_b2c3d4e5f6a7b8c9",
"livemode": true,
"documentId": "doc_5Qr9tA3fZwLZmp3D1bCdEfG",
"name": "María López",
"email": "maria@ejemplo.com",
"phone": null,
"status": "sent",
"signedAt": null
}
],
"hasMore": false,
"nextCursor": null,
"previousCursor": null,
"limit": null
}
List events
GET /documents/{document_id}/events
Lista la bitácora de eventos de un documento (creación, envío, firmas, etc.), paginada por cursor. type es un token del catálogo de eventos con namespace punteado recurso.enPasado (ej. document.created).
Parámetros
document_id path · requerido |
ID del documento (doc_…). |
limit query |
Resultados por página (1–100, default 20). |
startingAfter query |
Cursor: eventos después de este id (evt_…). |
endingBefore query |
Cursor: eventos antes de este id (evt_…). |
Ejemplo (cURL)
curl "https://api.allsign.io/v3/documents/doc_5Qr9tA3fZwLZmp3D1bCdEfG/events?limit=20" \
-H "Authorization: Bearer allsign_live_sk_..."
Respuestas
200 Sobre de paginación por cursor con la bitácora de eventos del documento. — EventList
{
"object": "list",
"data": [
{
"object": "event",
"id": "evt_0a1b2c3d4e5f6a7b",
"livemode": true,
"type": "document.created",
"documentId": "doc_5Qr9tA3fZwLZmp3D1bCdEfG",
"signatureId": null,
"actorType": "api_key",
"success": true,
"message": "Documento creado vía API",
"data": {
"source": "template"
},
"createdAt": "2026-07-12T15:00:00Z"
}
],
"hasMore": false,
"limit": 20,
"nextCursor": null,
"previousCursor": null
}
Get evidence bundle
GET /documents/{document_id}/evidence
Los 2 archivos de respaldo de un documento: el PDF sellado con todas las firmas (evidencePdf) y la constancia de conservación NOM-151 (nom151, null si el documento no es livemode). Ambos son null hasta que todos los firmantes completan — el workflow de Temporal que los genera termina unos segundos después de la última firma, así que haz poll de available en vez de asumir que ya existen justo al completarse el flujo.
Parámetros
document_id path · requerido |
ID del documento (doc_…). |
Ejemplo (cURL)
curl "https://api.allsign.io/v3/documents/doc_5Qr9tA3fZwLZmp3D1bCdEfG/evidence" \
-H "Authorization: Bearer allsign_live_sk_..."
Respuestas
200 El bundle de evidencia — available indica si ya están listos los archivos. — DocumentEvidence
{
"documentId": "doc_5Qr9tA3fZwLZmp3D1bCdEfG",
"available": true,
"evidencePdf": {
"url": "https://evidence.allsign.io/doc_5Qr9tA3fZwLZmp3D1bCdEfG/evidence.pdf?sig=...",
"sha256": "9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08"
},
"nom151": {
"url": "https://evidence.allsign.io/doc_5Qr9tA3fZwLZmp3D1bCdEfG/nom151.pdf?sig=...",
"sha256": "a3f1e0b8c9d2e4f5a6b7c8d9e0f1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9"
}
}
Remind signer
POST /documents/{document_id}/signers/{signer_id}/remind
Reenvía la invitación (email o WhatsApp, según cómo se agregó el firmante) a UN firmante que todavía no completa. Limitado a un recordatorio cada 4 horas por firmante — no lleva Idempotency-Key propio porque este throttle server-side ya cumple ese rol: un reintento dentro de la ventana simplemente responde 429, nunca reenvía dos veces.
Parámetros
document_id path · requerido |
ID del documento (doc_…). |
signer_id path · requerido |
ID del firmante a recordar (sgr_…). |
Ejemplo (cURL)
curl -X POST "https://api.allsign.io/v3/documents/doc_5Qr9tA3fZwLZmp3D1bCdEfG/signers/sgr_b2c3d4e5f6a7b8c9/remind" \
-H "Authorization: Bearer allsign_live_sk_..."
Respuestas
200 Confirmación del recordatorio — incluye nextAllowedAt. — RemindResponse
{
"documentId": "doc_5Qr9tA3fZwLZmp3D1bCdEfG",
"signerId": "sgr_b2c3d4e5f6a7b8c9",
"sentAt": "2026-07-15T14:00:00Z",
"nextAllowedAt": "2026-07-15T18:00:00Z",
"channel": "email",
"delivered": true
}
Bulk delete documents
DELETE /documents/bulk
Elimina hasta 100 documentos en una sola petición. Éxito parcial por diseño (igual que v2): un id mal formado, un id de otro tenant, o un documento en un estado no eliminable (ya firmado o en progreso) falla SOLO ese elemento — nunca todo el lote. Revisa items[].status por cada id, nunca asumas éxito total por un 200.
Cuerpo de la petición
{
"documentIds": [
"doc_3Nk8sZ2eZvKYlo2C0aBcDeF",
"doc_5Qr9tA3fZwLZmp3D1bCdEfG"
]
}
Ejemplo (cURL)
curl -X DELETE "https://api.allsign.io/v3/documents/bulk" \
-H "Authorization: Bearer allsign_live_sk_..." \
-H "Content-Type: application/json" \
-d '{ "documentIds": ["doc_3Nk8sZ2eZvKYlo2C0aBcDeF", "doc_5Qr9tA3fZwLZmp3D1bCdEfG"] }'
Respuestas
200 Resultado por elemento (totalCount/successCount/errorCount/items[]) — mismo vocabulario que Create bulk send. — BulkDeleteResponse
{
"totalCount": 2,
"successCount": 1,
"errorCount": 1,
"items": [
{
"documentId": "doc_3Nk8sZ2eZvKYlo2C0aBcDeF",
"status": "deleted",
"error": null
},
{
"documentId": "doc_5Qr9tA3fZwLZmp3D1bCdEfG",
"status": "error",
"error": "Document is already signed."
}
]
}
Create bulk send
POST /documents/bulk-sends
Sube un PDF una sola vez y crea N documentos independientes, uno por destinatario, cada uno con su propio enlace de firma. Asíncrono: valida todo de forma síncrona (créditos, tamaño de archivo, forma del body) y agenda el trabajo pesado — la respuesta es un 202 con el lote en processing y cada items[].status en pending. Haz poll de GET /documents/bulk-sends/{id} (Get bulk send) hasta que status cambie a completed o partialError. Idempotency-Key es obligatorio: un reintento con la misma key devuelve el MISMO 202 + el mismo id de lote (Idempotency-Replayed: true) en vez de agendar el trabajo dos veces — nunca cobra créditos ni invita dos veces por un retry.
Cuerpo de la petición
{
"name": "Política de privacidad 2026",
"file": {
"content": "JVBERi0xLjQKJcOkw7zDtsO...",
"fileType": "pdf"
},
"recipients": [
{
"email": "ana@ejemplo.com",
"name": "Ana Torres"
},
{
"email": "luis@ejemplo.com",
"name": "Luis Gómez"
}
],
"sendInvites": true
}
Ejemplo (cURL)
curl -X POST "https://api.allsign.io/v3/documents/bulk-sends" \
-H "Authorization: Bearer allsign_live_sk_..." \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{
"name": "Política de privacidad 2026",
"file": { "content": "JVBERi0...", "fileType": "pdf" },
"recipients": [
{ "email": "ana@ejemplo.com", "name": "Ana Torres" },
{ "email": "luis@ejemplo.com", "name": "Luis Gómez" }
]
}'
Respuestas
202 El lote agendado — header Location apunta a Get bulk send; status: "processing", cada item pending. — BulkSendResponse
{
"id": "bat_7NqW4rZpXyBt2eLmQaVh8f",
"livemode": true,
"status": "processing",
"totalCount": 2,
"successCount": 0,
"errorCount": 0,
"items": [
{
"recipientEmail": "ana@ejemplo.com",
"documentId": null,
"status": "pending",
"error": null
},
{
"recipientEmail": "luis@ejemplo.com",
"documentId": null,
"status": "pending",
"error": null
}
]
}
Get bulk send
GET /documents/bulk-sends/{batch_id}
Consulta el resultado de un createBulkSend asíncrono. Usa el MISMO objeto que la respuesta 202 original — status empieza en processing (todos los items pending) y se asienta en completed o partialError una vez que cada destinatario fue intentado.
Parámetros
batch_id path · requerido |
ID del lote (bat_…), del header Location de Create bulk send. |
Ejemplo (cURL)
curl "https://api.allsign.io/v3/documents/bulk-sends/bat_7NqW4rZpXyBt2eLmQaVh8f" \
-H "Authorization: Bearer allsign_live_sk_..."
Respuestas
200 El lote — status/items[] reflejan el progreso más reciente. — BulkSendResponse
{
"id": "bat_7NqW4rZpXyBt2eLmQaVh8f",
"livemode": true,
"status": "completed",
"totalCount": 2,
"successCount": 2,
"errorCount": 0,
"items": [
{
"recipientEmail": "ana@ejemplo.com",
"documentId": "doc_3Nk8sZ2eZvKYlo2C0aBcDeF",
"status": "sent",
"error": null
},
{
"recipientEmail": "luis@ejemplo.com",
"documentId": "doc_5Qr9tA3fZwLZmp3D1bCdEfG",
"status": "sent",
"error": null
}
]
}