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
| Labelary | zpl.tools | |
|---|---|---|
| Key required? | No — free tier works with no key | Yes, on every request |
| How keys are issued | Email-based signup for a premium key | Create a scoped key from your account |
| Key scope | Single 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
| Labelary | zpl.tools | |
|---|---|---|
| Rate limit | 3–10 requests/sec depending on tier, plus daily caps | No default rate limit — optional soft limits (requests/sec, pages/day) can be set per key |
| Page count per request | 50 labels max | Unlimited |
| Request body size | 1 MB | Unlimited |
| Image file size | 200 KB | Unlimited |
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.
| Case | Status | Notes |
|---|---|---|
Invalid dpmm | 400 | Same message shape (Unknown print density N; valid values: 6, 8, 12, 24) |
| Label too large / too small | 400 | zpl.tools' floor is 0.001"; distinct messages for too-small vs. too-large |
| Index out of bounds | 404 | Same ordinal phrasing (Requested 2nd label but ZPL only generated 1 label) |
| No labels produced | 404 | Message depends on whether an index was requested — see Error Reference |
Unsupported Accept value | 406 | Both services reject with 406; zpl.tools also 406s formats Labelary supports that we don't generate (see below) |
| Malformed ZPL | Differs — see below | Not yet verified byte-for-byte against live Labelary; see below |
| Invalid API key | 401 (zpl.tools only) | No Labelary equivalent (key is optional there) |
Full reference: Error Reference.
Rendering defaults
X-Quality:Grayscaleis the default on both services and requires no change.Bitonalis implemented and thresholds the (already-grayscale) render down to pure black/white.X-Rotation: implemented for PNG output —0/90/180/270rotates 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^XZwith nothing in between) produces zero labels — a404naming that no labels were generated, not a500. 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) andPOST /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
dpmmaccepts both the suffixed form (8dpmm) and a bare number (8) — Labelary accepts both, so does zpl.tools.- Dimensions: zpl.tools accepts
0.001–15inches; a value outside that range gets a400naming which bound was hit (too small vs. too large).