Templates y documentos
Un template es un contrato Word reutilizable con huecos ({{ variable }}). Un documento es la instancia firmable que se genera al rellenar esos huecos con datos reales. Esta guía explica cuándo usar cada flujo y cómo conectarlos.
Dos flujos, una decisión
Hay exactamente dos formas de crear un documento en AllSign:
| Flujo Template | Flujo PDF directo | |
|---|---|---|
| Cuándo usarlo | Mismo contrato, datos distintos cada vez | Contrato único ya finalizado |
| Archivo de entrada | .docx con {{ variables }} | .pdf listo para firmar |
| Variables dinámicas | ✅ Sí — se rellenan al crear el doc | ❌ No |
| Reutilizable | ✅ Mismo template, N documentos distintos | ❌ Hay que proveer el PDF en cada request |
| Endpoint | POST /v2/documents con templateId | POST /v2/documents con document (base64) |
Los PDFs no se pueden subir como templates — no tienen sintaxis {{ }} por lo que las variables siempre quedarían vacías. Si tienes un PDF listo para firmar, créalo directamente como documento con el campo document en base64.
El flujo template tiene tres pasos. El PDF directo tiene uno. Esta guía cubre el flujo template completo.
Paso 1 — Prepara tu DOCX
Abre tu contrato en Word y reemplaza los datos variables con placeholders entre llaves dobles:
El arrendador {{ arrendador__nombre }}, con RFC {{ arrendador__rfc }},
arrienda el inmueble ubicado en {{ inmueble__direccion }} por
{{ vigencia_meses }} a partir del {{ fecha_inicio }},
con una renta mensual de {{ monto_renta }}.
Convención de nombres: el doble guion bajo (__) separa el rol del campo. AllSign usa esto para agrupar variables por firmante en el dashboard:
| Variable | Rol inferido | Tipo inferido |
|---|---|---|
arrendador__nombre | Arrendador | text |
arrendador__rfc | Arrendador | text |
inmueble__direccion | Inmueble | textarea |
vigencia_meses | — (sin rol) | number |
fecha_inicio | — (sin rol) | date |
monto_renta | — (sin rol) | currency |
Variables con __: se asocian al rol que está antes del guion (ej. arrendador__nombre → rol "Arrendador"). Variables sin __: son datos generales del documento sin firmante asignado.
El tipo se infiere del nombre del campo: palabras como fecha, monto, renta, meses, direccion disparan el tipo correspondiente. Consulta la tabla de inferencia completa.
Los valores en templateValues se inyectan verbatim en el DOCX — AllSign no formatea ni convierte. Si una variable es de tipo currency, pasa el string ya formateado: "$18,500.00 MXN", no 18500. Si una variable es de tipo number, pasa "12 meses", no 12.
Si omites una variable en templateValues, el placeholder aparece literalmente en el PDF — el documento mostrará {{ arrendador__nombre }} como texto. No hay error ni warning. Siempre provee un valor para cada variable listada en variableConfig.
Paso 2 — Sube el template
Una vez que tu DOCX tiene los placeholders, súbelo con POST /v2/templates. El request es multipart/form-data:
curl -X POST https://api.allsign.io/v2/templates \
-H "Authorization: Bearer allsign_live_sk_TU_API_KEY" \
-F "file=@./contrato_arrendamiento.docx" \
-F "name=Contrato de Arrendamiento v1" \
-F "tags=legal,renta" \
-F "category=contratos"
La respuesta incluye el id del template y la lista completa de variables detectadas con su tipo y rol inferidos:
Response (201)
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"name": "Contrato de Arrendamiento v1",
"description": null,
"originalFilename": "contrato_arrendamiento.docx",
"fileType": "docx",
"variables": [
"arrendador__nombre",
"arrendador__rfc",
"inmueble__direccion",
"vigencia_meses",
"fecha_inicio",
"monto_renta"
],
"variableConfig": [
{ "name": "arrendador__nombre", "label": "Nombre", "type": "text", "role": "Arrendador", "required": true, "defaultValue": null },
{ "name": "arrendador__rfc", "label": "Rfc", "type": "text", "role": "Arrendador", "required": true, "defaultValue": null },
{ "name": "inmueble__direccion", "label": "Direccion", "type": "textarea", "role": "Inmueble", "required": true, "defaultValue": null },
{ "name": "vigencia_meses", "label": "Vigencia Meses", "type": "number", "role": null, "required": true, "defaultValue": null },
{ "name": "fecha_inicio", "label": "Fecha Inicio", "type": "date", "role": null, "required": true, "defaultValue": null },
{ "name": "monto_renta", "label": "Monto Renta", "type": "currency", "role": null, "required": true, "defaultValue": null }
],
"tags": ["legal", "renta"],
"category": "contratos",
"aiEditable": true,
"createdAt": "2026-04-28T00:00:00Z"
}
Guarda el id — lo usarás como templateId en el siguiente paso. Usa el array variables para saber exactamente qué claves debes proveer en templateValues.
Paso 3 — Crea el documento
Con el templateId en mano, crea el documento pasando los valores concretos en templateValues. Las claves deben coincidir exactamente con los nombres de variables del template (incluyendo los __):
sendInvitations y startAtStep son inseparables. El backend rechaza con 422 si mandas sendInvitations: true sin startAtStep: 3. Siempre ponlos juntos — o ninguno de los dos.
curl -X POST https://api.allsign.io/v2/documents \
-H "Authorization: Bearer allsign_live_sk_TU_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"templateId": "550e8400-e29b-41d4-a716-446655440000",
"templateValues": {
"arrendador__nombre": "María García López",
"arrendador__rfc": "GALM800101ABC",
"inmueble__direccion": "Av. Lomas 123, Col. Polanco, CDMX",
"vigencia_meses": "12 meses",
"fecha_inicio": "1 de mayo de 2026",
"monto_renta": "$18,500.00 MXN"
},
"participants": [
{ "name": "María García López", "email": "maria@ejemplo.com" },
{ "name": "Carlos Pérez Ruiz", "email": "carlos@ejemplo.com" }
],
"config": { "sendInvitations": true, "startAtStep": 3 }
}'
# Para firmar por WhatsApp en lugar de email:
# { "name": "Carlos Pérez Ruiz", "whatsapp": "+528112345678" }
Response (201)
{
"id": "abc12345-0000-0000-0000-000000000000",
"name": "contrato_arrendamiento.docx",
"pdfHash": "a1b2c3d4e5f6...",
"description": null,
"createdAt": "2026-04-28T12:00:00Z",
"creditsConsumed": 1
}
AllSign descarga el DOCX, inyecta los valores en cada {{ variable }}, lo convierte a PDF y notifica a los firmantes. Todo en la misma llamada síncrona (~5–15 s).
startAtStep: 3 hace que los firmantes entren directamente al paso de firma. Sin él, el documento queda en borrador y los firmantes no pueden firmar.
¿Necesitas posicionar los campos de firma en coordenadas exactas? Agrega un array fields al request con la posición y tipo de cada campo — ver Campos de firma. Sin fields, los firmantes pueden colocar sus propios campos interactivamente al firmar.
Para respuesta inmediata (UIs interactivas, alta concurrencia), usa POST /v2/documents?mode=async — devuelve 202 con un workflowId al instante y procesa el documento en background. Usa el endpoint SSE /v2/documents/workflows/{workflowId}/progress para obtener el id final. Ver POST /v2/documents.
Ejemplo completo
El ciclo completo de un contrato de arrendamiento desde cero:
1. Subes "contrato_arrendamiento.docx" una sola vez
↓
templateId: "550e8400-..."
variables: ["arrendador__nombre", "monto_renta", ...]
2. Cada vez que necesitas un contrato nuevo:
POST /v2/documents {
templateId,
templateValues: { todas las variables del template, con valores ya formateados },
participants: [ ...firmantes ],
config: { sendInvitations: true, startAtStep: 3 }
}
↓
id: "abc123..." ← PDF generado + firmantes notificados por email/WhatsApp
El template vive en AllSign para siempre (o hasta que lo elimines). El paso 2 lo puedes repetir cientos de veces con datos distintos sin volver a subir el archivo.
Comportamientos a conocer
Estos son comportamientos del API que no producen errores pero pueden causar resultados inesperados:
Variables omitidas en templateValues — si no provees un valor para una variable, el PDF mostrará el placeholder literal ({{ arrendador__nombre }}). No hay error ni advertencia. Siempre provee todas las variables del array variables de la response del template.
Claves extra en templateValues — si mandas variables que no existen en el template, se ignoran silenciosamente. No produce error.
DOCX sin variables — un DOCX sin ningún {{ }} es válido. Se crea el template con variables: [] y variableConfig: []. Útil para contratos estáticos que solo necesitan campos de firma.
GET /v2/templates sin paginación — el endpoint devuelve todos los templates del tenant en una sola respuesta. Si tienes muchos templates, filtra por category o tags para reducir el payload. El filtro de tags es AND: ?tags=legal,nda retorna solo templates que tengan ambos tags.
Todos los templates del tenant son visibles — el GET /v2/templates/{id} y el listado devuelven templates de cualquier usuario del tenant, no solo los propios. Sin embargo, solo el creador (owner_id) puede modificarlos (PATCH) o eliminarlos (DELETE).
Errores comunes
| Error | Causa | Solución |
|---|---|---|
400 Only .docx files are supported as templates | Intentaste subir un PDF como template | Los PDFs se crean directamente como documentos con document (base64), no como templates |
400 Uploaded file is empty | El DOCX subido tiene 0 bytes | Verifica que el archivo no esté vacío o corrupto |
400 File exceeds 50 MB size limit | El DOCX pesa más de 50 MB | Reduce el tamaño del archivo (imágenes embebidas, fuentes) |
400 Failed to parse DOCX template | El archivo tiene extensión .docx pero el contenido no es un DOCX válido | Verifica que sea un archivo Word real, no renombrado |
400 Either 'document' (base64 file) or 'templateId' is required | El body de POST /v2/documents no tiene ninguno de los dos | Agrega templateId o document (base64) al request |
400 Provide either 'document' or 'templateId', not both | Mandaste los dos a la vez | Usa solo uno: templateId para template, document para PDF directo |
422 Unprocessable Entity (email) | El email de un participante no puede recibir mensajes | Verifica que los correos sean válidos y entregables antes de hacer el request |
422 startAtStep must be 3 when sending invitations | Pusiste sendInvitations: true sin startAtStep: 3 | Siempre ponlos juntos: { "sendInvitations": true, "startAtStep": 3 } |
| Firmantes no reciben correo | sendInvitations es false por default | Agrega "config": { "sendInvitations": true, "startAtStep": 3 } al request |
| Firmantes no pueden firmar | startAtStep es 1 por default (borrador) | Usa "config": { "startAtStep": 3 } junto con sendInvitations: true |
404 Template not found or has been deleted | El templateId no existe, fue eliminado, o no pertenece a tu tenant | Verifica el UUID con GET /v2/templates/{id} |
Placeholders visibles en el PDF ({{ variable }}) | Falta esa clave en templateValues | Provee un valor para cada variable en el array variables de la respuesta del template |
| Valores con formato incorrecto en el PDF | Se pasó 18500 en lugar de "$18,500.00 MXN" | Los valores se inyectan verbatim — formatea los strings antes de enviarlos |

