API de documentos
La API de documentos rellena una plantilla con los datos que envía en JSON (desde un ERP, un formulario web o un script) sin que haya ningún registro detrás. Recibe un enlace al documento terminado, en el formato de salida de la plantilla o en el que pida.
Funciona con cualquier tipo de plantilla. La fuente de datos propia de la plantilla simplemente no se usa: el JSON que envía es el registro.
Autenticación
Sección titulada «Autenticación»Envíe una clave de API en el encabezado X-Webhook-API-Key. Sirven dos tipos de clave:
- La clave propia de la plantilla: en la pestaña Plantilla, en API de documentos (es la misma clave que la del HTTP Trigger). Da acceso a esa plantilla.
- Una clave de API de la empresa: la crea un administrador en el Portal de empresa (en una empresa de Lark, un administrador de la app de Lark), en Empresa → Claves de API. Da acceso a todas las plantillas de su empresa. Solo se muestra una vez, al crearla; guárdela como si fuera una contraseña. Las plantillas de aprobación no tienen clave propia, así que para ellas use una clave de la empresa.
Si revoca una clave de la empresa o restablece la clave de una plantilla, deja de funcionar al instante.
Crear documentos
Sección titulada «Crear documentos»POST https://api.automadoc.cc/api/v1/templates/{templateId}/documentsEl id de la plantilla aparece en el endpoint que muestra la tarjeta API de documentos de la plantilla.
| Campo | Obligatorio | Qué hace |
|---|---|---|
data |
sí | El registro: sus claves son los marcadores. Una lista de objetos genera un documento por elemento o, si la plantilla crea un documento a partir de muchos registros, un solo documento con todos ellos (consulte Varios documentos a la vez). |
format |
no | "pdf", "png" (la primera página como imagen) o "native" (el archivo propio de la plantilla, p. ej. .docx). Por defecto, el que tenga configurado la plantilla. |
filename |
no | Un patrón de nombre de archivo para esta solicitud, con marcadores {Field}, en lugar del de la plantilla. |
recordId |
no | Lo que imprime {Record_ID}, para un solo documento. Por defecto, el id del documento. |
mode |
no | "separate", "list", "continuous" o "labels": lo que genera la plantilla, enviado como comprobación. Si se omite, decide la plantilla (consulte Varios documentos a la vez). |
Añada ?wait=20 (hasta 25 segundos) para que la respuesta espere a que el documento esté listo y le baste con una sola solicitud. Sin él, la respuesta llega de inmediato y usted consulta la URL de estado.
Las herramientas de flujos de trabajo que siguen la convención de sondeo 202 + Location (Power Automate, Logic Apps y similares) pueden añadir ?async=true en su lugar: mientras se crea el documento, la respuesta 202 incluye una cabecera Location que consultar y una cabecera Retry-After (5 segundos). Esa ubicación responde 202 hasta que el documento se completa (200) o falla (422, con "code": "DOCUMENT_FAILED" y el motivo en error). Un documento que ya ha fallado cuando se responde a la solicitud recibe ese 422 de inmediato. El endpoint de estado también acepta ?async=true. async sigue un solo documento, así que no puede usarse con una lista en data para una plantilla que crea un documento por elemento (INVALID_ASYNC). El conector de Power Automate lo utiliza.
Respuesta: 202 Accepted mientras se crea el documento, 200 OK si con wait ha terminado:
{ "generationId": "5d2f0c1e-6a1b-4c7e-9f0a-2b8c3d4e5f60", "templateId": "9b1c…", "status": "processing", "statusUrl": "https://api.automadoc.cc/api/v1/documents/5d2f0c1e-6a1b-4c7e-9f0a-2b8c3d4e5f60", "createdAt": 1791878400000}Obtener un documento
Sección titulada «Obtener un documento»GET https://api.automadoc.cc/api/v1/documents/{generationId}Use la misma clave que en la solicitud. status es processing, completed o failed:
{ "generationId": "5d2f0c1e-6a1b-4c7e-9f0a-2b8c3d4e5f60", "status": "completed", "filename": "Invoice-INV-2026-001.pdf", "downloadUrl": "https://api.automadoc.cc/api/generations/…/download?expires=…&signature=…", "downloadUrlExpiresAt": 1792137600000}El downloadUrl no necesita clave. Sigue siendo válido mientras su empresa conserve los documentos generados (según su plan), o 30 días si se conservan indefinidamente, y deja de funcionar cuando se elimina el documento. Cada consulta del estado devuelve un enlace nuevo. Un documento failed incluye un error con el motivo. Un documento completado puede incluir warnings: lo que se quedó fuera, como una imagen cuya URL no se pudo obtener, indicada por su campo y el host de la URL. Los marcadores para los que sus datos no tenían valor se enumeran juntos en una sola línea («3 fields had no value in the data: …»), después de las demás advertencias.
Este endpoint también informa de los documentos iniciados por el HTTP Trigger: su respuesta enumera sus generationIds.
Una clave solo ve los documentos de las plantillas a las que da acceso. Los documentos generados a mano en la extensión no son visibles a través de la API.
Descargar el archivo con la clave
Sección titulada «Descargar el archivo con la clave»GET https://api.automadoc.cc/api/v1/documents/{generationId}/fileEl propio archivo terminado, con la misma clave, para una herramienta que recibe un archivo en lugar de un enlace. Responde 409 con DOCUMENT_NOT_READY mientras se crea el documento, 422 con DOCUMENT_FAILED y el motivo en error si ha fallado, y 404 con DOCUMENT_FILE_MISSING cuando la retención de su empresa ya ha eliminado el archivo. Content-Type y Content-Disposition (el nombre del archivo) lo describen.
Listar las plantillas y sus datos
Sección titulada «Listar las plantillas y sus datos»GET https://api.automadoc.cc/api/v1/templatesGET https://api.automadoc.cc/api/v1/templates/{templateId}La primera enumera todas las plantillas de su empresa: id, name, source (base o approval), templateFormat, mode (lo que crea una solicitud, como en Varios documentos a la vez), outputFormat y ready (false mientras una plantilla no tiene archivo o tiene errores que corregir). Necesita una clave de API de la empresa; la clave propia de una plantilla se rechaza con COMPANY_KEY_REQUIRED.
La segunda describe una plantilla (sirve cualquiera de las dos claves) y añade dataSchema, un esquema JSON de los data que admite (una propiedad por marcador: texto, un número o la URL de una imagen, un sí/no para una condición, una lista para un bucle), sampleData y documentsUrl. Las herramientas de flujos de trabajo lo usan para mostrar un campo por marcador.
La descripción completa de estas rutas es un documento OpenAPI en https://api.automadoc.cc/api/v1/openapi.json.
Cómo rellenan sus datos la plantilla
Sección titulada «Cómo rellenan sus datos la plantilla»Nombres. Cada clave se convierte en un nombre de marcador exactamente igual que el nombre de un campo de Base: los espacios, los puntos y demás símbolos pasan a ser _, se conservan las letras y los dígitos de cualquier idioma, y se distingue entre mayúsculas y minúsculas.
| Clave que envía | Marcador que rellena |
|---|---|
"Customer" |
{Customer} |
"Invoice No." |
{Invoice_No_} |
"Unit price" |
{Unit_price} |
"客户名称" |
{客户名称} |
Si dos claves del mismo objeto dan el mismo nombre ("Unit price" y "Unit-price"), la solicitud se rechaza con DATA_NAME_COLLISION en lugar de que una de ellas gane sin avisar.
Valores.
- Texto y números se imprimen tal como se envían. Los números siguen siendo números, así que filtros como
number,currencyysumfuncionan con ellos. true/falsefuncionan con condiciones:{#if Paid}…{/if}.nully una lista vacía no imprimen nada y cuentan como vacíos en{#if}.- Un objeto rellena marcadores con punto:
{"Customer": {"Name": "Acme"}}rellena{Customer.Name}. - Una lista de objetos es un bucle:
{"Items": [{"Product": "Pen", "Qty": 2}]}rellena{#Items}{Product} × {Qty}{/Items}. - Una lista de valores simples se imprime separada por comas:
["red", "blue"]imprimered, blue. - Imágenes: donde la plantilla tenga un marcador de imagen (una imagen cuyo texto alternativo es
{Logo}, también dentro de una fila de bucle), envíe una URLhttps://, o una lista de URL para{Photos[1]},{Photos[2]}. La URL debe ser accesible desde internet. En cualquier otro sitio, una URL es solo texto. - Adjuntos:
{ATTACH:Field}solo añade los archivos de un campo de adjuntos de una Base o de un formulario de aprobación. La API de documentos no puede enviarle archivos: no añade nada, y las URL enviadas para él se imprimen como texto. {QR:Field}y{BARCODE:Field}imprimen un código con el texto que envía.
Record_ID, Template_Name y Print_Time los define AutomaDoc; una clave con ese nombre se sustituye (la respuesta se lo advierte).
En una plantilla de aprobación, los nombres que debe enviar son las variables que aparecen en su página. Su nombre de archivo por defecto incluye la solicitud de aprobación, que el JSON no tiene, así que los documentos creados con la API se llaman {Template_Name}-{Record_ID} salvo que envíe filename.
Varios documentos a la vez
Sección titulada «Varios documentos a la vez»Envíe data como una lista de hasta 50 objetos para crear un documento por elemento. La respuesta los enumera:
{ "documents": [ { "generationId": "…", "status": "processing", "statusUrl": "…" }, … ] }Si se rechaza algún elemento, no se crea ninguno. recordId no se puede usar con una lista.
Un documento con todos los elementos
Sección titulada «Un documento con todos los elementos»Si la plantilla está configurada para crear un documento a partir de muchos registros, ya sea una lista, una página por registro o etiquetas, una lista en data genera un solo documento: cada elemento es un registro de su bucle {#Records}, una página o una etiqueta, en el orden enviado. Hasta 500 elementos; un único objeto genera un documento de un elemento. La respuesta es ese documento, con recordCount:
{ "generationId": "…", "status": "processing", "statusUrl": "…", "recordCount": 120 }{Record_ID}imprime la posición de cada elemento, de1al número de elementos.- El patrón de nombre de archivo lee el primer elemento, más
{RecordCount}y{Date}. Sin patrón, el documento se llama{Template_Name}-{Date}. "format": "png"genera un PDF: una imagen solo contendría la primera página.- Cuenta como un documento. En el límite de 600 documentos por minuto de la empresa cuenta uno por elemento si es una página por registro, y uno por cada diez elementos si es una lista o etiquetas.
- No se puede enviar para firmar (
ESIGN_COMBINED).
Decide el ajuste Registros por documento de la plantilla. Si envía mode ("separate" para un documento por elemento, o "list", "continuous" para una página por registro, o "labels") y la plantilla está configurada de otra forma, la solicitud se rechaza con MODE_MISMATCH en lugar de devolver un número de archivos distinto del que espera su script.
Ejemplo: curl
Sección titulada «Ejemplo: curl»curl -X POST 'https://api.automadoc.cc/api/v1/templates/TEMPLATE_ID/documents?wait=20' \ -H 'X-Webhook-API-Key: YOUR_API_KEY' \ -H 'Content-Type: application/json' \ -d '{ "data": { "Invoice No.": "INV-2026-001", "Customer": { "Name": "Acme Corp", "Address": "1 Main St" }, "Items": [ { "Product": "Consulting", "Qty": 10, "Price": 120 }, { "Product": "Travel", "Qty": 1, "Price": 340 } ], "Logo": "https://example.com/logo.png" }, "format": "pdf" }'La tarjeta API de documentos de la plantilla copia una solicitud como esta, creada a partir de los marcadores de la propia plantilla.
Ejemplo: Node.js
Sección titulada «Ejemplo: Node.js»const API = 'https://api.automadoc.cc'const headers = { 'X-Webhook-API-Key': process.env.AUTOMADOC_KEY, 'Content-Type': 'application/json' }
async function generate(templateId, data) { const res = await fetch(`${API}/api/v1/templates/${templateId}/documents?wait=20`, { method: 'POST', headers, body: JSON.stringify({ data, format: 'pdf' }), }) let doc = await res.json() if (!res.ok) throw new Error(`${doc.code}: ${doc.error}`)
// Still processing after the wait: poll the status URL. while (doc.status === 'processing') { await new Promise((r) => setTimeout(r, 2000)) doc = await (await fetch(doc.statusUrl, { headers })).json() } if (doc.status === 'failed') throw new Error(doc.error) return doc.downloadUrl}Enviar el documento para firmar
Sección titulada «Enviar el documento para firmar»Añada un bloque sign para enviar el documento a firmar en cuanto se genere. No cuesta nada aparte del documento.
sign funciona con una plantilla de Lark Base: una plantilla de Word con campos de firma (consulte Firma electrónica) que crea un documento por registro, con data enviado como un solo objeto. Cualquier otra plantilla lo rechaza con SIGN_BASE_TEMPLATES_ONLY: las plantillas de Excel, de listas de SharePoint, de Dataverse, de Google Sheets y las que solo usan la API, y también las plantillas de Lark Approval, que se firman en la propia aprobación. Solo una cuenta de Lark tiene plantillas de Lark Base, así que en una cuenta de Microsoft, de Google o de correo electrónico ninguna plantilla acepta sign.
{ "data": { "Customer": "Acme Corp" }, "sign": { "signers": { "Customer": { "name": "Budi Santoso", "contact": "budi@acme.example" }, "Supplier": { "larkUserId": "ou_1234…" } }, "order": "sequential" }}| Campo | Qué hace |
|---|---|
signers |
Un firmante por cada rol de firma de la plantilla, indicado por el nombre del rol. Todos los roles necesitan uno: no hay ningún registro del que leer un firmante. Alguien externo a su empresa es { "name", "contact"? }: un nombre y, opcionalmente, una nota de contacto que se guarda con la solicitud, como una dirección de correo electrónico (no se le envía nada). Un compañero es { "larkUserId" }: su open_id de Lark, para una persona de su empresa en Lark que usa AutomaDoc. |
order |
"parallel" (todos a la vez) o "sequential" (en el orden de la plantilla). Por defecto, el que tenga configurado la plantilla. |
generatePasswords |
Una contraseña generada para cada firmante externo. Por defecto true. |
locale |
Idioma de los mensajes del bot y de la página de auditoría, p. ej. "en". |
La solicitud de firma se inicia cuando el documento está listo. Los compañeros reciben un mensaje del bot de AutomaDoc en Lark. Los enlaces de los firmantes externos, y sus contraseñas generadas, se devuelven una sola vez, en la primera llamada a GET /api/v1/documents/{generationId} después de que se haya iniciado la solicitud:
{ "status": "completed", "signing": { "status": "started", "requestId": "…", "links": [{ "role": "Customer", "displayName": "Budi Santoso", "url": "https://…/sign/…", "password": "K7mQ…" }] }}Envíelos usted mismo, y la contraseña por separado si es posible. Las lecturas posteriores muestran las mismas entradas con url y password a null y "linksRedacted": true. Si se pierde un enlace, emita uno nuevo desde la página Firmas. signing.status es queued hasta que el documento está terminado, starting durante un momento mientras se abre la solicitud, y después started o failed (con un código de error).
sign se rechaza con una lista en data (SIGN_SINGLE_DOCUMENT) y en una plantilla que crea un documento a partir de muchos registros (ESIGN_COMBINED).
Cuando el documento está listo
Sección titulada «Cuando el documento está listo»Si la plantilla tiene un Callback de Webhook, también se llama para los documentos de la API, con el enlace de descarga, siempre que tenga Pro (o una prueba) o un puesto Business, como para todo documento automatizado.
Errores
Sección titulada «Errores»Cada rechazo incluye un code y un error en inglés:
| Estado | code |
Motivo |
|---|---|---|
| 400 | INVALID_JSON, DATA_REQUIRED, DATA_NOT_OBJECT |
El cuerpo no es JSON, no tiene data, o data no es un objeto ni una lista de objetos |
| 400 | DATA_NAME_COLLISION, DATA_INVALID_NAME |
Dos claves rellenan el mismo marcador; una clave no tiene ninguna letra ni dígito |
| 400 | DATA_MIXED_ARRAY |
Una lista mezcla objetos y valores simples |
| 400 | DATA_TOO_DEEP, DATA_ARRAY_TOO_LONG, DATA_TOO_MANY_KEYS, DATA_STRING_TOO_LONG |
Se supera un límite |
| 400 | IMAGE_URL_NOT_ALLOWED, TOO_MANY_IMAGES |
La URL de una imagen no es una dirección http(s) pública; demasiadas imágenes |
| 400 | BATCH_EMPTY, BATCH_TOO_LARGE |
Una lista vacía; más de 50 elementos (500 si la plantilla crea un documento a partir de muchos registros) |
| 400 | INVALID_FORMAT, INVALID_FILENAME, INVALID_RECORD_ID, INVALID_WAIT, INVALID_MODE, INVALID_ASYNC |
Una opción no es válida |
| 400 | TEMPLATE_VALIDATION_ERRORS |
El archivo de la plantilla tiene errores que hay que corregir antes (enumerados en validationErrors) |
| 400 | MODE_MISMATCH |
mode no es lo que genera la plantilla |
| 401 | API_KEY_MISSING |
Falta el encabezado X-Webhook-API-Key |
| 403 | API_KEY_INVALID |
La clave es incorrecta, está revocada o no da acceso a esta plantilla; también es la respuesta para un id de plantilla que no existe |
| 403 | QUOTA_EXCEEDED |
No quedan documentos este mes; compra un paquete o un puesto |
| 403 | TEMPLATE_DISABLED |
La plantilla supera el límite de plantillas de su plan |
| 403 | COMPANY_KEY_REQUIRED |
Para listar las plantillas hace falta una clave de API de la empresa, no la clave propia de una plantilla |
| 404 | TEMPLATE_NOT_FOUND, DOCUMENT_NOT_FOUND |
No existe esa plantilla o ese documento para esta clave |
| 404 | DOCUMENT_FILE_MISSING |
La retención de su empresa ha eliminado el archivo del documento |
| 409 | TEMPLATE_FILE_MISSING, TEMPLATE_NO_OWNER |
La plantilla aún no tiene archivo; no tiene propietario (ábrala y guárdela una vez, o use una clave de la empresa) |
| 409 | DOCUMENT_NOT_READY |
Se descarga el archivo de un documento que aún se está creando |
| 413 | BODY_TOO_LARGE |
El cuerpo supera 1 MB |
| 422 | DOCUMENT_FAILED |
Se descarga el archivo de un documento que ha fallado, o se envía una solicitud o se consulta el estado con async=true para uno; error indica el motivo |
| 429 | RATE_LIMITED |
Más de 60 solicitudes por minuto para una plantilla, 600 documentos por minuto para una empresa, 60 consultas de estado o 60 descargas por minuto para un documento, o 60 listados de plantillas por minuto para una empresa. Los documentos del HTTP Trigger cuentan para los 600 de la empresa; sus solicitudes tienen su propio límite de 300 por minuto por plantilla |
| 400 | SIGN_INVALID, SIGN_SINGLE_DOCUMENT, SIGN_BASE_TEMPLATES_ONLY |
El bloque sign no es válido, data es una lista o la plantilla no es una plantilla de Lark Base, así que sus documentos no se pueden enviar a firmar |
| 400, 409 | ESIGN_… |
Rechazado por la firma electrónica: ESIGN_ROLES_MISMATCH (un rol sin firmante, o un rol desconocido), ESIGN_SIGNER_FIELD (un firmante que se lee de un campo), ESIGN_INVALID_SIGNER (un larkUserId que no es un usuario de su empresa), ESIGN_NO_MASTER (la plantilla no tiene campos de firma), ESIGN_COMBINED (la plantilla crea un documento a partir de muchos registros), ESIGN_RECORD_UNREADABLE (la plantilla no tiene propietario en cuyo nombre enviar la solicitud) |
| 502 | WORKER_UNAVAILABLE |
No se pudo contactar con el servicio de documentos; inténtelo de nuevo en unos momentos |
| 503 | TEMPLATE_FORMAT_UNAVAILABLE |
La plantilla es un archivo de Excel o PowerPoint que el servicio de documentos aún no puede abrir; inténtelo más tarde |
| 503 | COMBINED_UNAVAILABLE |
Ahora no se puede crear un documento a partir de muchos registros; inténtelo más tarde |
| 503 | ATTACHMENTS_UNAVAILABLE |
La plantilla crea un documento a partir de muchos registros y añade adjuntos al PDF, algo que ahora no es posible; inténtelo más tarde |
Límites
Sección titulada «Límites»| Cuerpo de la solicitud | 1 MB |
| Documentos por solicitud | 50, o 500 elementos en un documento a partir de muchos registros |
| Anidamiento de objetos y listas | 8 niveles |
| Elementos de una lista | 1.000 |
| Claves de un objeto | 500 |
| Caracteres de un valor | 100.000 |
| Imágenes por documento | 50; 500 entre todos los elementos de un documento a partir de muchos registros |
wait |
25 segundos |
| Solicitudes por plantilla | 60 por minuto; el HTTP Trigger tiene su propio límite de 300 por minuto |
| Consultas de estado por documento | 60 por minuto; las descargas de archivos tienen sus propias 60 |
| Lista de plantillas | 60 por minuto por empresa; la descripción de una plantilla, 60 por minuto |
| Documentos por empresa | 600 por minuto, entre la API de documentos y el HTTP Trigger |