---
title: "Descarga el PDF firmado y su evidencia — Receta de la API v3 de AllSign"
type: how-to
canonical_url: "https://allsign.io/developers/docs/recetas/descarga-el-pdf-firmado-y-la-evidencia"
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:46.696Z"
---

Receta

# Descarga el PDF firmado y su evidencia

**Objetivo:** El PDF firmado y el PDF de evidencia de un documento completado, con su huella sha256 para archivarlos.

Para: integrador · nivel inicial · 5 min · Necesitas: API key de sandbox

## 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/descarga-el-pdf-firmado-y-la-evidencia.receta.spec.ts`

Ejemplo de sandbox: se grabó con una key de prueba y parte de lo que ves solo pasa así en sandbox; en producción el resultado puede ser distinto.

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 Crea el documento con su firmante

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

### Qué haces

El documento nace en draft. Guarda su id: lo vas a necesitar para pedir la evidencia y el PDF.

### Qué mirar en sandbox

-   `id` = `"doc_c18e3aaf505d4e8aa839591f6d38f7b9"`
-   `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 '{
  "name": "Contrato de servicios (sandbox)",
  "file": {
    "content": "'"$(base64 < contrato.pdf | tr -d '\n')"'",
    "fileType": "pdf",
    "name": "contrato.pdf"
  },
  "signers": [
    {
      "email": "signer-success@sandbox.allsign.io",
      "name": "Ana Torres"
    }
  ]
}'
```

**Node**

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

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({
        name: 'Contrato de servicios (sandbox)',
        file: {
            content: readFileSync('contrato.pdf').toString('base64'),
            fileType: 'pdf',
            name: 'contrato.pdf',
        },
        signers: [
            {
                email: 'signer-success@sandbox.allsign.io',
                name: 'Ana Torres',
            },
        ],
    }),
});
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/documents",
    headers={
        "Authorization": f"Bearer {os.environ['ALLSIGN_API_KEY']}",
        "AllSign-Version": "2026-07-11",
        "Idempotency-Key": str(uuid.uuid4()),
    },
    json={
        "name": "Contrato de servicios (sandbox)",
        "file": {
            "content": base64.b64encode(Path("contrato.pdf").read_bytes()).decode(),
            "fileType": "pdf",
            "name": "contrato.pdf",
        },
        "signers": [
            {
                "email": "signer-success@sandbox.allsign.io",
                "name": "Ana Torres",
            },
        ],
    },
)
print(respuesta.status_code, respuesta.json())
```

**Respuesta · 201**

```
{
  "livemode": false,
  "id": "doc_c18e3aaf505d4e8aa839591f6d38f7b9",
  "object": "document",
  "name": "Contrato de servicios (sandbox)",
  "status": "draft",
  "documentType": "EDITABLE",
  "signerCount": 1,
  "signedCount": 0,
  "ownerId": "usr_d6f2ef7bc72d4754940f12e71ad1964f",
  "orgId": "cc2dd4db-c027-496a-924f-bcdbb9b51387",
  "folderId": null,
  "expiresAt": null,
  "signingOrder": "parallel",
  "currentStage": null,
  "expirationReminders": null,
  "templateId": null,
  "templateVersionId": null,
  "parentDocumentId": null,
  "createdAt": "2026-07-11T18:00:00.000000Z",
  "updatedAt": "2026-07-11T18:00:00.000000Z"
}
```

## 2 Envíalo a firma

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

### Qué mirar

-   `status` = `"completed"`

### En producción

Aquí verás awaiting\_signatures y la evidencia estará lista cuando firme la última persona; te enterarás por el webhook document.completed. En sandbox signer-success@sandbox.allsign.io firma en segundos.

**cURL**

```
curl -X POST 'https://api.allsign.io/v3/documents/doc_c18e3aaf505d4e8aa839591f6d38f7b9/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_c18e3aaf505d4e8aa839591f6d38f7b9/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_c18e3aaf505d4e8aa839591f6d38f7b9/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_c18e3aaf505d4e8aa839591f6d38f7b9",
  "object": "document",
  "name": "Contrato de servicios (sandbox)",
  "status": "completed",
  "documentType": "EDITABLE",
  "signerCount": 1,
  "signedCount": 1,
  "ownerId": "usr_d6f2ef7bc72d4754940f12e71ad1964f",
  "orgId": "cc2dd4db-c027-496a-924f-bcdbb9b51387",
  "folderId": null,
  "expiresAt": null,
  "signingOrder": "parallel",
  "currentStage": null,
  "expirationReminders": null,
  "templateId": null,
  "templateVersionId": null,
  "parentDocumentId": null,
  "createdAt": "2026-07-11T18:00:00.000000Z",
  "updatedAt": "2026-07-11T18:00:01.978000Z"
}
```

## 3 Pide la evidencia

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

### Qué haces

Con available en true, evidencePdf.url es una liga firmada para descargar el PDF de evidencia sin la API key; vence, así que pídela cuando la vayas a usar. Guarda el sha256 junto al archivo para comprobar después que nadie lo cambió.

### Qué mirar

-   `available` = `true`
-   `evidencePdf.url` = `"<url-firmada>"`
-   `evidencePdf.sha256` = `"8a6bf4a711f5204bcce37981400b4a4030d969b33d24e7f2ad78748ca1e68725"`

**cURL**

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

**Node**

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

**Respuesta · 200**

```
{
  "livemode": false,
  "documentId": "doc_c18e3aaf505d4e8aa839591f6d38f7b9",
  "available": true,
  "evidencePdf": {
    "url": "<url-firmada>",
    "sha256": "8a6bf4a711f5204bcce37981400b4a4030d969b33d24e7f2ad78748ca1e68725"
  },
  "nom151": null,
  "reason": null,
  "signedCount": 1,
  "totalSigners": 1
}
```

## 4 Descarga el PDF firmado

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

### Qué haces

El documento con las firmas estampadas. La respuesta es el PDF mismo, no JSON: guárdalo tal cual.

**cURL**

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

**Node**

```
import { writeFileSync } from 'node:fs';

const respuesta = await fetch('https://api.allsign.io/v3/documents/doc_c18e3aaf505d4e8aa839591f6d38f7b9/file', {
    headers: {
        Authorization: `Bearer ${process.env.ALLSIGN_API_KEY}`,
        'AllSign-Version': '2026-07-11',
    },
});
writeFileSync('descarga.pdf', Buffer.from(await respuesta.arrayBuffer()));
```

**Python**

```
import os
from pathlib import Path

import requests

respuesta = requests.get(
    "https://api.allsign.io/v3/documents/doc_c18e3aaf505d4e8aa839591f6d38f7b9/file",
    headers={
        "Authorization": f"Bearer {os.environ['ALLSIGN_API_KEY']}",
        "AllSign-Version": "2026-07-11",
    },
)
Path("descarga.pdf").write_bytes(respuesta.content)
```

**Respuesta · 200**

```
<archivo application/pdf>
```

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

`INVALID_ID` · 400 · en el paso 3 (Pide la evidencia)

Pide la evidencia con un id incompleto. [Qué significa y qué hacer](https://allsign.io/developers/docs/errors#INVALID_ID)

**Respuesta · 400 · INVALID_ID**

```
{
  "type": "https://allsign.io/developers/docs/errors#INVALID_ID",
  "title": "Malformed identifier",
  "status": 400,
  "detail": "Invalid document id.",
  "instance": "/v3/documents/doc_123/evidence",
  "code": "INVALID_ID",
  "requestId": "req_8a1bc74e22d945a6ad9358d2f8b27ec2"
}
```

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/descarga-el-pdf-firmado-y-la-evidencia.receta.spec.ts`

`DOCUMENT_NOT_FOUND` · 404 · en el paso 4 (Descarga el PDF firmado)

Descarga el PDF de un documento que no existe o es de otra cuenta. [Qué significa y qué hacer](https://allsign.io/developers/docs/errors#DOCUMENT_NOT_FOUND)

**Respuesta · 404 · DOCUMENT_NOT_FOUND**

```
{
  "type": "https://allsign.io/developers/docs/errors#DOCUMENT_NOT_FOUND",
  "title": "Document not found",
  "status": 404,
  "detail": "Document not found",
  "instance": "/v3/documents/doc_9c9f2f6749794c8c8717b0fd5458f074/file",
  "code": "DOCUMENT_NOT_FOUND",
  "requestId": "req_9099fea09e7e4822a33e00dde0d7dc14"
}
```

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/descarga-el-pdf-firmado-y-la-evidencia.receta.spec.ts`

`DOCUMENT_NOT_FOUND` · 404 · en el paso 3 (Pide la evidencia)

Pide la evidencia de un documento que no existe o es de otra cuenta. [Qué significa y qué hacer](https://allsign.io/developers/docs/errors#DOCUMENT_NOT_FOUND)

**Respuesta · 404 · DOCUMENT_NOT_FOUND**

```
{
  "type": "https://allsign.io/developers/docs/errors#DOCUMENT_NOT_FOUND",
  "title": "Document not found",
  "status": 404,
  "detail": "No document was found with that id.",
  "instance": "/v3/documents/doc_9c9f2f6749794c8c8717b0fd5458f074/evidence",
  "code": "DOCUMENT_NOT_FOUND",
  "requestId": "req_f004c5b00c5e41eba0d4a03491fdf499"
}
```

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/descarga-el-pdf-firmado-y-la-evidencia.receta.spec.ts`
