Skip to content

n8n integration

The LabelZoom community node converts and prints labels from an n8n workflow. It is verified by n8n, so it installs straight from the canvas; it handles binary in and out, carries every conversion option, and is the path these docs cover.

A n8n workflow showing LabelZoom’s node wired to print a label on a Shopify trigger A n8n workflow showing LabelZoom’s node wired to print a label on a Shopify trigger

Open the nodes panel on the canvas — +, or press n — search for LabelZoom, and pick it out of More from the community. There is no package name to type. This is the same on n8n Cloud and self-hosted.

the n8n canvas nodes panel, “LabelZoom” typed into the search, the node showing in the search results the n8n canvas nodes panel, “LabelZoom” typed into the search, the node showing in the search results

Installing is an instance owner or admin action and enables the node for everyone on the instance. If LabelZoom does not appear in the search, verified community nodes are switched off: on n8n Cloud the owner toggles them in the Admin Panel, and self-hosted instances control them with environment variables. A restart may be needed before the node shows up.

Built and tested against n8n 2.x, which itself requires Node 24 or later. The node has no runtime dependencies — it uses n8n’s own HTTP helpers.

The fallback when verified community nodes are unavailable to you — an older n8n, an instance where an admin has turned them off, or a version you need to pin. Settings → Community nodes → Install, then enter:

n8n-nodes-labelzoom

Self-hosted instances can also install it from the command line:

Terminal window
npm install n8n-nodes-labelzoom

The n8n Community nodes install dialog with n8n-nodes-labelzoom entered as the npm package name The n8n Community nodes install dialog with n8n-nodes-labelzoom entered as the npm package name

An API key is optional for converting. Leave the credential unset and the node runs on the free tier: unlimited conversions, watermarked output, first label only, 1 MB request cap. Every example below works as-is. Add a LabelZoom API credential when you’re ready to ship — see Authentication. Printing always needs a key with the print scope; print implies convert, so one key covers both.

Field Notes
API Key Optional for Label operations, required for Printer operations
Max Retries 429 and 5xx are retried with exponential backoff. 0 fails fast. Client errors are never retried.
Base URL Only change this if you were given a dedicated endpoint

The credential’s Test button calls GET /api/v3/templates, not a conversion — a bad key is rejected there, while the conversion endpoint would accept it anonymously. See A bad API key does not fail.

The LabelZoom API credential in n8n showing the API Key, Max Retries and Base URL fields, with a successful connection test The LabelZoom API credential in n8n showing the API Key, Max Retries and Base URL fields, with a successful connection test

The simplest useful workflow: something produces ZPL, you want a PDF.

  1. Add a LabelZoom node.
  2. Resource: Label · Operation: Convert
  3. Source Format: ZPL · Target Format: PDF
  4. Input Type: Text, and put the label code in Label Content — or leave it on Binary File and point Input Binary Field at a file from the previous node.

The result comes out as a binary field (named data by default), ready for Google Drive, Dropbox, an email attachment, or an HTTP response.

The LabelZoom node configured to convert ZPL to PDF, with the converted PDF shown as binary output The LabelZoom node configured to convert ZPL to PDF, with the converted PDF shown as binary output

Set label size and density under Options:

Option Value
Label Width (Inches) 4
Label Height (Inches) 6
DPI 203

Leave width and height unset to have LabelZoom detect the size from the source.

The other direction, and the more common one in shipping workflows.

  1. HTTP Request node — download the carrier’s label PDF, with Response Format set to File so it arrives as binary.
  2. LabelZoom node — Label → Convert, Source Format PDF, Target Format ZPL, Input Type Binary File.

Useful options:

  • PDF Conversion Mode — IMAGE (the default) rasterizes each page and preserves the exact appearance, which is what you want for a carrier label. NATIVE extracts the underlying vector and text.
  • PDF Page Number — 0-based. Set 0 for the first page; leave it empty to convert every page.

The ZPL comes back as binary and as a text field on the node’s JSON output, so you can pipe it straight into a downstream node without decoding the binary yourself.

Put the values in Options → Variable Data (JSON), keyed by the template’s merge field names:

[{ "sku": "A-100", "qty": "12" }, { "sku": "A-101", "qty": "5" }]

Each array entry produces one label. Two entries render the template twice — two pages in a PDF, two concatenated blocks in ZPL. Map it from the incoming item with an expression:

{{ JSON.stringify($json.rows) }}

See Multi-label jobs for how each target format handles more than one label. Multi-page output is a paid feature.

  1. LabelZoom node — Resource: Printer · Operation: Print
  2. Printer — pick from the list. The dropdown shows each printer’s native format and live status, e.g. Warehouse Zebra — ZPL (ready).

The Printer dropdown in the LabelZoom node listing cloud printers with their native format and live status The Printer dropdown in the LabelZoom node listing cloud printers with their native format and live status

  1. Source Format — leave on Auto-detect unless the document is one of the printer languages, which all look alike on the wire.
  2. Point it at your binary field or label text.

You do not need to convert first. If the document isn’t in the printer’s native format, LabelZoom converts it in transit — a carrier PDF sent to a Zebra becomes ZPL automatically. Every transform option from Convert works here too, even when no format change happens, so rotation: 90 on the way to the printer is a one-field change.

Copies sends the job to the printer this many times, from 1 to 9999. It is on both Print and Print Template, from n8n-nodes-labelzoom 1.2.0.

  • Leave it at 1 (the default) to send the job once, exactly as before.
  • A quantity already in the label multiplies. A label carrying a ZPL ^PQ3 with Copies set to 5 prints 15.
  • A job holding several labels prints collated (A, B, A, B), as one job. The node’s output reports the copies the job was accepted with — null when Copies was left at 1.

Copies takes an expression, so the count can come from the incoming item:

{{ $json.quantity }}

A number that arrives as text, such as "25" from a spreadsheet or CSV, is accepted. Anything that isn’t a whole number from 1 to 9999 fails the item before a request is sent.

With Copies above 1, the LabelZoom Print Agent serving the printer must be up to date; an older one fails the item with a 422 (agent_update_required) and nothing prints. For a large run of a complex label, putting the quantity in the label itself (such as a ZPL ^PQ) usually prints faster — see Printing copies.

The node returns as soon as the job is accepted:

{ "jobId": "9f8e…", "status": "dispatched", "copies": null, "printerId": "b2c3…" }

dispatched means an online agent has the job. queued means every bound agent is offline and it will print when one reconnects. Neither means the label came out of the printer — only the agent moves a job to completed.

If the workflow needs to know it actually printed, turn on Wait for Completion: the node polls the job until it reaches completed or failed, or the timeout expires. Otherwise, add a later Printer → Get Job step with the jobId.

Print sends an Idempotency Key; repeating a key for the same request returns the original job instead of printing again. The default is:

{{ $execution.id }}-{{ $itemIndex }}

which makes a retried step safe. Set it from a stable business value to make a whole workflow re-run safe too:

{{ $json.orderNumber }}

A key identifies the whole request, Copies included. Repeating it with a different document, different merge data, a different printer or template, different options, or a different Copies fails the item with a 422 (idempotency_key_reused) instead of replaying the original job. So when a workflow deliberately reprints — or prints the same order again at a new quantity — give that print a key of its own, for example {{ $json.orderNumber }}-reprint-{{ $execution.id }}. See Idempotency.

If the label is designed in LabelZoom Studio and published to Print Templates, you send only the values — no label code in the workflow.

  1. Resource: Printer · Operation: Print Template
  2. Pick the printer, then the template. The template dropdown shows each template’s merge fields, so you can see what data it wants — e.g. Shipping Label — orderNumber, sku.

The Template dropdown listing Print Templates, each annotated with its merge field names The Template dropdown listing Print Templates, each annotated with its merge field names

  1. Merge Data (JSON) — the values, keyed by field name:
    {{ JSON.stringify({ orderNumber: $json.number, sku: $json.line_items[0].sku }) }}
  2. Leave Validate Merge Fields on, so a missing field is rejected rather than printed on the label as the literal text null — see Merge fields.
  3. Copies — how many times to send the label to the printer. Leave it at 1 to send it once; see Print copies.

Send one object per item. n8n already runs the operation once per input item, so a batch of orders is a batch of items, and each gets its own job and its own idempotency key.

Pick a product, enter how many tags you need, and print them. Anything that hands the node a product and a quantity works — a row from a product sheet with a quantity column, an order line, or an n8n Form asking for a SKU and a count, followed by a lookup of that product:

{ "sku": "A-100", "description": "Widget, blue", "price": "4.99", "quantity": 25 }

Then a LabelZoom node — Printer → Print Template, your price-tag template, and:

Field Value
Merge Data (JSON) {{ JSON.stringify({ sku: $json.sku, description: $json.description, price: $json.price }) }}
Copies {{ $json.quantity }}

That sends the tag to the printer 25 times as a single job. Design the template to print one tag: a print quantity built into the template multiplies with Copies. Keep the default idempotency key here rather than keying on the SKU — printing the same tag again later is the point, and a SKU key would replay the first job, or be refused with a different Copies.

There’s also a Label → Convert Template operation, which renders a filled template without printing it — useful for a preview or approval step.

Validate the key by converting, not by status code

Section titled “Validate the key by converting, not by status code”

A typo’d key returns a perfectly healthy 200 carrying a watermarked free-tier label, because the conversion endpoint treats an unresolvable credential as anonymous. Use the credential’s Test button — it calls an endpoint that does reject a bad key — and during setup, convert one label and look at it. See A bad API key does not fail.

Keys created from the dashboard are always test keys (lz_test_): watermarked and never billed. Production keys (lz_live_) are provisioned on Pro and above. A workflow that “works fine but watermarks in prod” is nearly always this, not a configuration problem. See Test keys and live keys.

The throughput cap is noticeably tighter on the Free and Basic tiers — those plans are sized for evaluation and light use. The budget is shared by everything using the same API key, so running more workflows in parallel does not buy more throughput; size any Split In Batches loop with that in mind. The node retries 429 and 5xx with backoff and honors Retry-After, so an occasional limit is absorbed rather than failing the execution. See Rate limits and plans.

The node does not retry 401 or 403, and neither should anything else calling the API. Repeated authentication failures are themselves rate limited, and the effect is not scoped to the workflow that caused them — hammering a bad credential can lock out every other workflow on the same n8n instance. If you set Retry On Fail on the node, keep the attempt count low.

The API key is a bearer credential: anyone holding it can spend your quota. Keep it in an n8n credential, never in a node parameter or an expression.

The node is the supported way to reach LabelZoom from n8n. If you need raw HTTP anyway — from a Code node, or for something the node doesn’t cover — start from Supported formats and the JavaScript Quickstart.

One trap to carry over: take the response as binary. Five of the thirteen targets are binary, and epl, tspl and dpl come back as text/plain but can inline raw bytes — EPL’s GW, TSPL’s BITMAP, and DPL’s leading STX. Decoding those to a string corrupts every label carrying graphics — see Supported formats for why.