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.


Dos modos de variables

AllSign tiene dos formas distintas de llenar variables en un documento. Elegir la correcta es la decisión más importante de esta guía:

Owner-fixedRole-bound (por rol)
Quién llena los valoresEl remitente, al crear el documentoCada firmante llena lo suyo
CuándoEn el POST /v2/documentsDespués de invitar, antes de firmar
Nombre de la variableCualquiera — {{ nombre }}Convención rol__campo{{ arrendador__nombre }}
Cómo mandas los valoresCampo placeholders (o templateValues) al creardetect-variablesassign-variables / add-signer
Estado del documentoVa directo a ESPERANDO_FIRMASPasa por LLENANDO_DATOS hasta que todos llenen
Caso típicoEl remitente ya tiene todos los datosCada parte aporta sus propios datos

El playground de la página Documentos demuestra el modo owner-fixed (campo placeholders). El resto de esta guía cubre el modo role-bound — el .docx declara qué llena cada rol y cada firmante completa lo suyo antes de firmar.


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 DOCXPrefijoComportamiento
arrendador__nombrearrendadorAsignada al rol "Arrendador"
proveedor__rfcproveedorAsignada al rol "Proveedor"
sender__fecha_iniciosenderSender-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"
  • sender es 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.


Quickstart con .docx de ejemplo

La forma más rápida de ver el modo role-bound de punta a punta. Este .docx trae variables de los tres tipos: por rol (arrendador__*, arrendatario__*), owner-fixed (sender__*) y sin asignar (lugar_firma).

1. Crear el documento con el .docx

Codifica el archivo a base64 y súbelo en document.base64Content.

Crear documento

POST
/v2/documents/
# base64 -i contrato-arrendamiento-roles.docx | tr -d '\n'   (macOS / Linux)
curl -X POST "https://api.allsign.io/v2/documents/" \
  -H "Authorization: Bearer ALLSIGN_LIVE_SK" \
  -H "Content-Type: application/json" \
  -d '{
    "document": {
      "name": "contrato-arrendamiento-roles.docx",
      "base64Content": "<BASE64_DEL_DOCX>"
    }
  }'

Guarda el id del documento — lo necesitas en los pasos siguientes. AllSign convierte el .docx a PDF y conserva el .docx fuente para detectar variables.

2. Detectar las variables (B5)

curl -X POST "https://api.allsign.io/v2/documents/{id}/detect-variables" \
  -H "Authorization: Bearer ALLSIGN_LIVE_SK"

Para este .docx, la respuesta clasifica las 8 variables por su prefijo (se omiten pdfOccurrences / multiPdfConflict por brevedad — ver la forma completa en el Path B):

Response (200)

{
  "documentId": "doc-uuid",
  "docxSource": "source_docx_s3_key",
  "variables": [
    { "name": "arrendador__domicilio", "label": "Domicilio", "assignment": "role", "suggestedRoleName": "Arrendador", "type": "textarea" },
    { "name": "arrendador__nombre", "label": "Nombre", "assignment": "role", "suggestedRoleName": "Arrendador", "type": "text" },
    { "name": "arrendador__rfc", "label": "Rfc", "assignment": "role", "suggestedRoleName": "Arrendador", "type": "text" },
    { "name": "arrendatario__nombre", "label": "Nombre", "assignment": "role", "suggestedRoleName": "Arrendatario", "type": "text" },
    { "name": "arrendatario__rfc", "label": "Rfc", "assignment": "role", "suggestedRoleName": "Arrendatario", "type": "text" },
    { "name": "lugar_firma", "label": "Lugar Firma", "assignment": "unassigned", "suggestedRoleName": null, "type": "text" },
    { "name": "sender__fecha_firma", "label": "Fecha Firma", "assignment": "sender", "suggestedRoleName": null, "type": "date" },
    { "name": "sender__monto_renta", "label": "Monto Renta", "assignment": "sender", "suggestedRoleName": null, "type": "currency" }
  ],
  "total": 8,
  "pdfsScanned": 1
}
  • role → la llena el firmante de ese rol (Arrendador, Arrendatario).
  • sender → la fija el remitente al asignar (valor fijo, oculta para firmantes).
  • unassigned → sin prefijo; tú decides si la asignas a un rol, la fijas con un valor, o la dejas manual.

3. Asignar las variables (B6)

Asigna las role a su rol, las sender con un valor fijo, y la unassigned como prefieras.

curl -X POST "https://api.allsign.io/v2/documents/{id}/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": "arrendador__rfc", "roleName": "Arrendador", "type": "text", "required": true },
      { "variableName": "arrendador__domicilio", "roleName": "Arrendador", "type": "textarea", "required": true },
      { "variableName": "arrendatario__nombre", "roleName": "Arrendatario", "type": "text", "required": true },
      { "variableName": "arrendatario__rfc", "roleName": "Arrendatario", "type": "text", "required": true },
      { "variableName": "sender__fecha_firma", "value": "2026-07-01", "type": "date" },
      { "variableName": "sender__monto_renta", "value": "$18,500.00 MXN", "type": "currency" },
      { "variableName": "lugar_firma", "value": "Ciudad de México", "type": "text" }
    ]
  }'

Cada assignment con roleName crea (o reutiliza) ese DocumentRole y deja la variable lista para que ese firmante la complete. Las que llevan value quedan fijadas por ti.

4. Agregar los firmantes a sus roles

curl -X POST "https://api.allsign.io/v2/documents/{id}/add-signer" \
  -H "Authorization: Bearer ALLSIGN_LIVE_SK" \
  -H "Content-Type: application/json" \
  -d '{ "signerEmail": "arrendador@correo.com", "signerName": "Juan García", "roleName": "Arrendador" }'

Repite para el Arrendatario. add-signer con roleName liga al firmante con su rol y auto-asigna las variables de ese rol (la respuesta lista autoAssignedVariables).

5. Invitar a firmar

curl -X POST "https://api.allsign.io/v2/documents/{id}/invite-bulk" \
  -H "Authorization: Bearer ALLSIGN_LIVE_SK" \
  -H "Content-Type: application/json" \
  -d '{
    "participants": [
      { "email": "arrendador@correo.com", "name": "Juan García" },
      { "email": "arrendatario@correo.com", "name": "María López" }
    ],
    "config": { "invitedByEmail": "owner@empresa.com" }
  }'

Como hay variables por rol sin valor, al invitar el documento entra a LLENANDO_DATOS: cada firmante llena sus variables antes de poder firmar. Cuando el último completa su llenado y el PDF se materializa, el documento pasa automáticamente a ESPERANDO_FIRMAS. Puedes seguir todo el ciclo con los webhooks document.fill_started / signer.fill_completed / document.ready_to_sign y el ciclo de vida del documento.


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

POST
/v2/documents/
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",
      "name": "documento.pdf"
    }
  ],
  "roles": [
    {
      "id": "role-uuid-1",
      "name": "Arrendador",
      "contactEmail": "arrendador@empresa.com",
      "contactPhone": null,
      "sortOrder": 0,
      "kind": "signer"
    },
    {
      "id": "role-uuid-2",
      "name": "Arrendatario",
      "contactEmail": "arrendatario@empresa.com",
      "contactPhone": null,
      "sortOrder": 1,
      "kind": "signer"
    }
  ],
  "variables": [
    {
      "id": "var-uuid-1",
      "variableName": "arrendador__nombre",
      "roleId": "role-uuid-1",
      "documentPdfIds": ["pdf-uuid-1"]
    },
    {
      "id": "var-uuid-2",
      "variableName": "arrendador__rfc",
      "roleId": "role-uuid-1",
      "documentPdfIds": ["pdf-uuid-1"]
    },
    {
      "id": "var-uuid-3",
      "variableName": "sender__fecha_inicio",
      "roleId": null,
      "documentPdfIds": ["pdf-uuid-1"]
    }
  ]
}

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" \
  -H "Content-Type: application/json" \
  -d '{
    "participants": [
      { "email": "arrendador@empresa.com", "name": "Juan García" }
    ],
    "config": { "invitedByEmail": "owner@empresa.com" }
  }'

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": "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 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 rol
  • assignment: "sender" — Variable sender__*, debe ser llenada por el dueño
  • assignment: "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",
        "label": "Nombre del arrendador",
        "type": "text",
        "required": true
      },
      {
        "variableName": "sender__fecha_inicio",
        "roleId": null,
        "label": "Fecha de inicio",
        "value": "2026-06-01",
        "type": "date",
        "required": false
      },
      {
        "variableName": "importe_mensual",
        "roleName": "Arrendador",
        "label": "Importe mensual",
        "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": "Nombre del arrendador",
      "type": "text",
      "required": true,
      "value": null,
      "action": "created"
    },
    {
      "id": "var-uuid-2",
      "variableName": "sender__fecha_inicio",
      "roleId": null,
      "label": "Fecha de 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. El auto-vinculado de variables ocurre del lado del servidor: AllSign reclama las variables sin asignar cuyo nombre coincide con el del rol (_auto_link_unassigned_variables_to_role). No envías una lista de variables — el request body no acepta ese campo (cualquier campo extra se ignora silenciosamente).

Agregar firmante con rol y auto-link

POST
/v2/documents/{id}/add-signer
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"
  }'

Response (200)

{
  "success": true,
  "message": "Firmante arrendador@empresa.com agregado correctamente.",
  "signatureId": "sig-uuid-1",
  "signerId": "signer-uuid-1",
  "roleId": "role-uuid-1",
  "roleName": "Arrendador",
  "roleContactEmail": "arrendador@empresa.com",
  "autoAssignedVariables": ["arrendador__nombre", "arrendador__rfc", "arrendador__domicilio"]
}

Nota: La respuesta viene en camelCase (signatureId, signerId, roleId, …). El campo autoAssignedVariables lista las variables del rol que se ligaron automáticamente al firmante.

PASO 5: Invitar al documento

curl -X POST "https://api.allsign.io/v2/documents/doc-uuid/invite-bulk" \
  -H "Authorization: Bearer ALLSIGN_LIVE_SK" \
  -H "Content-Type: application/json" \
  -d '{
    "participants": [
      { "email": "arrendador@empresa.com", "name": "Juan García" }
    ],
    "config": { "invitedByEmail": "owner@empresa.com" }
  }'

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 (create compound) no dispara el auto-link

Problema: En el path de creación compound (array documents), el roleName de participants se ignora: el rol se crea con el name del participante, sin buscar/crear el DocumentRole ni auto-linkear variables. (En el create simple document/templateId y en add-signer / PATCH .../signers/{id} sí se auto-linkea.)

Solución: Para garantizar el auto-link, usar POST /add-signer explícitamente con roleName. El auto-link es server-side: AllSign vincula las variables sin asignar cuyo nombre coincide con el del rol. No se envía una lista de variables en el body.

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á en la lista de firmantes." } — 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.

Was this page helpful?