¿Cómo instalo el SDK?
Instala el paquete con tu gestor de paquetes. Se necesita Node 20.3 o superior, Bun o un empaquetador. Los tipos de TypeScript vienen incluidos y no hace falta @types/node.
npm install @pdf123/sdkbun add @pdf123/sdk y pnpm add @pdf123/sdk funcionan igual.
¿Cómo uno dos PDF?
Crea un cliente, ejecuta la herramienta merge con dos archivos y guarda el resultado. Sin opciones, el cliente se comunica con la API pública de forma anónima.
import { Pdf123Client } from "@pdf123/sdk";
import { readFileInput, saveResult } from "@pdf123/sdk/node";
const client = new Pdf123Client();
const result = await client.run("merge", {
input: [await readFileInput("a.pdf"), await readFileInput("b.pdf")],
});
const path = await saveResult(result, { output: "merged.pdf" });
console.log(path);El resultado contiene los bytes en data, el contentType, el filename del servidor y json para las herramientas que devuelven un informe. La misma operación está disponible en el sitio web como Unir PDF.
¿Qué punto de entrada debo importar?
| Punto de entrada | Requiere | Ofrece |
|---|---|---|
@pdf123/sdk | Solo fetch | Pdf123Client, TOOLS, getTool, Pdf123Error y las funciones auxiliares del catálogo |
@pdf123/sdk/node | Node o Bun | readFileInput, fileSource, saveResult, checkOutput y clientFromEnv |
Importa desde el punto de entrada raíz en navegadores y entornos edge, y añade el de node solo donde leas o escribas archivos.
¿Qué métodos tiene el cliente?
| Método | Qué hace |
|---|---|
run(tool, { input, params }) | Ejecuta una herramienta y se resuelve con un resultado |
runBatch(tool, inputs, options) | Ejecuta una herramienta de un solo archivo sobre muchas entradas y se resuelve con una entrada por cada una |
pipeline(steps, input, options) | Ejecuta varias herramientas en una sola solicitud |
call(target, files, fields) | Envía una solicitud sin procesar a un id de herramienta, un id de operación o una ruta /api/... |
upload(file) | Sube un archivo mediante la API de subida por fragmentos y devuelve su id |
Las funciones auxiliares del catálogo son funciones simples: TOOLS enumera todas las herramientas, getTool(id) devuelve los campos, los valores por defecto y los tipos de archivo aceptados de una herramienta, y toolGroup, toolSummary, matchesQuery y suggestTools ayudan a construir selectores de herramientas. La línea de comandos imprime el mismo catálogo con pdfx list y pdfx describe.
¿Cómo paso opciones a una herramienta?
params está tipado por herramienta. Solo acepta los campos de esa herramienta, y los campos de elección solo admiten sus valores permitidos. Los campos numéricos se comprueban contra su mínimo y su máximo, y cada archivo contra los tipos aceptados, antes de subir nada. Los valores por defecto que necesita el servidor se rellenan solos.
const marked = await client.run("watermark", {
input: await readFileInput("a.pdf"),
params: { watermarkText: "DRAFT", fontSize: 40, rotation: -45 },
});
await saveResult(marked, { output: "draft.pdf" });Una cadena vacía significa «sin definir», así que se aplica el valor por defecto. Consulta Marca de agua en PDF para saber qué hace cada opción.
¿Cómo proceso muchos archivos?
runBatch ejecuta una herramienta de un solo archivo, como Comprimir, Rotar o Proteger, sobre cada entrada con las mismas opciones. Por defecto procesa dos archivos a la vez. Un archivo defectuoso nunca detiene a los demás.
import { fileSource, saveResult } from "@pdf123/sdk/node";
const controller = new AbortController();
const entries = await client.runBatch("compress", [fileSource("a.pdf"), fileSource("b.pdf")], {
concurrency: 2,
signal: controller.signal,
onResult: async (entry, index) => {
if (entry.ok) await saveResult(entry.result, { output: "compressed/" });
},
});
console.log(entries.map((entry) => entry.ok));fileSource(path)es un origen diferido que se lee solo cuando un worker lo toma, de modo que muchos archivos grandes nunca están a la vez en memoria.onResultrecibe cada resultado en cuanto se completa. Guárdalo ahí y, si cancelas en el archivo 50 de 100, se conservan los 49 primeros. ConretainData: false, el array devuelto no conserva los bytes.- Cualquier llamada acepta
timeoutMsy unsignalpara cancelarla. idempotencyKeyse convierte en<key>:<index>para cada archivo.
Las herramientas de filtro (ids que empiezan por filter-) se resuelven con matched: false en lugar de lanzar un error cuando no se cumple su condición. En un lote, ese archivo sigue contando como ok.
¿Cómo encadeno herramientas en una sola solicitud?
pipeline envía una lista de pasos y una o varias entradas. El servidor pasa la salida de cada paso al siguiente.
const piped = await client.pipeline(
[{ tool: "merge" }, { tool: "watermark", params: { watermarkText: "DRAFT" } }, { tool: "compress" }],
[await readFileInput("a.pdf"), await readFileInput("b.pdf")],
);
await saveResult(piped, { output: "out.pdf" });Los pipelines aceptan las mismas opciones de contraseña que run.
¿Cómo trabajo con PDF cifrados?
Pasa password a run para abrir primero una entrada cifrada. El desbloqueo y la herramienta se ejecutan en una sola solicitud. Para las herramientas que reciben varios archivos, como Unir, pasa passwords con un elemento por entrada y una cadena vacía para los archivos abiertos. Cada archivo se desbloquea por separado.
await client.run("compress", { input: await readFileInput("locked.pdf"), password: "secret" });
await client.run("merge", {
input: [await readFileInput("locked.pdf"), await readFileInput("open.pdf")],
passwords: ["secret", ""],
});En un lote, passwordFor(file, index) devuelve la contraseña de cada entrada. Para quitar la protección de forma permanente, usa la herramienta Desbloquear.
¿Cómo funcionan los errores?
Los fallos lanzan Pdf123Error. Tiene status (undefined si no hubo respuesta), code, reason para la causa detallada, como password_required, y problem con los detalles del problema que da el servidor, entre ellos hint cuando existe. Los errores de validación se lanzan antes de subir nada.
import { Pdf123Error } from "@pdf123/sdk";
try {
await client.run("compress", { input: await readFileInput("locked.pdf") });
} catch (error) {
if (error instanceof Pdf123Error) {
console.error(error.status, error.code, error.reason, error.problem?.hint);
} else {
throw error;
}
}Los códigos del servidor figuran en Códigos de error. El cliente añade estos códigos propios:
| Código | Significado |
|---|---|
network_error | La solicitud no recibió respuesta |
timeout | Una solicitud superó timeoutMs |
cancelled | Tu signal abortó la llamada |
input_unreadable | No se pudo leer una ruta local |
output_unwritable | No se pudo guardar el resultado en la ruta indicada |
output_mismatch | saveResult se negó a escribir un ZIP con un nombre .pdf |
unsupported_file_type | La herramienta no acepta el tipo de archivo |
unknown_tool | El id de la herramienta no existe; el mensaje sugiere ids parecidos |
invalid_target | call rechazó una ruta /api/... con segmentos .., . o vacíos |
no_content | La herramienta no tenía nada que devolver (HTTP 204) |
saveResult nunca sobrescribe un archivo dentro de un directorio. Llama antes a checkOutput(output, { several }) para saber, antes de subir nada, si se puede escribir en una ruta.
¿Qué ajustes de TypeScript y de módulos funcionan?
Los tipos se resuelven con los ajustes de moduleResolution nodenext, node16, bundler y el antiguo node10, incluida la subruta @pdf123/sdk/node. El paquete es un módulo ES, por lo que import funciona en todas partes. require("@pdf123/sdk") desde CommonJS funciona en Node 22.12 o superior y no está disponible en Node 20.
¿Cómo configuro el cliente?
| Opción | Variable de entorno | Valor por defecto |
|---|---|---|
baseUrl | PDFX_API_BASE | https://pdf123.xyz |
apiKey | PDFX_API_KEY | ninguno, anónimo |
timeoutMs | ninguna | 300000 |
new Pdf123Client() nunca lee el entorno. clientFromEnv() de @pdf123/sdk/node lee las dos variables, y las opciones que pasas tienen prioridad. La clave se envía en la cabecera X-API-KEY; consulta Autenticación.
Para usar tu propio servidor, define baseUrl con su dirección, por ejemplo http://localhost:8080. Consulta Autohospedaje.
¿Puedo usar el SDK en un navegador?
Sí. El punto de entrada raíz @pdf123/sdk solo necesita fetch y no depende de Node. Crea tú mismo los objetos FileInput a partir de un File o un Uint8Array, porque las funciones para archivos están en el punto de entrada node. No incluyas una clave de API en código de navegador que otras personas puedan leer.
Páginas relacionadas
- Resumen para desarrolladores, con la API REST y la autenticación
- Línea de comandos pdfx, construida sobre este SDK
- Servidores MCP para agentes de IA
- Swagger UI y el documento OpenAPI
- Páginas de herramientas: Unir, Dividir, Comprimir, OCR, Proteger
Preguntas frecuentes
¿El SDK necesita una clave de API?
No. Un cliente creado sin opciones llama a la API pública de forma anónima. Pasa apiKey para enviar la cabecera X-API-KEY.
¿Qué versión de Node necesita el SDK?
Node 20.3 o superior, o Bun. El punto de entrada raíz solo necesita fetch, así que también funciona en navegadores y empaquetadores.
¿Cómo uso una herramienta más reciente que el SDK?
Usa client.call. Recibe un id de herramienta, un id de operación como general/merge-pdfs o una ruta /api/..., además de archivos y campos. No se valida ni se rellena nada por defecto en local.
¿Qué tamaño de archivo puedo subir?
Las entradas de más de 95 MB en total pasan automáticamente por la API de subida por fragmentos. El cuerpo de una solicitud directa está limitado a 100 MiB.
¿Por qué mi llamada lanzó un error con un PDF sin tablas?
Herramientas como pdf-to-csv y pdf-to-xlsx responden sin contenido cuando el PDF no tiene ninguna tabla detectable. El SDK lanza Pdf123Error con el código no_content en lugar de devolver un archivo vacío. Comprueba ese código si un resultado vacío es aceptable.