Project

labelzoom

0.0
The project is in a healthy, maintained state
Converts barcode labels between ZPL, EPL, IPL, TSPL, DPL, SBPL, PDF, LabelZoom XML/JSON, and raster images via the LabelZoom API.
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
 Dependencies
 Project Readme

LabelZoom Logo

LabelZoom SDK

Official client libraries for the LabelZoom API — convert barcode labels between ZPL, EPL, IPL, TSPL, DPL, SBPL, PDF, LabelZoom XML/JSON, and raster images.

Status

The SDKs are built around a shared, machine-checked API contract. This table is the honest state of play, not a roadmap:

Language Package Status
.NET LabelZoom.Sdk released NuGet — the reference implementation
Node / TypeScript @labelzoom/sdk released npm
Java com.labelzoom:labelzoom-sdk released Maven Central
Python labelzoom-sdk released PyPI
PHP labelzoom/sdk released Packagist
Go github.com/labelzoom/labelzoom-sdk/go released Go
Ruby labelzoom released Gem
Rust labelzoom released crates.io

npm, PyPI, NuGet, crates.io and RubyGems release from CI over OIDC trusted publishing, with no stored credential. Maven Central and Packagist have no OIDC equivalent, so those two use scoped repository secrets — and Packagist, which reads composer.json from a repository root rather than accepting an upload, publishes via a split mirror repo (.github/workflows/release-php.yml explains why). Go publishes to no registry at all: the module proxy serves straight from a go/vX.Y.Z tag, which is why its release workflow is a gate rather than a publisher.

The first five shipped 1.0.0 together, once five independent implementations had validated the shared contract against the same fixtures; Go, Ruby and Rust joined at 1.0.0 after doing the same. The contract is versioned separately from every SDK, in conformance/spec.json — see docs/API_CONTRACT.md.

For copy-paste snippets in languages without a package — PowerShell, Groovy, VB.NET, and friends — see samples/.

What the API does

One endpoint covers almost everything:

POST https://api.labelzoom.com/api/v2/convert/{sourceFormat}/to/{targetFormat}

Sources: zpl epl ipl tspl dpl sbpl xml json pdf png bmp gif jpg jpeg url

Targets: zpl epl ipl tspl dpl sbpl xml json pdf png bmp gif jpeg

jpg and url are source-only — jpg is an input spelling that normalizes to jpeg, and url tells the server to go fetch a document rather than naming a format. Every SDK enforces that at compile time where the language allows it.

The printer languages round-trip: epl, ipl, tspl, dpl and sbpl are targets as well as sources, so pdf/to/epl and zpl/to/sbpl are real conversions. Their output is text/plain with every label concatenated — but they can all carry raw binary (EPL's GW, TSPL's BITMAP, IPL's STX/ETX-framed bitmap columns, SBPL's inline graphics), so read the result's bytes, not its text, whenever a label might carry graphics.

Authentication is optional. Without a key you get the free tier: watermarked output, first label only, a 1 MB request cap, and no multi-page, JSON-target, or image-to-image conversion. With a key you get the rest. Every SDK works with no credential configured — that is a contract requirement, not an accident.

// No API key: this works, and returns a watermarked label.
using var client = new LabelZoomClient();

var result = await client.Convert()
    .FromZpl("^XA^FO20,20^A0N,28^FDHello^FS^XZ")
    .ToPng()
    .WithDpi(300)
    .WithLabelSize(widthInches: 4f, heightInches: 6f)
    .ExecuteAsync();

await File.WriteAllBytesAsync("label.png", result.Bytes);

Set LABELZOOM_API_KEY and every SDK picks it up automatically.

Repository layout

docs/API_CONTRACT.md   what every SDK must do, stated once
docs/CONFORMANCE.md    how to add a language
conformance/           language-neutral fixtures all SDKs are tested against
dotnet/ node/ java/ …  one directory per SDK
samples/               copy-paste snippets for languages without a package

Why a conformance suite

Eight independent implementations of one wire protocol drift, and they drift quietly. So the behavior lives in docs/API_CONTRACT.md as numbered rules, the machine-checkable subset lives in conformance/ as language-neutral JSON, and every language's test suite runs the same cases and asserts it ran all of them.

The rules exist because each one was gotten wrong at least once. Two examples:

  • Accept: */*, always. The server's produces list omits image/gif, image/bmp, and image/jpeg, so sending the target's exact media type returns 406 for those three targets.
  • pdf.pageNumber is 0-based and label.width / label.height are inches. Both are routinely misread; both are pinned by fixtures.
node conformance/lint.mjs

Contributing

Read docs/API_CONTRACT.md first, then docs/CONFORMANCE.md. Changing SDK behavior means changing a fixture, and changing a fixture re-runs every language.

License

MIT — see LICENSE.

Links