Copiar página

Receta

Crea un contrato desde tu plantilla de Word

Objetivo: Un acuerdo de confidencialidad generado desde tu plantilla DOCX, con los datos de cada parte en su lugar y enviado a firma.

Para: integrador · nivel intermedio · 10 min · Necesitas: API key de sandbox · Una plantilla DOCX con variables {{ rol__campo }}: acuerdo.docx

Grabado en el entorno interno de AllSign con una key de sandbox · backend 24c0469 · · test docs-checks-v3/tests/recetas/documento-desde-plantilla-docx.receta.spec.ts

Los ejemplos usan $ALLSIGN_API_KEY. Defínela una vez con tu key de sandbox: export ALLSIGN_API_KEY="allsign_test_sk_…" (en PowerShell: $env:ALLSIGN_API_KEY="allsign_test_sk_…").

1 Da de alta tu plantilla de Word

POST /templates ver en la referencia

Qué haces

AllSign lee cada llave {{ }} del Word y la vuelve una variable. Las que llevan doble guion bajo, como parte_a__nombre, pertenecen a un rol (Parte A); las demás, como folio_acuerdo, son del documento. La das de alta una vez y la reusas en cada contrato.

Qué mirar

  • id = "tmpl_67fb98658fe548d3a71eae28087d7060"
  • variableCount = 22
  • readiness = "pending"

2 Revisa qué variables pide y de quién es cada una

GET /templates/{template_id}/variables ver en la referencia

Qué haces

role ya viene resuelto desde el nombre de la llave: no parseas nada. Revisa también type: AllSign lo deduce del nombre, y aquí monto_pena_letra salió como currency aunque lleva el monto escrito con letra.

Qué mirar

  • data.5.type = "currency"
  • data.9.role = "Parte A"

3 Corrige el tipo que se dedujo mal

PATCH /templates/{template_id}/variables ver en la referencia

Qué haces

Responde la lista completa de variables, ya con monto_pena_letra como text. Si no lo corriges, cada documento que mande el monto con letra se rechaza como INVALID_AMOUNT.

Qué mirar

  • data.5.type = "text"

4 Prueba unos valores sin crear nada

POST /templates/{template_id}/validate-values ver en la referencia

Qué haces

Valídalo antes de crear: es gratis y no crea nada. Si lo llamas mientras tu usuario escribe, hazlo con debounce para no gastar tu límite de 100 solicitudes por minuto. Responde 200 aunque encuentre problemas, porque es un diagnóstico, no un rechazo: errors dice qué variable falla y por qué, e ignored las llaves que mandaste y la plantilla no tiene.

Qué mirar

  • valid = false
  • errors = [{"name":"fecha_celebracion","code":"INVALID_DATE","detail":"Write a date as YYYY-MM-DD or DD/MM/YYYY."},{"name":"monto_pena","code":"INVALID_AMOUNT","detail":"Write a numeric amount. Example: 15000 or $15,000.00."},{"name":"numero_cliente","code":"UNKNOWN_VARIABLE","detail":"The template has no variable with this name. Check the spelling in GET /v3/templates/{id}/variables."}]
  • ignored = ["numero_cliente"]

5 Valida los valores completos

POST /templates/{template_id}/validate-values ver en la referencia

Qué haces

Con valid en true, ya puedes crear el documento con estos mismos valores.

Qué mirar

  • valid = true

6 Crea el documento con un firmante por rol

POST /documents ver en la referencia

Qué haces

roleName conecta a cada firmante con su rol de la plantilla. Los valores van en templateValues con las mismas llaves que validaste. Crear no envía nada: el documento nace en draft y todavía lo puedes revisar.

Qué mirar en sandbox

  • id = "doc_b5dcbda2f82c4b4fbec9cc944a7b2ea2"
  • status = "draft"
  • templateId = "tmpl_67fb98658fe548d3a71eae28087d7060"
  • signerCount = 2

7 Envíalo a firma

POST /documents/{document_id}/send ver en la referencia

Qué haces

Aquí salen las invitaciones a las dos partes, cada una a su correo.

Qué mirar

  • status = "awaiting_signatures"

En producción

Con una key live este paso consume créditos de tu saldo; en sandbox no se cobra nada.

8 Revisa quién ya firmó

GET /documents/{document_id}/signers ver en la referencia

Qué haces

Cada firmante trae su propio status. No consultes esto en bucle: para enterarte cuando firme cada quien, suscríbete a los webhooks signer.signed y document.completed.

Qué mirar

  • data.0.status = "signed"
  • data.1.status = "sent"

En producción

La Parte A firmó sola porque usamos signer-success@sandbox.allsign.io. Con firmantes reales, las dos quedan pendientes hasta que cada quien firme desde su invitación.

Errores comunes de esta receta

Errores reales que el test de esta receta provocó a propósito en sandbox, sobre sus mismos pasos. Cada uno enlaza a su explicación en Errores.

VALIDATION_ERROR · 422 · en el paso 6 (Crea el documento con un firmante por rol)

Crea el documento sin llenar todas las variables. Qué significa y qué hacer

Respuesta · 422 · VALIDATION_ERROR
{
  "type": "https://allsign.io/developers/docs/errors#VALIDATION_ERROR",
  "title": "Validation failed",
  "status": 422,
  "detail": "The values are not valid. Fix the fields listed in `errors`. You can test a set of values for free with POST /v3/templates/{id}/validate-values.",
  "instance": "/v3/documents",
  "code": "VALIDATION_ERROR",
  "requestId": "req_71750d833b65413ea2c9794e81405461",
  "errors": [
    {
      "field": "templateValues.ciudad_celebracion",
      "code": "MISSING_REQUIRED_VARIABLE",
      "detail": "This required variable is missing. Send it with a non-empty value."
    },
    {
      "field": "templateValues.fecha_celebracion",
      "code": "MISSING_REQUIRED_VARIABLE",
      "detail": "This required variable is missing. Send it with a non-empty value."
    },
    {
      "field": "templateValues.folio_acuerdo",
      "code": "MISSING_REQUIRED_VARIABLE",
      "detail": "This required variable is missing. Send it with a non-empty value."
    },
    {
      "field": "templateValues.jurisdiccion",
      "code": "MISSING_REQUIRED_VARIABLE",
      "detail": "This required variable is missing. Send it with a non-empty value."
    },
    {
      "field": "templateValues.monto_pena",
      "code": "MISSING_REQUIRED_VARIABLE",
      "detail": "This required variable is missing. Send it with a non-empty value."
    },
    {
      "field": "templateValues.monto_pena_letra",
      "code": "MISSING_REQUIRED_VARIABLE",
      "detail": "This required variable is missing. Send it with a non-empty value."
    },
    {
      "field": "templateValues.objeto_relacion",
      "code": "MISSING_REQUIRED_VARIABLE",
      "detail": "This required variable is missing. Send it with a non-empty value."
    },
    {
      "field": "templateValues.parte_a__domicilio",
      "code": "MISSING_REQUIRED_VARIABLE",
      "detail": "This required variable is missing. Send it with a non-empty value."
    },
    {
      "field": "templateValues.parte_a__email",
      "code": "MISSING_REQUIRED_VARIABLE",
      "detail": "This required variable is missing. Send it with a non-empty value."
    },
    {
      "field": "templateValues.parte_a__representante",
      "code": "MISSING_REQUIRED_VARIABLE",
      "detail": "This required variable is missing. Send it with a non-empty value."
    },
    {
      "field": "templateValues.parte_a__rfc",
      "code": "MISSING_REQUIRED_VARIABLE",
      "detail": "This required variable is missing. Send it with a non-empty value."
    },
    {
      "field": "templateValues.parte_a__telefono",
      "code": "MISSING_REQUIRED_VARIABLE",
      "detail": "This required variable is missing. Send it with a non-empty value."
    },
    {
      "field": "templateValues.parte_b__domicilio",
      "code": "MISSING_REQUIRED_VARIABLE",
      "detail": "This required variable is missing. Send it with a non-empty value."
    },
    {
      "field": "templateValues.parte_b__email",
      "code": "MISSING_REQUIRED_VARIABLE",
      "detail": "This required variable is missing. Send it with a non-empty value."
    },
    {
      "field": "templateValues.parte_b__nombre",
      "code": "MISSING_REQUIRED_VARIABLE",
      "detail": "This required variable is missing. Send it with a non-empty value."
    },
    {
      "field": "templateValues.parte_b__representante",
      "code": "MISSING_REQUIRED_VARIABLE",
      "detail": "This required variable is missing. Send it with a non-empty value."
    },
    {
      "field": "templateValues.parte_b__rfc",
      "code": "MISSING_REQUIRED_VARIABLE",
      "detail": "This required variable is missing. Send it with a non-empty value."
    },
    {
      "field": "templateValues.parte_b__telefono",
      "code": "MISSING_REQUIRED_VARIABLE",
      "detail": "This required variable is missing. Send it with a non-empty value."
    },
    {
      "field": "templateValues.tipo_informacion_confidencial",
      "code": "MISSING_REQUIRED_VARIABLE",
      "detail": "This required variable is missing. Send it with a non-empty value."
    },
    {
      "field": "templateValues.vigencia",
      "code": "MISSING_REQUIRED_VARIABLE",
      "detail": "This required variable is missing. Send it with a non-empty value."
    },
    {
      "field": "templateValues.vigencia_post_terminacion",
      "code": "MISSING_REQUIRED_VARIABLE",
      "detail": "This required variable is missing. Send it with a non-empty value."
    }
  ]
}

Grabado en el entorno interno de AllSign con una key de sandbox · backend 24c0469 · · test docs-checks-v3/tests/recetas/documento-desde-plantilla-docx.receta.spec.ts

TEMPLATE_NOT_FOUND · 404 · en el paso 6 (Crea el documento con un firmante por rol)

Usa una plantilla que no existe. Qué significa y qué hacer

Respuesta · 404 · TEMPLATE_NOT_FOUND
{
  "type": "https://allsign.io/developers/docs/errors#TEMPLATE_NOT_FOUND",
  "title": "Template not found",
  "status": 404,
  "detail": "Template not found or has been deleted.",
  "instance": "/v3/documents",
  "code": "TEMPLATE_NOT_FOUND",
  "requestId": "req_252364b6627a443285dda69be2eb4213"
}

Grabado en el entorno interno de AllSign con una key de sandbox · backend 24c0469 · · test docs-checks-v3/tests/recetas/documento-desde-plantilla-docx.receta.spec.ts

IDEMPOTENCY_KEY_REUSED · 409 · en el paso 6 (Crea el documento con un firmante por rol)

Reintenta con la misma Idempotency-Key pero otro cuerpo. Qué significa y qué hacer

Este 409 solo sale si antes mandaste esa misma Idempotency-Key con otro cuerpo: aquí, la del request que creó el acuerdo NDA-2026-015, que no aparece en este bloque. Como el ejemplo genera una llave nueva, copiado tal cual no da este error. Si reintentas con la misma llave y exactamente el mismo cuerpo, recibes el mismo documento en lugar de uno duplicado; si cambiaste el cuerpo, es otro documento y lleva una llave nueva.

Respuesta · 409 · IDEMPOTENCY_KEY_REUSED
{
  "type": "https://allsign.io/developers/docs/errors#IDEMPOTENCY_KEY_REUSED",
  "title": "Idempotency key reused",
  "status": 409,
  "detail": "This Idempotency-Key was already used with a different request.",
  "instance": "/v3/documents",
  "code": "IDEMPOTENCY_KEY_REUSED",
  "requestId": "req_7a71eb8164e14a01a6760499df342f6f"
}

Grabado en el entorno interno de AllSign con una key de sandbox · backend 24c0469 · · test docs-checks-v3/tests/recetas/documento-desde-plantilla-docx.receta.spec.ts

Siguiente