How-to2026-09-289 min läsning

TypeScript-SDK för PDF-API:et: fem minuter till första anropet och vad det lämnar åt dig

Använd @pdf123/sdk från TypeScript för att slå ihop filer, lägga till vattenmärken, läsa filinformation och kedja flera verktyg i en enda begäran. Den fångar ett felstavat verktygs- eller parameternamn innan något laddas upp; serverns avslag har med orsak och tips, medan omförsök, avbrott och delvisa fel i en batch är ditt ansvar.

PDF123 · Updated 2026-09-28

När du anropar PDF-API:et från Node fångar utvecklarpaketet (SDK) @pdf123/sdk ett felstavat verktygs- eller parameternamn innan någon fil har laddats upp. Det gör inga omförsök, avbryter inte åt dig och strömmar inte resultat. new Pdf123Client() pekar som standard anonymt mot https://pdf123.xyz; dina filer laddas upp dit och bearbetas där, eftersom det inte finns någon lokal motor.

Diagram: ett anrop passerar tre grindar i tur och ordning, tsc-kontrollen vid kompilering, valideringen vid körning innan begäran skickas och den 400 som servern svarar med efter uppladdningen; omförsök och avbrott är anroparens sak, och indata på sammanlagt mer än 95 MiB laddas upp i delar automatiskt

Två PDF-filer i en mapp räcker för att slå ihop

Du behöver Node 20.3 eller nyare, eller Bun. Paketet är en ES-modul: lägg koden i en .mjs-fil eller kör npm pkg set type=module först. Lägg a.pdf och b.pdf i den aktuella katalogen.

npm install @pdf123/sdk
// merge.mjs
import { Pdf123Client } from "@pdf123/sdk";
import { readFileInput, saveResult } from "@pdf123/sdk/node";

const client = new Pdf123Client();
const merged = await client.run("merge", {
  input: [await readFileInput("a.pdf"), await readFileInput("b.pdf")],
});
console.log(await saveResult(merged, { output: "merged.pdf" }));

Efter node merge.mjs skriver terminalen ut sökvägen du angav, merged.pdf, och filen ligger i den aktuella katalogen. readFileInput och saveResult finns i @pdf123/sdk/node. Rotingången är bara beroende av fetch och tar indata som enkla { name, data }, så en miljö utan filsystem kan använda samma klient. Ett resultat är { data, contentType, filename, json }; data är en hel Uint8Array, och Buffer.from(result.data) ger en Buffer.

Slå ihop PDF är bara ett av verktygen.

Filer kommer tillbaka i data, rapporter i json

Varje verktyg anropas som client.run(toolName, { input, params }). Koden nedan fortsätter på merge.mjs från föregående avsnitt, med client och saveResult redan i scope. Var du läser resultatet beror på fältet returns från getTool, som är antingen "file" eller "json": använd data för det första och json för det andra.

import { getTool } from "@pdf123/sdk";
import { readFileInput, saveResult } from "@pdf123/sdk/node";

// client kommer från merge.mjs i föregående avsnitt
const marked = await client.run("watermark", {
  input: await readFileInput("a.pdf"),
  params: { watermarkText: "DRAFT", fontSize: 40 },
});
console.log(await saveResult(marked, { output: "marked.pdf" }));

const info = await client.run("get-info", { input: await readFileInput("a.pdf") });
console.log(info.json.FileSize, info.json.Encrypted);
console.log(getTool("get-info")?.returns); // "json"

Det första blocket skriver den vattenmärkta filen till marked.pdf; i det andra är info.json rapporten. Du behöver inte lära dig fältnamn, standardvärden eller tillåtna värden utantill: getTool("watermark")?.fields är den katalogen, och pdfx describe watermark på kommandoraden läser samma. TOOLS innehåller alla 95 verktyg. Hela referensen finns i SDK-guiden på utvecklarsidan.

För att slå ihop, sedan lägga på vattenmärke och sedan komprimera kan du använda pipeline eller tre run-anrop i rad; vilket beror på om du vill ha mellanfilerna. Även här fortsätter koden på client ovan. pipeline viker ihop de tre stegen till en begäran, mellanresultaten stannar på servern och anroparen får bara det sista steget, som koden nedan skriver till out.pdf. Vill du ha filen från varje steg anropar du dem var för sig.

const result = await client.pipeline(
  [{ tool: "merge" }, { tool: "watermark", params: { watermarkText: "DRAFT" } }, { tool: "compress" }],
  [await readFileInput("a.pdf"), await readFileInput("b.pdf")],
);
console.log(await saveResult(result, { output: "out.pdf" }));

En pipeline har högst 8 steg. Ett 9:e steg får HTTP 400: at most 8 pipeline steps allowed.

Anonymt, med nyckel eller riktat mot din egen server

Om du har satt PDFX_API_BASE och ändå hamnar på https://pdf123.xyz beror det på att new Pdf123Client() inte läser miljövariabler; den tittar bara på konstruktorns alternativ.

För anonyma anrop använder du konstruktorn som den är. Med nyckel skriver du new Pdf123Client({ apiKey: process.env.PDFX_API_KEY }); begäranshuvudet är X-API-KEY.

För att peka mot din egen server använder du clientFromEnv() från @pdf123/sdk/node. Den läser PDFX_API_BASE och PDFX_API_KEY. Du kan också skriva new Pdf123Client({ baseUrl: "http://localhost:8080" }) direkt. Om adressen inte går att nå misslyckas anropet; något offlineläge finns inte. Vad du får, och vad det kostar, när filerna stannar i ditt eget nätverk går igenom i Vad du faktiskt vinner på att köra PDF123 själv (och vad det kostar).

En felaktig parameter fångas före uppladdningen

Utan detta skulle filen laddas upp först och ett felstavat fältnamn visa sig först som en 400 från servern. Parametertyperna för varje verktyg genereras från katalogen, så tre vanliga misstag faller redan i tsc-steget:

Vad du skriver Kompilatorfel (utdrag)
client.run("rotat", { input }) Argument of type '"rotat"' is not assignable to parameter of type 'ToolId'
params: { watermarkTxt: "DRAFT" } Object literal may only specify known properties, but 'watermarkTxt' does not exist, och sedan Did you mean to write 'watermarkText'? på slutet
params: { angle: 45 } (rotate godtar bara 90, 180, 270) Type '45' is not assignable to type …, följt av de tillåtna värdena

Korrekta anrop som { angle: 90 } eller { watermarkText: "DRAFT", fontSize: 30 } kompilerar. Numeriska fält godtar både tal och strängar, så fontSize: 30 och fontSize: "30" är likvärdiga. Ett projekt som inte använder TypeScript får samma fel vid körning, och begäran skickas aldrig: det tredje fallet ger Field "angle" of "rotate" must be one of: 90, 180, 270, och ett felstavat verktygsnamn ger unknown_tool, med liknande namn listade i meddelandet.

När servern avvisar, förgrena på reason

När servern avvisar en begäran kastar SDK:t Pdf123Error med status, code, reason och problem.hint. En och samma code kan ha flera reason-värden, så kontrollera reason först och falla tillbaka på code. Tre vanliga fel, körda lokalt med samma indata, ser ut så här:

Indata status code reason hint (originalet är på engelska)
Krypterad PDF, inget lösenord angivet 400 bad_request password_required Provide the document password, or unlock the PDF first
Fel lösenord 400 bad_request wrong_password Check the password and try again
Ingen PDF, eller en skadad fil 400 invalid_document invalid_pdf Upload a valid, undamaged PDF; you can try repairing it first
import { Pdf123Client, Pdf123Error } from "@pdf123/sdk";
import { readFileInput } from "@pdf123/sdk/node";

const client = new Pdf123Client();
const input = await readFileInput("locked.pdf");
try {
  await client.run("compress", { input });
} catch (error) {
  if (!(error instanceof Pdf123Error)) throw error;
  console.error(error.status, error.code, error.reason, error.problem?.hint);
  if (error.reason === "password_required") {
    await client.run("compress", { input, password: "secret" });
  }
}

När du känner till lösenordet skickar du password för en enskild fil; upplåsningen och målverktyget sker i samma begäran. För en skadad fil, prova Reparera PDF först.

"Inget resultat" behöver skiljas från fel. När PDF till CSV inte hittar någon tabell i PDF-filen svarar servern med 204 och SDK:t kastar code: "no_content"; orsaken finns i Tom tabellexport (204): din PDF har troligen inga kolumner. Villkorsfilterverktyg behandlar ett falskt villkor som ett normalt utfall: de kastar inget fel och returnerar matched: false med tom data.

Omförsök, minne och avbrott är anroparens sak

Nätverksfel och 5xx-svar kastas som de är; SDK:t gör aldrig omförsök på egen hand. För en begäran som ändrar tillstånd skickar du din egen idempotencyKey: att skicka om med samma nyckel ger tillbaka det första resultatet i stället för att bearbeta på nytt, och mekanismen och gränserna finns i Idempotency-Key: säkra återförsök för PDF-jobb. Resultat läses in i minnet i sin helhet, utan strömning. När både indata och utdata är stora, räkna det minne de upptar samtidigt.

Avbrott och timeout är två olika code-värden, och ett anrop rapporterar bara det som inträffar först. Exemplet nedan testar dem i två separata anrop, så att båda grenarna faktiskt kan köras:

import { Pdf123Client, Pdf123Error } from "@pdf123/sdk";
import { readFileInput } from "@pdf123/sdk/node";

const client = new Pdf123Client();
const input = await readFileInput("a.pdf");

const controller = new AbortController();
setTimeout(() => controller.abort(), 10_000);
try {
  await client.run("compress", { input, signal: controller.signal });
} catch (error) {
  if (error instanceof Pdf123Error && error.code === "cancelled") { /* du avbröt */ }
}

try {
  await client.run("compress", { input, timeoutMs: 60_000 });
} catch (error) {
  if (error instanceof Pdf123Error && error.code === "timeout") { /* överskred timeoutMs; ingen signal den här gången */ }
}

Så fort avbrottssignalen (AbortSignal) utlöses avvisas begäran med code: "cancelled"; en överskriden timeout ger code: "timeout". Varje begäran har en standardtimeout på 5 minuter, som du kan ändra när du skapar klienten eller åsidosätta per anrop med timeoutMs. Vid en uppladdning i delar bär varje begäran den timeouten för sig. Ett avbrott stänger bara den här anslutningen; det finns ingen garanti för att servern slutar bearbeta.

En fil misslyckas, resten fortsätter, och callbacks kommer i slutförandeordning

För en batch av indata till ett enfilsverktyg använder du runBatch. Om en fil misslyckas går de andra vidare. onResult anropas i samma stund som varje fil blir klar, så den körs i slutförandeordning, och index är filens position i indata-arrayen; den returnerade arrayen är alltid i indataordning. Skriv bytena till disk inne i den callbacken: retainData: false tömmer data när callbacken returnerar, så ett resultat du inte skickar till saveResult här är borta. Om körningen avbryts finns de redan skrivna filerna kvar.

Anta att mappen har tre fungerande PDF-filer, a.pdf, b.pdf och en krypterad locked.pdf (lösenord secret), plus en trasig fil, broken.pdf, som bara innehåller några inskrivna tecken:

import { Pdf123Client } from "@pdf123/sdk";
import { fileSource, saveResult } from "@pdf123/sdk/node";

const client = new Pdf123Client();
const results = await client.runBatch("compress", [
  fileSource("a.pdf"), fileSource("broken.pdf"), fileSource("b.pdf"), fileSource("locked.pdf"),
], {
  concurrency: 2,
  passwordFor: (file) => (file.name === "locked.pdf" ? "secret" : undefined),
  onResult: async (entry, index) => {
    console.log(index, entry.input.name, entry.ok ? "ok" : entry.error.reason);
    if (entry.ok) await saveResult(entry.result, { output: "out/" });
  },
  retainData: false,
});

Som standard bearbetas två filer åt gången; ändra det med concurrency. fileSource(path) läser en fil från disk först när det är dess tur, så en stor batch med stora filer ligger aldrig i minnet på en gång. Med passwordFor kan en batch som blandar låsta och olåsta filer köras i ett svep. När de fyra filerna ovan kördes lokalt fick callbacken:

1 broken.pdf invalid_pdf
0 a.pdf ok
2 b.pdf ok
3 locked.pdf ok

Slutförandeordningen kan skilja sig vid varje körning; det här är bara hur en körning såg ut. retainData: false gör att data i den returnerade arrayen är tom; de lyckade filerna hade redan skrivits till out/ av saveResult ovan. När du skickar idempotencyKey till runBatch är nyckeln som faktiskt skickas för varje fil <key>:<index>.

Uppladdning i delar börjar först över 95 MiB sammanlagt

En direkt begäranskropp är begränsad till 100 MiB, och allt större avvisas; detaljerna finns i När en stor PDF-uppladdning avvisas: gränsen på 100 MiB för begärandekroppen och felet som pekar i fel riktning. När alla filer i en begäran tillsammans överstiger 95 MiB byter SDK:t till uppladdning i delar, och ditt client.run-anrop ändras inte. Serverns standardtak för en enskild uppladdning är 500 MiB; när du kör själv justerar du det med PDFX_UPLOAD_MAX_BYTES.

För samma operation skriven i curl, MCP och på kommandoraden, se Samma operation, fyra klienter: webbläsare, curl, MCP, pdfx: det inlägget lägger de fyra anropen sida vid sida, och det här går bara djupare i SDK:t. Paketets sida på npm är @pdf123/sdk.

Open tool
Process in the browser — no watermark, files removed after the job.
Open tool