zpl.tools
Migrate from Labelary

Behavioral differences

Authentication, error codes, rate limits, and the gaps worth knowing about before you cut over

This is the honest list — what's genuinely different, and what's not implemented yet. None of it is fatal to a migration, but each item is worth five minutes of thought against your specific integration before you flip traffic over.

Authentication

Labelaryzpl.tools
Key required?No — free tier works with no keyYes, on every request
How keys are issuedEmail-based signup for a premium keyCreate a scoped key from your account
Key scopeSingle tier (free/premium)Keys are scoped to PNG only, PDF only, or all formats

Bring a key before you migrate — there's no unauthenticated fallback. If a key is scoped to png and a request's Accept header resolves to PDF (or vice versa), you get a 403 with a structured body (see Error Reference).

Rate limits and throughput

Labelaryzpl.tools
Rate limit3–10 requests/sec depending on tier, plus daily capsNo default rate limit — optional soft limits (requests/sec, pages/day) can be set per key
Page count per request50 labels maxUnlimited
Request body size1 MBUnlimited
Image file size200 KBUnlimited

If your integration currently paces requests to stay under Labelary's limits, that pacing logic is no longer required — but it's harmless to leave in place while you validate the migration. A platform-level abuse limit still applies per organization; it's not meant to be reachable by normal traffic.

Error codes

Render errors (bad input, ZPL problems) are text/plain with an ERROR: prefix on both services — the messages are close but not byte-identical everywhere. Auth/authorization errors (401/403/429) are a zpl.tools-specific JSON envelope; Labelary doesn't have an equivalent since auth is optional there.

CaseStatusNotes
Invalid dpmm400Same message shape (Unknown print density N; valid values: 6, 8, 12, 24)
Label too large / too small400zpl.tools' floor is 0.001"; distinct messages for too-small vs. too-large
Index out of bounds404Same ordinal phrasing (Requested 2nd label but ZPL only generated 1 label)
No labels produced404Message depends on whether an index was requested — see Error Reference
Unsupported Accept value406Both services reject with 406; zpl.tools also 406s formats Labelary supports that we don't generate (see below)
Malformed ZPLDiffers — see belowNot yet verified byte-for-byte against live Labelary; see below
Invalid API key401 (zpl.tools only)No Labelary equivalent (key is optional there)

Full reference: Error Reference.

Rendering defaults

  • X-Quality: Grayscale is the default on both services and requires no change. Bitonal is implemented and thresholds the (already-grayscale) render down to pure black/white.
  • X-Rotation: implemented for PNG output — 0/90/180/270 rotates the image clockwise, matching Labelary. PDF output does not rotate yet. If your integration requests PDF + rotation, hold off or render PNG for now.
  • Malformed ZPL: zpl.tools renders best-effort rather than erroring on a single bad command — unknown or invalid commands are skipped, not fatal (same posture as a physical Zebra printer). A submission with no recognizable ZPL at all (e.g. plain text, or ^XA^XZ with nothing in between) produces zero labels — a 404 naming that no labels were generated, not a 500. Labelary's exact behavior on fully unparsable input hasn't been cross-checked against a live call in this pass; if your integration depends on this edge case, verify it against both services before relying on it.

PDF page-layout headers (biggest gap for PDF users)

X-Page-Size, X-Page-Orientation, X-Page-Layout, X-Page-Align, X-Page-Vertical-Align, and X-Label-Border are all accepted and validated the same way Labelary validates them — unknown values are rejected with the same kind of 400, and a label that can't physically fit the requested page/layout gets the same "not enough room" error. What they don't do yet is change the actual rendered PDF: the page is still sized to the label, not to Letter/A4/etc., and multiple labels aren't arranged into a grid.

If your integration only checks that the request succeeds, this is transparent. If it depends on the PDF actually being letter-sized, or labels being laid out N-up on a page, that's not there yet — check with us before migrating that part of your integration.

Formats not implemented

Labelary supports several formats we don't generate. Requesting one gets an honest 406, not a mismatched 200:

  • application/json (label-data extraction — parses ZPL fields back out as structured data, rather than rendering an image)
  • application/epl, application/ipl, application/dpl, application/sbpl, application/pcl5, application/pcl6 (alternate printer languages)
  • POST /v1/graphics (image → ZPL/EPL/IPL/DPL/SBPL/PCL) and POST /v1/fonts (TTF → ZPL font) — neither utility endpoint exists

If any of these are load-bearing for your integration, contact us — knowing there's real demand helps us prioritize.

Path parameter details

  • dpmm accepts both the suffixed form (8dpmm) and a bare number (8) — Labelary accepts both, so does zpl.tools.
  • Dimensions: zpl.tools accepts 0.00115 inches; a value outside that range gets a 400 naming which bound was hit (too small vs. too large).