---
title: "Prellena un formulario PDF y mándalo a firma — Receta de la API v3 de AllSign"
type: how-to
canonical_url: "https://allsign.io/developers/docs/recetas/formulario-pdf-acroform"
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:18:08.709Z"
---

Receta

# Prellena un formulario PDF y mándalo a firma

**Objetivo:** Un formulario PDF con sus campos prellenados, el RFC bloqueado y enviado a la persona que lo llena y firma.

Para: integrador · nivel intermedio · 10 min · Necesitas: API key de sandbox · Un PDF con campos de formulario (AcroForm): formulario.pdf

## 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:18 (hora CDMX) · test `docs-checks-v3/tests/recetas/formulario-pdf-acroform.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 el formulario como plantilla

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

### Qué haces

AllSign importa cada campo del formulario (los widgets del PDF) con su nombre y su tipo. Ya trae un rol (roleCount: 1) porque el PDF tiene una caja de firma llamada firma\_cliente. readiness en pending quiere decir que hay campos que todavía no son de nadie.

### Qué mirar

-   `id` = `"tmpl_39701d80589b412dbd39e02b48679840"`
-   `fieldCount` = `5`
-   `roleCount` = `1`
-   `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": "Solicitud de alta de cliente",
  "file": {
    "content": "'"$(base64 < formulario.pdf | tr -d '\n')"'",
    "fileType": "pdf",
    "name": "formulario.pdf"
  }
}'
```

**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: 'Solicitud de alta de cliente',
        file: {
            content: readFileSync('formulario.pdf').toString('base64'),
            fileType: 'pdf',
            name: 'formulario.pdf',
        },
    }),
});
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": "Solicitud de alta de cliente",
        "file": {
            "content": base64.b64encode(Path("formulario.pdf").read_bytes()).decode(),
            "fileType": "pdf",
            "name": "formulario.pdf",
        },
    },
)
print(respuesta.status_code, respuesta.json())
```

**Respuesta · 201**

```
{
  "livemode": false,
  "id": "tmpl_39701d80589b412dbd39e02b48679840",
  "object": "template",
  "name": "Solicitud de alta de cliente",
  "description": null,
  "fileType": "pdf",
  "originalFilename": "formulario.pdf",
  "aiEditable": true,
  "variableCount": 0,
  "fieldCount": 5,
  "unassignedFieldCount": 4,
  "roleCount": 1,
  "pendingCandidates": 0,
  "readiness": "pending",
  "tags": [],
  "category": null,
  "usageCount": 0,
  "lastUsedAt": null,
  "currentVersion": 1,
  "previewUrl": "/templates/tmpl_39701d80589b412dbd39e02b48679840/preview",
  "downloadUrl": "/templates/tmpl_39701d80589b412dbd39e02b48679840/download",
  "createdAt": "2026-07-11T18:00:00.000000Z",
  "updatedAt": "2026-07-11T18:00:00.000000Z"
}
```

## 2 Revisa los campos que importó

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

### Qué haces

La caja de firma ya es del rol Cliente, así que no tienes que declarar roles. Los otros cuatro campos (nombre, rfc, fecha y acepta) esperan a que digas quién los llena.

### Qué mirar

-   `unassignedCount` = `4`
-   `data.4.role` = `"Cliente"`

**cURL**

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

**Node**

```
const respuesta = await fetch('https://api.allsign.io/v3/templates/tmpl_39701d80589b412dbd39e02b48679840/fields', {
    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_39701d80589b412dbd39e02b48679840/fields",
    headers={
        "Authorization": f"Bearer {os.environ['ALLSIGN_API_KEY']}",
        "AllSign-Version": "2026-07-11",
    },
)
print(respuesta.status_code, respuesta.json())
```

**Respuesta · 200**

```
{
  "livemode": false,
  "object": "list",
  "templateId": "tmpl_39701d80589b412dbd39e02b48679840",
  "pageCount": 1,
  "data": [
    {
      "object": "template_field",
      "name": "nombre",
      "type": "text",
      "role": null,
      "required": true,
      "label": "Nombre",
      "options": null,
      "group": null,
      "source": "acroform",
      "value": null,
      "readOnly": false,
      "fixedWidth": false,
      "placeholder": null,
      "maxLength": null,
      "areas": [
        {
          "page": 1,
          "rect": {
            "x": 8.1699,
            "y": 10.101,
            "width": 40.8497,
            "height": 3.0303
          }
        }
      ]
    },
    {
      "object": "template_field",
      "name": "rfc",
      "type": "text",
      "role": null,
      "required": true,
      "label": "Rfc",
      "options": null,
      "group": null,
      "source": "acroform",
      "value": null,
      "readOnly": false,
      "fixedWidth": false,
      "placeholder": null,
      "maxLength": null,
      "areas": [
        {
          "page": 1,
          "rect": {
            "x": 8.1699,
            "y": 15.1515,
            "width": 40.8497,
            "height": 3.0303
          }
        }
      ]
    },
    {
      "object": "template_field",
      "name": "fecha",
      "type": "date",
      "role": null,
      "required": true,
      "label": "Fecha",
      "options": null,
      "group": null,
      "source": "acroform",
      "value": null,
      "readOnly": false,
      "fixedWidth": false,
      "placeholder": null,
      "maxLength": null,
      "areas": [
        {
          "page": 1,
          "rect": {
            "x": 8.1699,
            "y": 20.202,
            "width": 40.8497,
            "height": 3.0303
          }
        }
      ]
    },
    {
      "object": "template_field",
      "name": "acepta",
      "type": "checkbox",
      "role": null,
      "required": false,
      "label": "Acepta",
      "options": null,
      "group": null,
      "source": "acroform",
      "value": null,
      "readOnly": false,
      "fixedWidth": false,
      "placeholder": null,
      "maxLength": null,
      "areas": [
        {
          "page": 1,
          "rect": {
            "x": 8.1699,
            "y": 25.2525,
            "width": 3.5948,
            "height": 2.7778
          }
        }
      ]
    },
    {
      "object": "template_field",
      "name": "firma_cliente",
      "type": "signature",
      "role": "Cliente",
      "required": true,
      "label": null,
      "options": null,
      "group": null,
      "source": "acroform",
      "value": null,
      "readOnly": false,
      "fixedWidth": false,
      "placeholder": null,
      "maxLength": null,
      "areas": [
        {
          "page": 1,
          "rect": {
            "x": 8.1699,
            "y": 39.1414,
            "width": 40.8497,
            "height": 7.5758
          }
        }
      ]
    }
  ],
  "unassignedCount": 4,
  "hasMore": false
}
```

## 3 Asigna un campo al rol

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

### Qué haces

Repite esta llamada con rfc, fecha y acepta: cada campo dice qué rol lo llena. Un rol es un lugar en el formulario, no una persona; la persona se asigna al crear cada documento.

### Qué mirar

-   `name` = `"nombre"`
-   `role` = `"Cliente"`

**cURL**

```
curl -X PATCH 'https://api.allsign.io/v3/templates/tmpl_39701d80589b412dbd39e02b48679840/fields/nombre' \
  -H "Authorization: Bearer $ALLSIGN_API_KEY" \
  -H "AllSign-Version: 2026-07-11" \
  -H "Content-Type: application/json" \
  -d '{
  "role": "Cliente"
}'
```

**Node**

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

**Python**

```
import os

import requests

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

**Respuesta · 200**

```
{
  "object": "template_field",
  "name": "nombre",
  "type": "text",
  "role": "Cliente",
  "required": true,
  "label": "Nombre",
  "options": null,
  "group": null,
  "source": "acroform",
  "value": null,
  "readOnly": false,
  "fixedWidth": false,
  "placeholder": null,
  "maxLength": null,
  "areas": [
    {
      "page": 1,
      "rect": {
        "x": 8.1699,
        "y": 10.101,
        "width": 40.8497,
        "height": 3.0303
      }
    }
  ]
}
```

## 4 Confirma que la plantilla quedó lista

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

### Qué haces

Con todos los campos asignados, readiness pasa a ready.

### Qué mirar

-   `readiness` = `"ready"`

**cURL**

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

**Node**

```
const respuesta = await fetch('https://api.allsign.io/v3/templates/tmpl_39701d80589b412dbd39e02b48679840', {
    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_39701d80589b412dbd39e02b48679840",
    headers={
        "Authorization": f"Bearer {os.environ['ALLSIGN_API_KEY']}",
        "AllSign-Version": "2026-07-11",
    },
)
print(respuesta.status_code, respuesta.json())
```

**Respuesta · 200**

```
{
  "livemode": false,
  "id": "tmpl_39701d80589b412dbd39e02b48679840",
  "object": "template",
  "name": "Solicitud de alta de cliente",
  "description": null,
  "fileType": "pdf",
  "originalFilename": "formulario.pdf",
  "aiEditable": true,
  "variableCount": 0,
  "fieldCount": 5,
  "unassignedFieldCount": 0,
  "roleCount": 1,
  "pendingCandidates": 0,
  "readiness": "ready",
  "tags": [],
  "category": null,
  "usageCount": 0,
  "lastUsedAt": null,
  "currentVersion": 1,
  "previewUrl": "/templates/tmpl_39701d80589b412dbd39e02b48679840/preview",
  "downloadUrl": "/templates/tmpl_39701d80589b412dbd39e02b48679840/download",
  "createdAt": "2026-07-11T18:00:00.000000Z",
  "updatedAt": "2026-07-11T18:00:00.000000Z"
}
```

## 5 Crea el documento con valores y un campo bloqueado

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

### Qué haces

values prellena los campos por su nombre (texto o casilla) y readOnly bloquea los que el firmante no debe cambiar: aquí el RFC, que ya validaste de tu lado. Un nombre de campo que no existe se ignora sin error, así que revisa la ortografía contra la lista de campos.

### Qué mirar

-   `id` = `"doc_c8fee66bd4fb43ad9d928183b9ed7b38"`
-   `status` = `"draft"`

**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_39701d80589b412dbd39e02b48679840",
  "name": "Alta de cliente — Ana Torres",
  "signers": [
    {
      "roleName": "Cliente",
      "email": "ana@ejemplo.com",
      "name": "Ana Torres",
      "values": {
        "nombre": "Ana Torres",
        "rfc": "XAXX010101000",
        "acepta": true
      },
      "readOnly": [
        "rfc"
      ]
    }
  ]
}'
```

**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_39701d80589b412dbd39e02b48679840',
        name: 'Alta de cliente — Ana Torres',
        signers: [
            {
                roleName: 'Cliente',
                email: 'ana@ejemplo.com',
                name: 'Ana Torres',
                values: {
                    nombre: 'Ana Torres',
                    rfc: 'XAXX010101000',
                    acepta: true,
                },
                readOnly: [
                    'rfc',
                ],
            },
        ],
    }),
});
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_39701d80589b412dbd39e02b48679840",
        "name": "Alta de cliente — Ana Torres",
        "signers": [
            {
                "roleName": "Cliente",
                "email": "ana@ejemplo.com",
                "name": "Ana Torres",
                "values": {
                    "nombre": "Ana Torres",
                    "rfc": "XAXX010101000",
                    "acepta": True,
                },
                "readOnly": [
                    "rfc",
                ],
            },
        ],
    },
)
print(respuesta.status_code, respuesta.json())
```

**Respuesta · 201**

```
{
  "livemode": false,
  "id": "doc_c8fee66bd4fb43ad9d928183b9ed7b38",
  "object": "document",
  "name": "Alta de cliente — Ana Torres",
  "status": "draft",
  "documentType": "EDITABLE",
  "signerCount": 1,
  "signedCount": 0,
  "ownerId": "usr_106b50e8748a4364b28ac86e4bf5fe4f",
  "orgId": "5a0700dc-3921-4b6f-ace7-6f404f037808",
  "folderId": null,
  "expiresAt": null,
  "signingOrder": "parallel",
  "currentStage": null,
  "expirationReminders": null,
  "templateId": "tmpl_39701d80589b412dbd39e02b48679840",
  "templateVersionId": null,
  "parentDocumentId": null,
  "createdAt": "2026-07-11T18:00:03.973000Z",
  "updatedAt": "2026-07-11T18:00:03.973000Z"
}
```

## 6 Revisa cómo quedaron los campos

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

### Qué haces

filledBy en owner dice que el valor lo puso quien envía; la fecha queda vacía para que la llene el firmante.

### Qué mirar

-   `data.1.value` = `{"text":"XAXX010101000","checked":null}`
-   `data.1.readOnly` = `true`
-   `data.1.filledBy` = `"owner"`
-   `data.2.filledBy` = `null`

**cURL**

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

**Node**

```
const respuesta = await fetch('https://api.allsign.io/v3/documents/doc_c8fee66bd4fb43ad9d928183b9ed7b38/fields', {
    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_c8fee66bd4fb43ad9d928183b9ed7b38/fields",
    headers={
        "Authorization": f"Bearer {os.environ['ALLSIGN_API_KEY']}",
        "AllSign-Version": "2026-07-11",
    },
)
print(respuesta.status_code, respuesta.json())
```

**Respuesta · 200**

```
{
  "livemode": false,
  "object": "list",
  "documentId": "doc_c8fee66bd4fb43ad9d928183b9ed7b38",
  "data": [
    {
      "id": "fie_8f82e5aaf2314a5a8a672431087526c8",
      "object": "document_field",
      "name": "nombre",
      "type": "text",
      "role": "Cliente",
      "signerId": "sgr_3ecb998cf6cc48c6825fd665d73a2f07",
      "required": true,
      "label": "Nombre",
      "options": null,
      "group": null,
      "source": "template",
      "readOnly": false,
      "fixedWidth": false,
      "placeholder": null,
      "maxLength": null,
      "page": 1,
      "rect": {
        "x": 8.1699,
        "y": 10.101,
        "width": 40.8497,
        "height": 3.0303
      },
      "position": 1,
      "status": "pending",
      "value": {
        "text": "Ana Torres",
        "checked": null
      },
      "filledBy": "owner",
      "filledAt": "2026-07-11T18:00:04.611000Z"
    },
    {
      "id": "fie_7fcc5ad17fed4d1f90d1a5a209f5ce48",
      "object": "document_field",
      "name": "rfc",
      "type": "text",
      "role": "Cliente",
      "signerId": "sgr_3ecb998cf6cc48c6825fd665d73a2f07",
      "required": true,
      "label": "Rfc",
      "options": null,
      "group": null,
      "source": "template",
      "readOnly": true,
      "fixedWidth": false,
      "placeholder": null,
      "maxLength": null,
      "page": 1,
      "rect": {
        "x": 8.1699,
        "y": 15.1515,
        "width": 40.8497,
        "height": 3.0303
      },
      "position": 1,
      "status": "pending",
      "value": {
        "text": "XAXX010101000",
        "checked": null
      },
      "filledBy": "owner",
      "filledAt": "2026-07-11T18:00:04.611000Z"
    },
    {
      "id": "fie_e8291f03304c4ec7a815c3d93d55234d",
      "object": "document_field",
      "name": "fecha",
      "type": "date",
      "role": "Cliente",
      "signerId": "sgr_3ecb998cf6cc48c6825fd665d73a2f07",
      "required": true,
      "label": "Fecha",
      "options": null,
      "group": null,
      "source": "template",
      "readOnly": false,
      "fixedWidth": false,
      "placeholder": null,
      "maxLength": null,
      "page": 1,
      "rect": {
        "x": 8.1699,
        "y": 20.202,
        "width": 40.8497,
        "height": 3.0303
      },
      "position": 1,
      "status": "pending",
      "value": {
        "text": null,
        "checked": null
      },
      "filledBy": null,
      "filledAt": null
    },
    {
      "id": "fie_73c88511f9e3402c851a89be02643c27",
      "object": "document_field",
      "name": "acepta",
      "type": "checkbox",
      "role": "Cliente",
      "signerId": "sgr_3ecb998cf6cc48c6825fd665d73a2f07",
      "required": false,
      "label": "Acepta",
      "options": null,
      "group": null,
      "source": "template",
      "readOnly": false,
      "fixedWidth": false,
      "placeholder": null,
      "maxLength": null,
      "page": 1,
      "rect": {
        "x": 8.1699,
        "y": 25.2525,
        "width": 3.5948,
        "height": 2.7778
      },
      "position": 1,
      "status": "pending",
      "value": {
        "text": null,
        "checked": true
      },
      "filledBy": "owner",
      "filledAt": "2026-07-11T18:00:04.611000Z"
    },
    {
      "id": "fie_7d1dd7756041414193bc9f8c999cf86b",
      "object": "document_field",
      "name": "firma_cliente",
      "type": "signature",
      "role": "Cliente",
      "signerId": "sgr_3ecb998cf6cc48c6825fd665d73a2f07",
      "required": true,
      "label": null,
      "options": null,
      "group": null,
      "source": "template",
      "readOnly": false,
      "fixedWidth": false,
      "placeholder": null,
      "maxLength": null,
      "page": 1,
      "rect": {
        "x": 8.1699,
        "y": 39.1414,
        "width": 40.8497,
        "height": 7.5758
      },
      "position": 1,
      "status": "pending",
      "value": {
        "text": null,
        "checked": null
      },
      "filledBy": null,
      "filledAt": null
    }
  ],
  "unassignedCount": 0,
  "hasMore": false
}
```

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

La persona recibe su invitación, llena la fecha, ve el RFC sin poder cambiarlo y firma.

### 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_c8fee66bd4fb43ad9d928183b9ed7b38/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_c8fee66bd4fb43ad9d928183b9ed7b38/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_c8fee66bd4fb43ad9d928183b9ed7b38/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_c8fee66bd4fb43ad9d928183b9ed7b38",
  "object": "document",
  "name": "Alta de cliente — Ana Torres",
  "status": "awaiting_signatures",
  "documentType": "EDITABLE",
  "signerCount": 1,
  "signedCount": 0,
  "ownerId": "usr_106b50e8748a4364b28ac86e4bf5fe4f",
  "orgId": "5a0700dc-3921-4b6f-ace7-6f404f037808",
  "folderId": null,
  "expiresAt": null,
  "signingOrder": "parallel",
  "currentStage": null,
  "expirationReminders": null,
  "templateId": "tmpl_39701d80589b412dbd39e02b48679840",
  "templateVersionId": null,
  "parentDocumentId": null,
  "createdAt": "2026-07-11T18:00:03.973000Z",
  "updatedAt": "2026-07-11T18:00:06.682000Z"
}
```

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

`FIELD_NOT_FOUND` · 404 · en el paso 3 (Asigna un campo al rol)

Asigna un campo que no existe. [Qué significa y qué hacer](https://allsign.io/developers/docs/errors#FIELD_NOT_FOUND)

**Respuesta · 404 · FIELD_NOT_FOUND**

```
{
  "type": "https://allsign.io/developers/docs/errors#FIELD_NOT_FOUND",
  "title": "Not Found",
  "status": 404,
  "detail": "Field 'telefono_movil' not found in this template.",
  "instance": "/v3/templates/tmpl_24c55a589976432da1a168e3c4859ce6/fields/telefono_movil",
  "code": "FIELD_NOT_FOUND",
  "requestId": "req_06aa3c8f7ed843d0afa10acac48240e5"
}
```

Grabado en el entorno interno de AllSign con una key de sandbox · backend `24c0469` · 8 oct 2026, 06:18 (hora CDMX) · test `docs-checks-v3/tests/recetas/formulario-pdf-acroform.receta.spec.ts`

`DOCUMENT_CONFLICT` · 409 · en `PATCH /v3/documents/doc_6b7fc763d2bc430980ae397679f7a465/fields/fie_fb20c7c439fc4902b6b6bbc9bbca55cc`

Corrige un campo de un documento anulado. [Qué significa y qué hacer](https://allsign.io/developers/docs/errors#DOCUMENT_CONFLICT)

**Respuesta · 409 · DOCUMENT_CONFLICT**

```
{
  "type": "https://allsign.io/developers/docs/errors#DOCUMENT_CONFLICT",
  "title": "Conflict",
  "status": 409,
  "detail": "Este documento ya terminó (ANULADO): sus campos ya no se pueden crear, mover, reasignar ni borrar.",
  "instance": "/v3/documents/doc_6b7fc763d2bc430980ae397679f7a465/fields/fie_fb20c7c439fc4902b6b6bbc9bbca55cc",
  "code": "DOCUMENT_CONFLICT",
  "requestId": "req_55b09c55654746338f3f811e0ced82a7",
  "reason": "document_terminal"
}
```

Grabado en el entorno interno de AllSign con una key de sandbox · backend `24c0469` · 8 oct 2026, 06:18 (hora CDMX) · test `docs-checks-v3/tests/recetas/formulario-pdf-acroform.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.
-   [Crea un contrato desde tu plantilla de Word](https://allsign.io/developers/docs/recetas/documento-desde-plantilla-docx) — Un acuerdo de confidencialidad generado desde tu plantilla DOCX, con los datos de cada parte en su lugar y enviado a firma.
