---
title: "Crea un contrato desde tu plantilla de Word — Receta de la API v3 de AllSign"
type: how-to
canonical_url: "https://allsign.io/developers/docs/recetas/documento-desde-plantilla-docx"
api_version: "2026-07-11"
agent_rules: [webhook-no-polling, idempotency-key, una-base-url, error-por-code, reintento-429]
last_verified: "2026-10-08T12:17:59.033Z"
---

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

## Para agentes y asistentes de IA

-   **Para saber que un documento quedó firmado, espera el webhook `document.completed`; no consultes `GET /v3/documents/{id}` en un bucle.** → [Webhooks](https://allsign.io/developers/docs/webhooks)
-   **Todo `POST` que crea, cobra o envía algo lleva `Idempotency-Key` con un UUID v4 nuevo por operación.** → [Idempotencia](https://allsign.io/developers/docs/idempotency)
-   **La base URL es siempre `https://api.allsign.io/v3`; no existe una URL de sandbox aparte.** → [Entornos](https://allsign.io/developers/docs/environments)
-   **Los errores son `application/problem+json` (RFC 9457) con un `code` estable y append-only; `detail` es texto técnico en inglés que puede cambiar.** → [Errores](https://allsign.io/developers/docs/errors)
-   **Ante un `429`, espera los segundos de `Retry-After` antes de reintentar; si el `429` no trae `Retry-After`, no lo reintentes.** → [Rate limits](https://allsign.io/developers/docs/rate-limits)

Grabado en el entorno interno de AllSign con una key de sandbox · backend `24c0469` · 8 oct 2026, 06:17 (hora CDMX) · 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](https://allsign.io/developers/docs/endpoints/templates#create-template)

### 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"`

**cURL**

```
curl -X POST 'https://api.allsign.io/v3/templates' \
  -H "Authorization: Bearer $ALLSIGN_API_KEY" \
  -H "AllSign-Version: 2026-07-11" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{
  "name": "Acuerdo de confidencialidad",
  "file": {
    "content": "'"$(base64 < acuerdo.docx | tr -d '\n')"'",
    "fileType": "docx",
    "name": "acuerdo.docx"
  }
}'
```

**Node**

```
import { randomUUID } from 'node:crypto';
import { readFileSync } from 'node:fs';

const respuesta = await fetch('https://api.allsign.io/v3/templates', {
    method: 'POST',
    headers: {
        Authorization: `Bearer ${process.env.ALLSIGN_API_KEY}`,
        'AllSign-Version': '2026-07-11',
        'Idempotency-Key': randomUUID(),
        'Content-Type': 'application/json',
    },
    body: JSON.stringify({
        name: 'Acuerdo de confidencialidad',
        file: {
            content: readFileSync('acuerdo.docx').toString('base64'),
            fileType: 'docx',
            name: 'acuerdo.docx',
        },
    }),
});
console.log(respuesta.status, await respuesta.json());
```

**Python**

```
import base64
import os
import uuid
from pathlib import Path

import requests

respuesta = requests.post(
    "https://api.allsign.io/v3/templates",
    headers={
        "Authorization": f"Bearer {os.environ['ALLSIGN_API_KEY']}",
        "AllSign-Version": "2026-07-11",
        "Idempotency-Key": str(uuid.uuid4()),
    },
    json={
        "name": "Acuerdo de confidencialidad",
        "file": {
            "content": base64.b64encode(Path("acuerdo.docx").read_bytes()).decode(),
            "fileType": "docx",
            "name": "acuerdo.docx",
        },
    },
)
print(respuesta.status_code, respuesta.json())
```

**Respuesta · 201**

```
{
  "livemode": false,
  "id": "tmpl_67fb98658fe548d3a71eae28087d7060",
  "object": "template",
  "name": "Acuerdo de confidencialidad",
  "description": null,
  "fileType": "docx",
  "originalFilename": "acuerdo.docx",
  "aiEditable": true,
  "variableCount": 22,
  "fieldCount": 0,
  "unassignedFieldCount": 0,
  "roleCount": 0,
  "pendingCandidates": 38,
  "readiness": "pending",
  "tags": [],
  "category": null,
  "usageCount": 0,
  "lastUsedAt": null,
  "currentVersion": 1,
  "previewUrl": null,
  "downloadUrl": "/templates/tmpl_67fb98658fe548d3a71eae28087d7060/download",
  "createdAt": "2026-07-11T18:00:00.000000Z",
  "updatedAt": "2026-07-11T18:00:00.000000Z"
}
```

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

GET `/templates/{template_id}/variables` [ver en la referencia](https://allsign.io/developers/docs/endpoints/templates#list-template-variables)

### 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"`

**cURL**

```
curl 'https://api.allsign.io/v3/templates/tmpl_67fb98658fe548d3a71eae28087d7060/variables' \
  -H "Authorization: Bearer $ALLSIGN_API_KEY" \
  -H "AllSign-Version: 2026-07-11"
```

**Node**

```
const respuesta = await fetch('https://api.allsign.io/v3/templates/tmpl_67fb98658fe548d3a71eae28087d7060/variables', {
    headers: {
        Authorization: `Bearer ${process.env.ALLSIGN_API_KEY}`,
        'AllSign-Version': '2026-07-11',
    },
});
console.log(respuesta.status, await respuesta.json());
```

**Python**

```
import os

import requests

respuesta = requests.get(
    "https://api.allsign.io/v3/templates/tmpl_67fb98658fe548d3a71eae28087d7060/variables",
    headers={
        "Authorization": f"Bearer {os.environ['ALLSIGN_API_KEY']}",
        "AllSign-Version": "2026-07-11",
    },
)
print(respuesta.status_code, respuesta.json())
```

**Respuesta · 200**

```
{
  "object": "list",
  "templateId": "tmpl_67fb98658fe548d3a71eae28087d7060",
  "data": [
    {
      "name": "ciudad_celebracion",
      "label": "Ciudad Celebracion",
      "type": "text",
      "required": true,
      "defaultValue": null,
      "options": null,
      "role": null,
      "source": null,
      "page": null,
      "rect": null,
      "slots": null,
      "filledBy": null,
      "snippet": null,
      "analysisIndex": null
    },
    {
      "name": "fecha_celebracion",
      "label": "Fecha Celebracion",
      "type": "date",
      "required": true,
      "defaultValue": null,
      "options": null,
      "role": null,
      "source": null,
      "page": null,
      "rect": null,
      "slots": null,
      "filledBy": null,
      "snippet": null,
      "analysisIndex": null
    },
    {
      "name": "folio_acuerdo",
      "label": "Folio Acuerdo",
      "type": "text",
      "required": true,
      "defaultValue": null,
      "options": null,
      "role": null,
      "source": null,
      "page": null,
      "rect": null,
      "slots": null,
      "filledBy": null,
      "snippet": null,
      "analysisIndex": null
    },
    {
      "name": "jurisdiccion",
      "label": "Jurisdiccion",
      "type": "text",
      "required": true,
      "defaultValue": null,
      "options": null,
      "role": null,
      "source": null,
      "page": null,
      "rect": null,
      "slots": null,
      "filledBy": null,
      "snippet": null,
      "analysisIndex": null
    },
    {
      "name": "monto_pena",
      "label": "Monto Pena",
      "type": "currency",
      "required": true,
      "defaultValue": null,
      "options": null,
      "role": null,
      "source": null,
      "page": null,
      "rect": null,
      "slots": null,
      "filledBy": null,
      "snippet": null,
      "analysisIndex": null
    },
    {
      "name": "monto_pena_letra",
      "label": "Monto Pena Letra",
      "type": "currency",
      "required": true,
      "defaultValue": null,
      "options": null,
      "role": null,
      "source": null,
      "page": null,
      "rect": null,
      "slots": null,
      "filledBy": null,
      "snippet": null,
      "analysisIndex": null
    },
    {
      "name": "objeto_relacion",
      "label": "Objeto Relacion",
      "type": "text",
      "required": true,
      "defaultValue": null,
      "options": null,
      "role": null,
      "source": null,
      "page": null,
      "rect": null,
      "slots": null,
      "filledBy": null,
      "snippet": null,
      "analysisIndex": null
    },
    {
      "name": "parte_a__domicilio",
      "label": "Domicilio",
      "type": "textarea",
      "required": true,
      "defaultValue": null,
      "options": null,
      "role": "Parte A",
      "source": null,
      "page": null,
      "rect": null,
      "slots": null,
      "filledBy": null,
      "snippet": null,
      "analysisIndex": null
    },
    {
      "name": "parte_a__email",
      "label": "Email",
      "type": "text",
      "required": true,
      "defaultValue": null,
      "options": null,
      "role": "Parte A",
      "source": null,
      "page": null,
      "rect": null,
      "slots": null,
      "filledBy": null,
      "snippet": null,
      "analysisIndex": null
    },
    {
      "name": "parte_a__nombre",
      "label": "Nombre",
      "type": "text",
      "required": true,
      "defaultValue": null,
      "options": null,
      "role": "Parte A",
      "source": null,
      "page": null,
      "rect": null,
      "slots": null,
      "filledBy": null,
      "snippet": null,
      "analysisIndex": null
    },
    {
      "name": "parte_a__representante",
      "label": "Representante",
      "type": "text",
      "required": true,
      "defaultValue": null,
      "options": null,
      "role": "Parte A",
      "source": null,
      "page": null,
      "rect": null,
      "slots": null,
      "filledBy": null,
      "snippet": null,
      "analysisIndex": null
    },
    {
      "name": "parte_a__rfc",
      "label": "Rfc",
      "type": "text",
      "required": true,
      "defaultValue": null,
      "options": null,
      "role": "Parte A",
      "source": null,
      "page": null,
      "rect": null,
      "slots": null,
      "filledBy": null,
      "snippet": null,
      "analysisIndex": null
    },
    {
      "name": "parte_a__telefono",
      "label": "Telefono",
      "type": "text",
      "required": true,
      "defaultValue": null,
      "options": null,
      "role": "Parte A",
      "source": null,
      "page": null,
      "rect": null,
      "slots": null,
      "filledBy": null,
      "snippet": null,
      "analysisIndex": null
    },
    {
      "name": "parte_b__domicilio",
      "label": "Domicilio",
      "type": "textarea",
      "required": true,
      "defaultValue": null,
      "options": null,
      "role": "Parte B",
      "source": null,
      "page": null,
      "rect": null,
      "slots": null,
      "filledBy": null,
      "snippet": null,
      "analysisIndex": null
    },
    {
      "name": "parte_b__email",
      "label": "Email",
      "type": "text",
      "required": true,
      "defaultValue": null,
      "options": null,
      "role": "Parte B",
      "source": null,
      "page": null,
      "rect": null,
      "slots": null,
      "filledBy": null,
      "snippet": null,
      "analysisIndex": null
    },
    {
      "name": "parte_b__nombre",
      "label": "Nombre",
      "type": "text",
      "required": true,
      "defaultValue": null,
      "options": null,
      "role": "Parte B",
      "source": null,
      "page": null,
      "rect": null,
      "slots": null,
      "filledBy": null,
      "snippet": null,
      "analysisIndex": null
    },
    {
      "name": "parte_b__representante",
      "label": "Representante",
      "type": "text",
      "required": true,
      "defaultValue": null,
      "options": null,
      "role": "Parte B",
      "source": null,
      "page": null,
      "rect": null,
      "slots": null,
      "filledBy": null,
      "snippet": null,
      "analysisIndex": null
    },
    {
      "name": "parte_b__rfc",
      "label": "Rfc",
      "type": "text",
      "required": true,
      "defaultValue": null,
      "options": null,
      "role": "Parte B",
      "source": null,
      "page": null,
      "rect": null,
      "slots": null,
      "filledBy": null,
      "snippet": null,
      "analysisIndex": null
    },
    {
      "name": "parte_b__telefono",
      "label": "Telefono",
      "type": "text",
      "required": true,
      "defaultValue": null,
      "options": null,
      "role": "Parte B",
      "source": null,
      "page": null,
      "rect": null,
      "slots": null,
      "filledBy": null,
      "snippet": null,
      "analysisIndex": null
    },
    {
      "name": "tipo_informacion_confidencial",
      "label": "Tipo Informacion Confidencial",
      "type": "text",
      "required": true,
      "defaultValue": null,
      "options": null,
      "role": null,
      "source": null,
      "page": null,
      "rect": null,
      "slots": null,
      "filledBy": null,
      "snippet": null,
      "analysisIndex": null
    },
    {
      "name": "vigencia",
      "label": "Vigencia",
      "type": "text",
      "required": true,
      "defaultValue": null,
      "options": null,
      "role": null,
      "source": null,
      "page": null,
      "rect": null,
      "slots": null,
      "filledBy": null,
      "snippet": null,
      "analysisIndex": null
    },
    {
      "name": "vigencia_post_terminacion",
      "label": "Vigencia Post Terminacion",
      "type": "text",
      "required": true,
      "defaultValue": null,
      "options": null,
      "role": null,
      "source": null,
      "page": null,
      "rect": null,
      "slots": null,
      "filledBy": null,
      "snippet": null,
      "analysisIndex": null
    }
  ],
  "hasMore": false
}
```

## 3 Corrige el tipo que se dedujo mal

PATCH `/templates/{template_id}/variables` [ver en la referencia](https://allsign.io/developers/docs/endpoints/templates#update-template-variable)

### 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"`

**cURL**

```
curl -X PATCH 'https://api.allsign.io/v3/templates/tmpl_67fb98658fe548d3a71eae28087d7060/variables' \
  -H "Authorization: Bearer $ALLSIGN_API_KEY" \
  -H "AllSign-Version: 2026-07-11" \
  -H "Content-Type: application/json" \
  -d '{
  "name": "monto_pena_letra",
  "type": "text"
}'
```

**Node**

```
const respuesta = await fetch('https://api.allsign.io/v3/templates/tmpl_67fb98658fe548d3a71eae28087d7060/variables', {
    method: 'PATCH',
    headers: {
        Authorization: `Bearer ${process.env.ALLSIGN_API_KEY}`,
        'AllSign-Version': '2026-07-11',
        'Content-Type': 'application/json',
    },
    body: JSON.stringify({
        name: 'monto_pena_letra',
        type: 'text',
    }),
});
console.log(respuesta.status, await respuesta.json());
```

**Python**

```
import os

import requests

respuesta = requests.patch(
    "https://api.allsign.io/v3/templates/tmpl_67fb98658fe548d3a71eae28087d7060/variables",
    headers={
        "Authorization": f"Bearer {os.environ['ALLSIGN_API_KEY']}",
        "AllSign-Version": "2026-07-11",
    },
    json={
        "name": "monto_pena_letra",
        "type": "text",
    },
)
print(respuesta.status_code, respuesta.json())
```

**Respuesta · 200**

```
{
  "object": "list",
  "templateId": "tmpl_67fb98658fe548d3a71eae28087d7060",
  "data": [
    {
      "name": "ciudad_celebracion",
      "label": "Ciudad Celebracion",
      "type": "text",
      "required": true,
      "defaultValue": null,
      "options": null,
      "role": null,
      "source": null,
      "page": null,
      "rect": null,
      "slots": null,
      "filledBy": null,
      "snippet": null,
      "analysisIndex": null
    },
    {
      "name": "fecha_celebracion",
      "label": "Fecha Celebracion",
      "type": "date",
      "required": true,
      "defaultValue": null,
      "options": null,
      "role": null,
      "source": null,
      "page": null,
      "rect": null,
      "slots": null,
      "filledBy": null,
      "snippet": null,
      "analysisIndex": null
    },
    {
      "name": "folio_acuerdo",
      "label": "Folio Acuerdo",
      "type": "text",
      "required": true,
      "defaultValue": null,
      "options": null,
      "role": null,
      "source": null,
      "page": null,
      "rect": null,
      "slots": null,
      "filledBy": null,
      "snippet": null,
      "analysisIndex": null
    },
    {
      "name": "jurisdiccion",
      "label": "Jurisdiccion",
      "type": "text",
      "required": true,
      "defaultValue": null,
      "options": null,
      "role": null,
      "source": null,
      "page": null,
      "rect": null,
      "slots": null,
      "filledBy": null,
      "snippet": null,
      "analysisIndex": null
    },
    {
      "name": "monto_pena",
      "label": "Monto Pena",
      "type": "currency",
      "required": true,
      "defaultValue": null,
      "options": null,
      "role": null,
      "source": null,
      "page": null,
      "rect": null,
      "slots": null,
      "filledBy": null,
      "snippet": null,
      "analysisIndex": null
    },
    {
      "name": "monto_pena_letra",
      "label": "Monto Pena Letra",
      "type": "text",
      "required": true,
      "defaultValue": null,
      "options": null,
      "role": null,
      "source": null,
      "page": null,
      "rect": null,
      "slots": null,
      "filledBy": null,
      "snippet": null,
      "analysisIndex": null
    },
    {
      "name": "objeto_relacion",
      "label": "Objeto Relacion",
      "type": "text",
      "required": true,
      "defaultValue": null,
      "options": null,
      "role": null,
      "source": null,
      "page": null,
      "rect": null,
      "slots": null,
      "filledBy": null,
      "snippet": null,
      "analysisIndex": null
    },
    {
      "name": "parte_a__domicilio",
      "label": "Domicilio",
      "type": "textarea",
      "required": true,
      "defaultValue": null,
      "options": null,
      "role": "Parte A",
      "source": null,
      "page": null,
      "rect": null,
      "slots": null,
      "filledBy": null,
      "snippet": null,
      "analysisIndex": null
    },
    {
      "name": "parte_a__email",
      "label": "Email",
      "type": "text",
      "required": true,
      "defaultValue": null,
      "options": null,
      "role": "Parte A",
      "source": null,
      "page": null,
      "rect": null,
      "slots": null,
      "filledBy": null,
      "snippet": null,
      "analysisIndex": null
    },
    {
      "name": "parte_a__nombre",
      "label": "Nombre",
      "type": "text",
      "required": true,
      "defaultValue": null,
      "options": null,
      "role": "Parte A",
      "source": null,
      "page": null,
      "rect": null,
      "slots": null,
      "filledBy": null,
      "snippet": null,
      "analysisIndex": null
    },
    {
      "name": "parte_a__representante",
      "label": "Representante",
      "type": "text",
      "required": true,
      "defaultValue": null,
      "options": null,
      "role": "Parte A",
      "source": null,
      "page": null,
      "rect": null,
      "slots": null,
      "filledBy": null,
      "snippet": null,
      "analysisIndex": null
    },
    {
      "name": "parte_a__rfc",
      "label": "Rfc",
      "type": "text",
      "required": true,
      "defaultValue": null,
      "options": null,
      "role": "Parte A",
      "source": null,
      "page": null,
      "rect": null,
      "slots": null,
      "filledBy": null,
      "snippet": null,
      "analysisIndex": null
    },
    {
      "name": "parte_a__telefono",
      "label": "Telefono",
      "type": "text",
      "required": true,
      "defaultValue": null,
      "options": null,
      "role": "Parte A",
      "source": null,
      "page": null,
      "rect": null,
      "slots": null,
      "filledBy": null,
      "snippet": null,
      "analysisIndex": null
    },
    {
      "name": "parte_b__domicilio",
      "label": "Domicilio",
      "type": "textarea",
      "required": true,
      "defaultValue": null,
      "options": null,
      "role": "Parte B",
      "source": null,
      "page": null,
      "rect": null,
      "slots": null,
      "filledBy": null,
      "snippet": null,
      "analysisIndex": null
    },
    {
      "name": "parte_b__email",
      "label": "Email",
      "type": "text",
      "required": true,
      "defaultValue": null,
      "options": null,
      "role": "Parte B",
      "source": null,
      "page": null,
      "rect": null,
      "slots": null,
      "filledBy": null,
      "snippet": null,
      "analysisIndex": null
    },
    {
      "name": "parte_b__nombre",
      "label": "Nombre",
      "type": "text",
      "required": true,
      "defaultValue": null,
      "options": null,
      "role": "Parte B",
      "source": null,
      "page": null,
      "rect": null,
      "slots": null,
      "filledBy": null,
      "snippet": null,
      "analysisIndex": null
    },
    {
      "name": "parte_b__representante",
      "label": "Representante",
      "type": "text",
      "required": true,
      "defaultValue": null,
      "options": null,
      "role": "Parte B",
      "source": null,
      "page": null,
      "rect": null,
      "slots": null,
      "filledBy": null,
      "snippet": null,
      "analysisIndex": null
    },
    {
      "name": "parte_b__rfc",
      "label": "Rfc",
      "type": "text",
      "required": true,
      "defaultValue": null,
      "options": null,
      "role": "Parte B",
      "source": null,
      "page": null,
      "rect": null,
      "slots": null,
      "filledBy": null,
      "snippet": null,
      "analysisIndex": null
    },
    {
      "name": "parte_b__telefono",
      "label": "Telefono",
      "type": "text",
      "required": true,
      "defaultValue": null,
      "options": null,
      "role": "Parte B",
      "source": null,
      "page": null,
      "rect": null,
      "slots": null,
      "filledBy": null,
      "snippet": null,
      "analysisIndex": null
    },
    {
      "name": "tipo_informacion_confidencial",
      "label": "Tipo Informacion Confidencial",
      "type": "text",
      "required": true,
      "defaultValue": null,
      "options": null,
      "role": null,
      "source": null,
      "page": null,
      "rect": null,
      "slots": null,
      "filledBy": null,
      "snippet": null,
      "analysisIndex": null
    },
    {
      "name": "vigencia",
      "label": "Vigencia",
      "type": "text",
      "required": true,
      "defaultValue": null,
      "options": null,
      "role": null,
      "source": null,
      "page": null,
      "rect": null,
      "slots": null,
      "filledBy": null,
      "snippet": null,
      "analysisIndex": null
    },
    {
      "name": "vigencia_post_terminacion",
      "label": "Vigencia Post Terminacion",
      "type": "text",
      "required": true,
      "defaultValue": null,
      "options": null,
      "role": null,
      "source": null,
      "page": null,
      "rect": null,
      "slots": null,
      "filledBy": null,
      "snippet": null,
      "analysisIndex": null
    }
  ],
  "hasMore": false
}
```

## 4 Prueba unos valores sin crear nada

POST `/templates/{template_id}/validate-values` [ver en la referencia](https://allsign.io/developers/docs/endpoints/templates#validate-template-values)

### 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"]`

**cURL**

```
curl -X POST 'https://api.allsign.io/v3/templates/tmpl_67fb98658fe548d3a71eae28087d7060/validate-values' \
  -H "Authorization: Bearer $ALLSIGN_API_KEY" \
  -H "AllSign-Version: 2026-07-11" \
  -H "Content-Type: application/json" \
  -d '{
  "templateValues": {
    "folio_acuerdo": "NDA-2026-014",
    "fecha_celebracion": "mañana",
    "ciudad_celebracion": "Ciudad de México",
    "objeto_relacion": "una integración de firma electrónica",
    "tipo_informacion_confidencial": "técnica, comercial y financiera",
    "vigencia": "2 años",
    "vigencia_post_terminacion": "3 años",
    "monto_pena": "cien mil",
    "monto_pena_letra": "doscientos cincuenta mil pesos 00/100 M.N.",
    "jurisdiccion": "Ciudad de México",
    "parte_a__nombre": "Comercializadora Ejemplo SA de CV",
    "parte_a__rfc": "CEJ200101AB1",
    "parte_a__domicilio": "Av. Reforma 100, Cuauhtémoc, Ciudad de México",
    "parte_a__representante": "Ana Torres",
    "parte_a__email": "contacto@ejemplo.com",
    "parte_a__telefono": "+525555550001",
    "parte_b__nombre": "Servicios Muestra SC",
    "parte_b__rfc": "SMU190505CD2",
    "parte_b__domicilio": "Insurgentes Sur 200, Benito Juárez, Ciudad de México",
    "parte_b__representante": "Luis Ramírez",
    "parte_b__email": "legal@ejemplo.com",
    "parte_b__telefono": "+525555550002",
    "numero_cliente": "C-0042"
  }
}'
```

**Node**

```
const respuesta = await fetch('https://api.allsign.io/v3/templates/tmpl_67fb98658fe548d3a71eae28087d7060/validate-values', {
    method: 'POST',
    headers: {
        Authorization: `Bearer ${process.env.ALLSIGN_API_KEY}`,
        'AllSign-Version': '2026-07-11',
        'Content-Type': 'application/json',
    },
    body: JSON.stringify({
        templateValues: {
            folio_acuerdo: 'NDA-2026-014',
            fecha_celebracion: 'mañana',
            ciudad_celebracion: 'Ciudad de México',
            objeto_relacion: 'una integración de firma electrónica',
            tipo_informacion_confidencial: 'técnica, comercial y financiera',
            vigencia: '2 años',
            vigencia_post_terminacion: '3 años',
            monto_pena: 'cien mil',
            monto_pena_letra: 'doscientos cincuenta mil pesos 00/100 M.N.',
            jurisdiccion: 'Ciudad de México',
            parte_a__nombre: 'Comercializadora Ejemplo SA de CV',
            parte_a__rfc: 'CEJ200101AB1',
            parte_a__domicilio: 'Av. Reforma 100, Cuauhtémoc, Ciudad de México',
            parte_a__representante: 'Ana Torres',
            parte_a__email: 'contacto@ejemplo.com',
            parte_a__telefono: '+525555550001',
            parte_b__nombre: 'Servicios Muestra SC',
            parte_b__rfc: 'SMU190505CD2',
            parte_b__domicilio: 'Insurgentes Sur 200, Benito Juárez, Ciudad de México',
            parte_b__representante: 'Luis Ramírez',
            parte_b__email: 'legal@ejemplo.com',
            parte_b__telefono: '+525555550002',
            numero_cliente: 'C-0042',
        },
    }),
});
console.log(respuesta.status, await respuesta.json());
```

**Python**

```
import os

import requests

respuesta = requests.post(
    "https://api.allsign.io/v3/templates/tmpl_67fb98658fe548d3a71eae28087d7060/validate-values",
    headers={
        "Authorization": f"Bearer {os.environ['ALLSIGN_API_KEY']}",
        "AllSign-Version": "2026-07-11",
    },
    json={
        "templateValues": {
            "folio_acuerdo": "NDA-2026-014",
            "fecha_celebracion": "mañana",
            "ciudad_celebracion": "Ciudad de México",
            "objeto_relacion": "una integración de firma electrónica",
            "tipo_informacion_confidencial": "técnica, comercial y financiera",
            "vigencia": "2 años",
            "vigencia_post_terminacion": "3 años",
            "monto_pena": "cien mil",
            "monto_pena_letra": "doscientos cincuenta mil pesos 00/100 M.N.",
            "jurisdiccion": "Ciudad de México",
            "parte_a__nombre": "Comercializadora Ejemplo SA de CV",
            "parte_a__rfc": "CEJ200101AB1",
            "parte_a__domicilio": "Av. Reforma 100, Cuauhtémoc, Ciudad de México",
            "parte_a__representante": "Ana Torres",
            "parte_a__email": "contacto@ejemplo.com",
            "parte_a__telefono": "+525555550001",
            "parte_b__nombre": "Servicios Muestra SC",
            "parte_b__rfc": "SMU190505CD2",
            "parte_b__domicilio": "Insurgentes Sur 200, Benito Juárez, Ciudad de México",
            "parte_b__representante": "Luis Ramírez",
            "parte_b__email": "legal@ejemplo.com",
            "parte_b__telefono": "+525555550002",
            "numero_cliente": "C-0042",
        },
    },
)
print(respuesta.status_code, respuesta.json())
```

**Respuesta · 200**

```
{
  "livemode": false,
  "object": "template_values_validation",
  "templateId": "tmpl_67fb98658fe548d3a71eae28087d7060",
  "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."
    }
  ],
  "warnings": [],
  "ignored": [
    "numero_cliente"
  ]
}
```

## 5 Valida los valores completos

POST `/templates/{template_id}/validate-values` [ver en la referencia](https://allsign.io/developers/docs/endpoints/templates#validate-template-values)

### Qué haces

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

### Qué mirar

-   `valid` = `true`

**cURL**

```
curl -X POST 'https://api.allsign.io/v3/templates/tmpl_67fb98658fe548d3a71eae28087d7060/validate-values' \
  -H "Authorization: Bearer $ALLSIGN_API_KEY" \
  -H "AllSign-Version: 2026-07-11" \
  -H "Content-Type: application/json" \
  -d '{
  "templateValues": {
    "folio_acuerdo": "NDA-2026-014",
    "fecha_celebracion": "2026-07-11",
    "ciudad_celebracion": "Ciudad de México",
    "objeto_relacion": "una integración de firma electrónica",
    "tipo_informacion_confidencial": "técnica, comercial y financiera",
    "vigencia": "2 años",
    "vigencia_post_terminacion": "3 años",
    "monto_pena": "250000",
    "monto_pena_letra": "doscientos cincuenta mil pesos 00/100 M.N.",
    "jurisdiccion": "Ciudad de México",
    "parte_a__nombre": "Comercializadora Ejemplo SA de CV",
    "parte_a__rfc": "CEJ200101AB1",
    "parte_a__domicilio": "Av. Reforma 100, Cuauhtémoc, Ciudad de México",
    "parte_a__representante": "Ana Torres",
    "parte_a__email": "contacto@ejemplo.com",
    "parte_a__telefono": "+525555550001",
    "parte_b__nombre": "Servicios Muestra SC",
    "parte_b__rfc": "SMU190505CD2",
    "parte_b__domicilio": "Insurgentes Sur 200, Benito Juárez, Ciudad de México",
    "parte_b__representante": "Luis Ramírez",
    "parte_b__email": "legal@ejemplo.com",
    "parte_b__telefono": "+525555550002"
  }
}'
```

**Node**

```
const respuesta = await fetch('https://api.allsign.io/v3/templates/tmpl_67fb98658fe548d3a71eae28087d7060/validate-values', {
    method: 'POST',
    headers: {
        Authorization: `Bearer ${process.env.ALLSIGN_API_KEY}`,
        'AllSign-Version': '2026-07-11',
        'Content-Type': 'application/json',
    },
    body: JSON.stringify({
        templateValues: {
            folio_acuerdo: 'NDA-2026-014',
            fecha_celebracion: '2026-07-11',
            ciudad_celebracion: 'Ciudad de México',
            objeto_relacion: 'una integración de firma electrónica',
            tipo_informacion_confidencial: 'técnica, comercial y financiera',
            vigencia: '2 años',
            vigencia_post_terminacion: '3 años',
            monto_pena: '250000',
            monto_pena_letra: 'doscientos cincuenta mil pesos 00/100 M.N.',
            jurisdiccion: 'Ciudad de México',
            parte_a__nombre: 'Comercializadora Ejemplo SA de CV',
            parte_a__rfc: 'CEJ200101AB1',
            parte_a__domicilio: 'Av. Reforma 100, Cuauhtémoc, Ciudad de México',
            parte_a__representante: 'Ana Torres',
            parte_a__email: 'contacto@ejemplo.com',
            parte_a__telefono: '+525555550001',
            parte_b__nombre: 'Servicios Muestra SC',
            parte_b__rfc: 'SMU190505CD2',
            parte_b__domicilio: 'Insurgentes Sur 200, Benito Juárez, Ciudad de México',
            parte_b__representante: 'Luis Ramírez',
            parte_b__email: 'legal@ejemplo.com',
            parte_b__telefono: '+525555550002',
        },
    }),
});
console.log(respuesta.status, await respuesta.json());
```

**Python**

```
import os

import requests

respuesta = requests.post(
    "https://api.allsign.io/v3/templates/tmpl_67fb98658fe548d3a71eae28087d7060/validate-values",
    headers={
        "Authorization": f"Bearer {os.environ['ALLSIGN_API_KEY']}",
        "AllSign-Version": "2026-07-11",
    },
    json={
        "templateValues": {
            "folio_acuerdo": "NDA-2026-014",
            "fecha_celebracion": "2026-07-11",
            "ciudad_celebracion": "Ciudad de México",
            "objeto_relacion": "una integración de firma electrónica",
            "tipo_informacion_confidencial": "técnica, comercial y financiera",
            "vigencia": "2 años",
            "vigencia_post_terminacion": "3 años",
            "monto_pena": "250000",
            "monto_pena_letra": "doscientos cincuenta mil pesos 00/100 M.N.",
            "jurisdiccion": "Ciudad de México",
            "parte_a__nombre": "Comercializadora Ejemplo SA de CV",
            "parte_a__rfc": "CEJ200101AB1",
            "parte_a__domicilio": "Av. Reforma 100, Cuauhtémoc, Ciudad de México",
            "parte_a__representante": "Ana Torres",
            "parte_a__email": "contacto@ejemplo.com",
            "parte_a__telefono": "+525555550001",
            "parte_b__nombre": "Servicios Muestra SC",
            "parte_b__rfc": "SMU190505CD2",
            "parte_b__domicilio": "Insurgentes Sur 200, Benito Juárez, Ciudad de México",
            "parte_b__representante": "Luis Ramírez",
            "parte_b__email": "legal@ejemplo.com",
            "parte_b__telefono": "+525555550002",
        },
    },
)
print(respuesta.status_code, respuesta.json())
```

**Respuesta · 200**

```
{
  "livemode": false,
  "object": "template_values_validation",
  "templateId": "tmpl_67fb98658fe548d3a71eae28087d7060",
  "valid": true,
  "errors": [],
  "warnings": [],
  "ignored": []
}
```

## 6 Crea el documento con un firmante por rol

POST `/documents` [ver en la referencia](https://allsign.io/developers/docs/endpoints/documents#create-document)

### 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`

**cURL**

```
curl -X POST 'https://api.allsign.io/v3/documents' \
  -H "Authorization: Bearer $ALLSIGN_API_KEY" \
  -H "AllSign-Version: 2026-07-11" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{
  "templateId": "tmpl_67fb98658fe548d3a71eae28087d7060",
  "name": "Acuerdo de confidencialidad NDA-2026-014",
  "templateValues": {
    "folio_acuerdo": "NDA-2026-014",
    "fecha_celebracion": "2026-07-11",
    "ciudad_celebracion": "Ciudad de México",
    "objeto_relacion": "una integración de firma electrónica",
    "tipo_informacion_confidencial": "técnica, comercial y financiera",
    "vigencia": "2 años",
    "vigencia_post_terminacion": "3 años",
    "monto_pena": "250000",
    "monto_pena_letra": "doscientos cincuenta mil pesos 00/100 M.N.",
    "jurisdiccion": "Ciudad de México",
    "parte_a__nombre": "Comercializadora Ejemplo SA de CV",
    "parte_a__rfc": "CEJ200101AB1",
    "parte_a__domicilio": "Av. Reforma 100, Cuauhtémoc, Ciudad de México",
    "parte_a__representante": "Ana Torres",
    "parte_a__email": "contacto@ejemplo.com",
    "parte_a__telefono": "+525555550001",
    "parte_b__nombre": "Servicios Muestra SC",
    "parte_b__rfc": "SMU190505CD2",
    "parte_b__domicilio": "Insurgentes Sur 200, Benito Juárez, Ciudad de México",
    "parte_b__representante": "Luis Ramírez",
    "parte_b__email": "legal@ejemplo.com",
    "parte_b__telefono": "+525555550002"
  },
  "signers": [
    {
      "email": "signer-success@sandbox.allsign.io",
      "name": "Ana Torres",
      "roleName": "Parte A"
    },
    {
      "email": "ana@ejemplo.com",
      "name": "Luis Ramírez",
      "roleName": "Parte B"
    }
  ]
}'
```

**Node**

```
import { randomUUID } from 'node:crypto';

const respuesta = await fetch('https://api.allsign.io/v3/documents', {
    method: 'POST',
    headers: {
        Authorization: `Bearer ${process.env.ALLSIGN_API_KEY}`,
        'AllSign-Version': '2026-07-11',
        'Idempotency-Key': randomUUID(),
        'Content-Type': 'application/json',
    },
    body: JSON.stringify({
        templateId: 'tmpl_67fb98658fe548d3a71eae28087d7060',
        name: 'Acuerdo de confidencialidad NDA-2026-014',
        templateValues: {
            folio_acuerdo: 'NDA-2026-014',
            fecha_celebracion: '2026-07-11',
            ciudad_celebracion: 'Ciudad de México',
            objeto_relacion: 'una integración de firma electrónica',
            tipo_informacion_confidencial: 'técnica, comercial y financiera',
            vigencia: '2 años',
            vigencia_post_terminacion: '3 años',
            monto_pena: '250000',
            monto_pena_letra: 'doscientos cincuenta mil pesos 00/100 M.N.',
            jurisdiccion: 'Ciudad de México',
            parte_a__nombre: 'Comercializadora Ejemplo SA de CV',
            parte_a__rfc: 'CEJ200101AB1',
            parte_a__domicilio: 'Av. Reforma 100, Cuauhtémoc, Ciudad de México',
            parte_a__representante: 'Ana Torres',
            parte_a__email: 'contacto@ejemplo.com',
            parte_a__telefono: '+525555550001',
            parte_b__nombre: 'Servicios Muestra SC',
            parte_b__rfc: 'SMU190505CD2',
            parte_b__domicilio: 'Insurgentes Sur 200, Benito Juárez, Ciudad de México',
            parte_b__representante: 'Luis Ramírez',
            parte_b__email: 'legal@ejemplo.com',
            parte_b__telefono: '+525555550002',
        },
        signers: [
            {
                email: 'signer-success@sandbox.allsign.io',
                name: 'Ana Torres',
                roleName: 'Parte A',
            },
            {
                email: 'ana@ejemplo.com',
                name: 'Luis Ramírez',
                roleName: 'Parte B',
            },
        ],
    }),
});
console.log(respuesta.status, await respuesta.json());
```

**Python**

```
import os
import uuid

import requests

respuesta = requests.post(
    "https://api.allsign.io/v3/documents",
    headers={
        "Authorization": f"Bearer {os.environ['ALLSIGN_API_KEY']}",
        "AllSign-Version": "2026-07-11",
        "Idempotency-Key": str(uuid.uuid4()),
    },
    json={
        "templateId": "tmpl_67fb98658fe548d3a71eae28087d7060",
        "name": "Acuerdo de confidencialidad NDA-2026-014",
        "templateValues": {
            "folio_acuerdo": "NDA-2026-014",
            "fecha_celebracion": "2026-07-11",
            "ciudad_celebracion": "Ciudad de México",
            "objeto_relacion": "una integración de firma electrónica",
            "tipo_informacion_confidencial": "técnica, comercial y financiera",
            "vigencia": "2 años",
            "vigencia_post_terminacion": "3 años",
            "monto_pena": "250000",
            "monto_pena_letra": "doscientos cincuenta mil pesos 00/100 M.N.",
            "jurisdiccion": "Ciudad de México",
            "parte_a__nombre": "Comercializadora Ejemplo SA de CV",
            "parte_a__rfc": "CEJ200101AB1",
            "parte_a__domicilio": "Av. Reforma 100, Cuauhtémoc, Ciudad de México",
            "parte_a__representante": "Ana Torres",
            "parte_a__email": "contacto@ejemplo.com",
            "parte_a__telefono": "+525555550001",
            "parte_b__nombre": "Servicios Muestra SC",
            "parte_b__rfc": "SMU190505CD2",
            "parte_b__domicilio": "Insurgentes Sur 200, Benito Juárez, Ciudad de México",
            "parte_b__representante": "Luis Ramírez",
            "parte_b__email": "legal@ejemplo.com",
            "parte_b__telefono": "+525555550002",
        },
        "signers": [
            {
                "email": "signer-success@sandbox.allsign.io",
                "name": "Ana Torres",
                "roleName": "Parte A",
            },
            {
                "email": "ana@ejemplo.com",
                "name": "Luis Ramírez",
                "roleName": "Parte B",
            },
        ],
    },
)
print(respuesta.status_code, respuesta.json())
```

**Respuesta · 201**

```
{
  "livemode": false,
  "id": "doc_b5dcbda2f82c4b4fbec9cc944a7b2ea2",
  "object": "document",
  "name": "Acuerdo de confidencialidad NDA-2026-014",
  "status": "draft",
  "documentType": "EDITABLE",
  "signerCount": 2,
  "signedCount": 0,
  "ownerId": "usr_d7bbf7f00d864ba08c91c084a095f54a",
  "orgId": "d324ee92-d990-4d77-871e-f021a69be102",
  "folderId": null,
  "expiresAt": null,
  "signingOrder": "parallel",
  "currentStage": null,
  "expirationReminders": null,
  "templateId": "tmpl_67fb98658fe548d3a71eae28087d7060",
  "templateVersionId": null,
  "parentDocumentId": null,
  "createdAt": "2026-07-11T18:00:04.929000Z",
  "updatedAt": "2026-07-11T18:00:04.929000Z"
}
```

## 7 Envíalo a firma

POST `/documents/{document_id}/send` [ver en la referencia](https://allsign.io/developers/docs/endpoints/documents#send-document)

### 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.

**cURL**

```
curl -X POST 'https://api.allsign.io/v3/documents/doc_b5dcbda2f82c4b4fbec9cc944a7b2ea2/send' \
  -H "Authorization: Bearer $ALLSIGN_API_KEY" \
  -H "AllSign-Version: 2026-07-11" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{}'
```

**Node**

```
import { randomUUID } from 'node:crypto';

const respuesta = await fetch('https://api.allsign.io/v3/documents/doc_b5dcbda2f82c4b4fbec9cc944a7b2ea2/send', {
    method: 'POST',
    headers: {
        Authorization: `Bearer ${process.env.ALLSIGN_API_KEY}`,
        'AllSign-Version': '2026-07-11',
        'Idempotency-Key': randomUUID(),
        'Content-Type': 'application/json',
    },
    body: JSON.stringify({}),
});
console.log(respuesta.status, await respuesta.json());
```

**Python**

```
import os
import uuid

import requests

respuesta = requests.post(
    "https://api.allsign.io/v3/documents/doc_b5dcbda2f82c4b4fbec9cc944a7b2ea2/send",
    headers={
        "Authorization": f"Bearer {os.environ['ALLSIGN_API_KEY']}",
        "AllSign-Version": "2026-07-11",
        "Idempotency-Key": str(uuid.uuid4()),
    },
    json={},
)
print(respuesta.status_code, respuesta.json())
```

**Respuesta · 200**

```
{
  "livemode": false,
  "id": "doc_b5dcbda2f82c4b4fbec9cc944a7b2ea2",
  "object": "document",
  "name": "Acuerdo de confidencialidad NDA-2026-014",
  "status": "awaiting_signatures",
  "documentType": "EDITABLE",
  "signerCount": 2,
  "signedCount": 1,
  "ownerId": "usr_d7bbf7f00d864ba08c91c084a095f54a",
  "orgId": "d324ee92-d990-4d77-871e-f021a69be102",
  "folderId": null,
  "expiresAt": null,
  "signingOrder": "parallel",
  "currentStage": null,
  "expirationReminders": null,
  "templateId": "tmpl_67fb98658fe548d3a71eae28087d7060",
  "templateVersionId": null,
  "parentDocumentId": null,
  "createdAt": "2026-07-11T18:00:04.929000Z",
  "updatedAt": "2026-07-11T18:00:09.623000Z"
}
```

## 8 Revisa quién ya firmó

GET `/documents/{document_id}/signers` [ver en la referencia](https://allsign.io/developers/docs/endpoints/documents#list-signers)

### 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.

**cURL**

```
curl 'https://api.allsign.io/v3/documents/doc_b5dcbda2f82c4b4fbec9cc944a7b2ea2/signers' \
  -H "Authorization: Bearer $ALLSIGN_API_KEY" \
  -H "AllSign-Version: 2026-07-11"
```

**Node**

```
const respuesta = await fetch('https://api.allsign.io/v3/documents/doc_b5dcbda2f82c4b4fbec9cc944a7b2ea2/signers', {
    headers: {
        Authorization: `Bearer ${process.env.ALLSIGN_API_KEY}`,
        'AllSign-Version': '2026-07-11',
    },
});
console.log(respuesta.status, await respuesta.json());
```

**Python**

```
import os

import requests

respuesta = requests.get(
    "https://api.allsign.io/v3/documents/doc_b5dcbda2f82c4b4fbec9cc944a7b2ea2/signers",
    headers={
        "Authorization": f"Bearer {os.environ['ALLSIGN_API_KEY']}",
        "AllSign-Version": "2026-07-11",
    },
)
print(respuesta.status_code, respuesta.json())
```

**Respuesta · 200**

```
{
  "object": "list",
  "data": [
    {
      "livemode": false,
      "id": "sgr_520ef61be35f422387dcd6e215346e57",
      "object": "signer",
      "documentId": "doc_b5dcbda2f82c4b4fbec9cc944a7b2ea2",
      "email": "signer-success@sandbox.allsign.io",
      "phone": null,
      "name": "Ana Torres",
      "status": "signed",
      "signedAt": "2026-07-11T18:00:12.733000Z",
      "routingOrder": null,
      "delivery": null
    },
    {
      "livemode": false,
      "id": "sgr_1788e01c8b924179ae95ca736bbd2663",
      "object": "signer",
      "documentId": "doc_b5dcbda2f82c4b4fbec9cc944a7b2ea2",
      "email": "ana@ejemplo.com",
      "phone": null,
      "name": "Luis Ramírez",
      "status": "sent",
      "signedAt": null,
      "routingOrder": null,
      "delivery": null
    }
  ],
  "hasMore": false,
  "nextCursor": null,
  "previousCursor": null,
  "limit": null
}
```

## 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](https://allsign.io/developers/docs/errors).

`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](https://allsign.io/developers/docs/errors#VALIDATION_ERROR)

**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` · 8 oct 2026, 06:17 (hora CDMX) · 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](https://allsign.io/developers/docs/errors#TEMPLATE_NOT_FOUND)

**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` · 8 oct 2026, 06:17 (hora CDMX) · 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](https://allsign.io/developers/docs/errors#IDEMPOTENCY_KEY_REUSED)

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` · 8 oct 2026, 06:17 (hora CDMX) · test `docs-checks-v3/tests/recetas/documento-desde-plantilla-docx.receta.spec.ts`

## Siguiente

-   [Recibe y verifica los webhooks de AllSign](https://allsign.io/developers/docs/recetas/recibe-y-verifica-webhooks) — Un endpoint que recibe los eventos de AllSign, comprueba que de verdad los firmó AllSign y sobrevive a sus propias caídas y a la rotación del secreto.
