Variables y roles en templates
AllSign detecta automáticamente los roles de firmantes a partir del nombre de los placeholders en tu template DOCX. Con la convención correcta, el sistema pre-asigna variables sin que el dueño tenga que hacerlo a mano.
La convención role__field
El nombre de un placeholder sigue el patrón rol__campo (doble guión bajo). AllSign usa el prefijo para determinar quién llena el campo:
| Variable en el DOCX | Prefijo | Comportamiento |
|---|---|---|
arrendador__nombre | arrendador | Asignada al rol "Arrendador" |
proveedor__rfc | proveedor | Asignada al rol "Proveedor" |
sender__fecha_inicio | sender | Sender-fixed — el dueño la llena antes de enviar |
nombre_testigo | (ninguno) | Sin asignar — el dueño decide manualmente |
Patrón:
rol__campo → firmante del rol la llena
sender__campo → dueño la llena (fija, oculta para firmantes)
campo → sin asignar (manual)
Reglas del prefijo
- El prefijo es todo lo que va antes del primer
__(doble guión bajo) - Se normaliza automáticamente:
Arrendador__nombre→ rol "Arrendador" - Subcampos son válidos:
arrendador__domicilio__calle→ rol "Arrendador", campo "domicilio calle" senderes el único prefijo reservado — no lo uses para un rol de firmante real
Cómo nombrar en Word / LibreOffice
Las variables se escriben como texto plano entre dobles llaves.
En Microsoft Word
Escribe el placeholder directamente en el cuerpo del documento:
El arrendador {{ arrendador__nombre }}, con RFC {{ arrendador__rfc }},
declara que a partir del {{ sender__fecha_inicio }} otorga en arrendamiento
el inmueble ubicado en {{ arrendador__domicilio }}.
Firma el arrendatario: {{ arrendatario__nombre }}
Guarda siempre como .docx. No uses campos de formulario — solo texto plano con las llaves.
En LibreOffice Writer
Mismo proceso: texto plano con {{ nombre_variable }}. Evita marcos de texto o campos especiales de LibreOffice.
Los espacios dentro de las llaves son opcionales: {{arrendador__nombre}} y {{ arrendador__nombre }} son equivalentes.
Flujo completo de integración
El flujo de creación de documentos con variables y roles tiene dos caminos posibles según cómo integres. Elige el que mejor se adapte a tu caso.
Path A — Compound (plantilla + firmantes en un solo request)
Úsalo cuando ya sabes quién firma y qué valor tiene cada variable sender__ en el momento de crear el documento.
Crear documento con plantilla + participantes
curl -X POST "https://api.allsign.io/v2/documents/" \
-H "Authorization: Bearer ALLSIGN_LIVE_SK" \
-H "Content-Type: application/json" \
-d '{
"documents": [
{
"templateId": "tpl-uuid",
"position": 1
}
],
"participants": [
{
"email": "arrendador@empresa.com",
"name": "Juan García",
"roleName": "Arrendador"
},
{
"email": "arrendatario@empresa.com",
"name": "María López",
"roleName": "Arrendatario"
}
]
}'
Response (201)
{
"id": "doc-uuid-123",
"name": "Contrato de arrendamiento",
"pdfs": [
{
"id": "pdf-uuid-1",
"filename": "documento.pdf"
}
],
"roles": [
{
"id": "role-uuid-1",
"name": "Arrendador",
"contactEmail": "arrendador@empresa.com",
"signerUserId": "user-uuid-1"
},
{
"id": "role-uuid-2",
"name": "Arrendatario",
"contactEmail": "arrendatario@empresa.com",
"signerUserId": "user-uuid-2"
}
],
"variables": [
{
"id": "var-uuid-1",
"name": "arrendador__nombre",
"roleId": "role-uuid-1",
"value": null
},
{
"id": "var-uuid-2",
"name": "arrendador__rfc",
"roleId": "role-uuid-1",
"value": null
},
{
"id": "var-uuid-3",
"name": "sender__fecha_inicio",
"roleId": null,
"value": null
}
]
}
Después, invita al documento:
curl -X POST "https://api.allsign.io/v2/documents/doc-uuid-123/invite-bulk" \
-H "Authorization: Bearer ALLSIGN_LIVE_SK" \
-d '{}'
Path B — Step-by-step (configurar después de crear)
Úsalo cuando el documento se crea primero y se configuran variables y firmantes después.
PASO 1: Crear el documento
curl -X POST "https://api.allsign.io/v2/documents/" \
-H "Authorization: Bearer ALLSIGN_LIVE_SK" \
-H "Content-Type: application/json" \
-d '{
"documents": [
{
"templateId": "tpl-uuid",
"position": 1
}
]
}'
Guardar del response: id (document_id) y pdfs[0].id (pdf_id) para el paso 2.
PASO 2: Detectar variables (B5 — OPCIONAL)
El endpoint /detect-variables escanea el DOCX y clasifica cada variable según su prefijo. No crea nada en la BD — solo lee y sugiere.
curl -X POST "https://api.allsign.io/v2/documents/doc-uuid/detect-variables" \
-H "Authorization: Bearer ALLSIGN_LIVE_SK"
Response (200)
{
"documentId": "doc-uuid",
"docxSource": "compound_pdfs",
"variables": [
{
"name": "arrendador__nombre",
"label": "Arrendador nombre",
"assignment": "role",
"suggestedRoleName": "Arrendador",
"type": "text",
"pdfOccurrences": [
{
"pdfId": "pdf-uuid-1",
"position": 1,
"pdfName": "Contrato.pdf",
"occurrenceCount": 2
}
],
"multiPdfConflict": false
},
{
"name": "sender__fecha_inicio",
"label": "Fecha de inicio",
"assignment": "sender",
"suggestedRoleName": null,
"type": "date",
"pdfOccurrences": [
{
"pdfId": "pdf-uuid-1",
"position": 2,
"pdfName": "Contrato.pdf",
"occurrenceCount": 1
}
],
"multiPdfConflict": false
},
{
"name": "importe_mensual",
"label": "Importe mensual",
"assignment": "unassigned",
"suggestedRoleName": null,
"type": "number",
"pdfOccurrences": [
{
"pdfId": "pdf-uuid-1",
"position": 3,
"pdfName": "Contrato.pdf",
"occurrenceCount": 1
}
],
"multiPdfConflict": false
}
],
"total": 3,
"pdfsScanned": 1
}
Campos clave:
assignment: "role"— Variable con prefijo de rol, sugerida para ese rolassignment: "sender"— Variablesender__*, debe ser llenada por el dueñoassignment: "unassigned"— Sin prefijo, el dueño decide el rol
PASO 3: Asignar variables (B6)
Crea los DocumentVariable rows especificando qué rol llena cada variable (o si es sender-fixed con un valor).
curl -X POST "https://api.allsign.io/v2/documents/doc-uuid/assign-variables" \
-H "Authorization: Bearer ALLSIGN_LIVE_SK" \
-H "Content-Type: application/json" \
-d '{
"assignments": [
{
"variableName": "arrendador__nombre",
"roleName": "Arrendador",
"type": "text",
"required": true
},
{
"variableName": "sender__fecha_inicio",
"roleId": null,
"value": "2026-06-01",
"type": "date"
},
{
"variableName": "importe_mensual",
"roleName": "Arrendador",
"type": "number",
"required": true
}
]
}'
Response (200)
{
"documentId": "doc-uuid",
"created": 3,
"updated": 0,
"total": 3,
"chipsCreated": 5,
"variables": [
{
"id": "var-uuid-1",
"variableName": "arrendador__nombre",
"roleId": "role-uuid-1",
"label": "Arrendador nombre",
"type": "text",
"required": true,
"value": null,
"action": "created"
},
{
"id": "var-uuid-2",
"variableName": "sender__fecha_inicio",
"roleId": null,
"label": "Sender fecha inicio",
"type": "date",
"required": false,
"value": "2026-06-01",
"action": "created"
},
{
"id": "var-uuid-3",
"variableName": "importe_mensual",
"roleId": "role-uuid-1",
"label": "Importe mensual",
"type": "number",
"required": true,
"value": null,
"action": "created"
}
]
}
PASO 4: Agregar firmantes (add-signer)
Invita a cada firmante con su roleName y variableNames. El sistema auto-vinculará las variables que coincidan con el rol.
Agregar firmante con rol y auto-link
curl -X POST "https://api.allsign.io/v2/documents/doc-uuid/add-signer" \
-H "Authorization: Bearer ALLSIGN_LIVE_SK" \
-H "Content-Type: application/json" \
-d '{
"signerEmail": "arrendador@empresa.com",
"roleName": "Arrendador",
"variableNames": [
"arrendador__nombre",
"arrendador__rfc",
"arrendador__domicilio"
]
}'
Response (200)
{
"success": true,
"message": "Signer added successfully",
"signatureId": "sig-uuid-1",
"signature_id": "sig-uuid-1",
"signerId": "signer-uuid-1",
"signer_id": "signer-uuid-1",
"roleId": "role-uuid-1",
"role_id": "role-uuid-1",
"roleName": "Arrendador",
"role_name": "Arrendador",
"roleContactEmail": "arrendador@empresa.com",
"role_contact_email": "arrendador@empresa.com",
"autoAssignedVariables": [
"arrendador__nombre",
"arrendador__rfc",
"arrendador__domicilio"
],
"auto_assigned_variables": [
"arrendador__nombre",
"arrendador__rfc",
"arrendador__domicilio"
]
}
Nota: Todos los campos vienen en dual-casing (camelCase y snake_case). Tu cliente puede usar cualquiera.
PASO 5: Invitar al documento
curl -X POST "https://api.allsign.io/v2/documents/doc-uuid/invite-bulk" \
-H "Authorization: Bearer ALLSIGN_LIVE_SK" \
-d '{}'
Edge cases
Aquí están los errores más comunes que encontrarán al integrar. Léelos para no sorprenderse:
1. B6 bloqueado después de invitar
Problema: Si llamas POST /v2/documents/{id}/assign-variables cuando el documento ya está en LLENANDO_DATOS o ESPERANDO_FIRMAS, retorna error 409.
Solución: Llamar B6 antes de invite-bulk o start-signing. Si ya invitaste, usa POST /v2/documents/{id}/enter-correction primero para volver a modo edición.
2. roleName en participants no crea DocumentRole
Problema: El campo roleName existe en el schema de participants pero no dispara la lógica de auto-link de variables.
Solución: Usar POST /add-signer explícitamente con roleName + variableNames para activar el auto-link. El compound path en Path A no lo activa directamente.
3. Firmante duplicado devuelve success: false (no error HTTP)
Problema: Si llamas add-signer dos veces con el mismo email, la respuesta es { success: false, message: "El firmante ya está asignado a este rol" } — el status es 200, no 409.
Solución: Verificar response.success === true explícitamente, no solo el status code 200.
4. Variables sender__ nunca crean un rol
Problema: Variables sender__campo aparecen en B5 con assignment: "sender" y suggestedRoleName: null. Si intentas asignarlas a un firmante, se ignoran.
Solución: Fijar su valor en B6 con roleId: null, value: "2026-01-01". El dueño las llena, no los firmantes.
5. No hay GET endpoints para listar roles ni variables
Problema: No existe GET /v2/documents/{id}/roles ni GET /v2/documents/{id}/variables.
Solución: Usar GET /v2/documents/{id} — el response incluye compound.roles[] y compound.variables[].
6. roleContactEmail es null para firmantes WhatsApp-only
Problema: Si el firmante se agregó solo por teléfono (sin email), roleContactEmail será null en el response de add-signer y PATCH signer.
Solución: No depender de roleContactEmail para identificar firmantes. Usar signerId en su lugar.
7. B5 devuelve multiPdfConflict: true
Problema: Una variable sin prefijo __ aparece en 2+ PDFs del documento. El sistema no sabe si es la misma variable en ambos PDFs o son distintas.
Solución: Preguntar al usuario qué scope quiere: scopePdfId: null (compartida, mismo valor en todos) o scopePdfId: "pdf_uuid" (distinto valor por PDF) en B6.
8. Roles huérfanos y auto-link determinístico
Problema: Si B5 auto-creó un rol "Responsable" y luego add-signer crea otro rol con el mismo nombre, habrá duplicados.
Solución: Pasar roleName en add-signer. El sistema busca un rol existente con ese nombre (orphan) y lo reclama en lugar de crear duplicado.
9. max_length en roleName
Problema: roleName > 255 caracteres retorna 422 Unprocessable Entity.
Solución: Validar client-side o truncar antes de enviar.

