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
}

Errores posibles (problem+json): 400 401 403 422 429

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
}

Errores posibles (problem+json): 401 403 422 429

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

application/json · schema DocumentCreateRequest

{
  "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"
}

Errores posibles (problem+json): 400 401 402 403 404 409 413 422 429

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"
}

Errores posibles (problem+json): 400 401 403 404 422 429

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

application/json · schema DocumentUpdateRequest

{
  "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"
}

Errores posibles (problem+json): 400 401 403 404 422 429

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

application/json · schema SendRequest

{
  "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"
}

Errores posibles (problem+json): 400 401 402 403 404 409 422 429

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

application/json · schema VoidRequest

{
  "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"
}

Errores posibles (problem+json): 400 401 403 404 409 422 429

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
}

Errores posibles (problem+json): 400 401 403 404 422 429

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
}

Errores posibles (problem+json): 400 401 403 404 422 429

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"
  }
}

Errores posibles (problem+json): 400 401 403 404 422 429

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
}

Errores posibles (problem+json): 400 401 403 404 409 422 429

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

application/json · schema BulkDeleteRequest

{
  "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."
    }
  ]
}

Errores posibles (problem+json): 401 403 422 429

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

application/json · schema BulkSendRequest

{
  "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
    }
  ]
}

Errores posibles (problem+json): 400 401 402 403 409 413 422 429

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
    }
  ]
}

Errores posibles (problem+json): 400 401 403 404 422 429