JavaScript Quickstart
Install
Section titled “Install”npm install @labelzoom/sdkNode 20+. Dual ESM/CJS builds with TypeScript declarations, no runtime dependencies — it uses
the platform fetch. Published from CI with npm
provenance, so every release is
cryptographically linked to the commit and workflow that built it.
Convert ZPL to PDF
Section titled “Convert ZPL to PDF”An API key is optional — without one you get the free tier.
import { writeFile } from 'node:fs/promises';import { LabelZoomClient } from '@labelzoom/sdk';
const client = new LabelZoomClient(); // reads LABELZOOM_API_KEY; anonymous if unset
const result = await client.convert() .fromZpl('^XA^FO50,50^ADN,36,20^FDLabelZoom^FS^XZ') .toPdf() .withLabelSize(4, 6) // inches .withDpi(203) .execute();
await writeFile('label.pdf', result.bytes);result.bytes is authoritative — five of the thirteen targets are binary. result.text decodes it
with the response charset for the textual ones (zpl, xml, json).
There’s also an object form, if you prefer it to the chain:
const result = await client.convert({ from: 'zpl', to: 'pdf', body: '^XA^FO50,50^ADN,36,20^FDLabelZoom^FS^XZ', options: { dpi: 203, label: { width: 4, height: 6 } },});Both do the same thing. Passing the key explicitly, or forcing anonymous:
const client = new LabelZoomClient({ apiKey: 'lz_live_...' });const anonymous = new LabelZoomClient({ apiKey: '' }); // ignores the env varConverting a PDF to ZPL
Section titled “Converting a PDF to ZPL”import { readFile } from 'node:fs/promises';
const result = await client.convert() .fromPdf(await readFile('shipping-label.pdf')) .toZpl() .withLabelSize(4, 6) .withPdfPage(0) // 0-based; omit for every page .execute();
const zpl = result.text;toUrl() doesn’t exist, and TypeScript will tell you so: jpg and url are source-only on
the server, and SourceFormat and TargetFormat are distinct types. A compile error rather
than a 404.
The printer languages epl, ipl, tspl, dpl and sbpl are targets — .fromPdf(bytes).toEpl() is a real conversion. Read result.bytes rather than the decoded text for those: EPL’s GW and TSPL’s BITMAP commands inline raw binary.
Filling variable fields
Section titled “Filling variable fields”Each record produces one label:
const result = await client.convert() .fromZpl(template) .toPdf() .withData({ name: 'ACME Corp', sku: '12345' }, { name: 'Globex', sku: '67890' }) .execute(); // a 2-page PDFCalling the REST API directly
Section titled “Calling the REST API directly”The SDK is a wrapper over one HTTP endpoint; fetch works just as well (Node.js 18+, Bun, Deno,
or serverless runtimes).
import { writeFile } from "node:fs/promises";
const zpl = "^XA^FO50,50^ADN,36,20^FDLabelZoom^FS^XZ";
// The API key is optional — omit the Authorization header if it isn't set.const headers = { "Content-Type": "text/plain" };if (process.env.LABELZOOM_API_KEY) { headers.Authorization = `Bearer ${process.env.LABELZOOM_API_KEY}`;}
const response = await fetch( "https://api.labelzoom.com/api/v2/convert/zpl/to/pdf?label.width=4&label.height=6&dpi=203", { method: "POST", headers, body: zpl, },);
if (!response.ok) { throw new Error(`Conversion failed: ${response.status} ${await response.text()}`);}
await writeFile("label.pdf", Buffer.from(await response.arrayBuffer()));console.log("Wrote label.pdf");To convert a PDF to ZPL, send the file bytes with Content-Type: application/pdf and read
await response.text().
- Call the API from your backend — never expose your key in browser code.
- All endpoint patterns, formats, and parameters are in the quickstart and the Swagger reference.
- Source, issues, and the shared conformance suite: labelzoom/labelzoom-sdk.