ZPLJetdocs

SDKs

Official ZPLJet API clients, four languages.

LanguageInstallPackage
TypeScript / JavaScriptnpm install @zpljet/node@zpljet/node
Pythonpip install zpljetzpljet
C# / .NETdotnet add package ZplJetZplJet
Gogo get github.com/zpljet/zpljet-gozpljet-go

Every SDK behaves the same, so switching languages is easy:

  • Zero (or near-zero) dependencies — thin clients over each language's standard HTTP stack.
  • Typed errors mapped 1:1 to the API's stable error codes with their context fields (param, retryAfter, quota, …).
  • Automatic retries for rate limits (429, honoring Retry-After), transient 5xx such as service_unavailable, and network errors; never for conversion_failed (engine rejected ZPL; retrying can't help). Default: 2 retries.
  • Configurable timeouts (60 s per attempt by default) and cancellation.
  • Same params as the REST API, both delivery modes: raw bytes (default, nothing stored) or hosted public URL (paid plans).

Keep API keys server-side — anyone with a key can spend your quota. Release notes for every SDK live in the changelog.

TypeScript / JavaScript

Install

npm install @zpljet/node

Runtime support: Node.js ≥ 22; Bun, Deno, edge runtimes

Convert

import { writeFile } from "node:fs/promises";
import { ZplJet } from "@zpljet/node";

const zpljet = new ZplJet({ apiKey: process.env.ZPLJET_API_KEY! });

// Raw PDF. Set format, dpmm, widthMm, or heightMm as needed.
const label = await zpljet.convert({
  zpl: "^XA^FO50,50^A0N,50,50^FDHello^FS^XZ",
});
await writeFile("label.pdf", label.data);

// Hosted URL (paid plans):
const hosted = await zpljet.convert({ zpl: "^XA…^XZ", output: "url" });
console.log(hosted.url, hosted.expiresAt);

Typed error handling

import { BadRequestError, QuotaExceededError, RateLimitError } from "@zpljet/node";

try {
  await zpljet.convert({ zpl });
} catch (err) {
  if (err instanceof BadRequestError) {
    console.error(`Invalid ${err.param}: ${err.message}`);
  } else if (err instanceof QuotaExceededError) {
    console.error(`Quota ${err.used}/${err.quota}, resets ${err.resetsAt}`);
  } else if (err instanceof RateLimitError) {
    console.error(`Rate limited — retry in ${err.retryAfter}s`);
  } else throw err;
}

Python

Install

pip install zpljet

Runtime support: Python ≥ 3.10; tested through 3.14

Convert

import os
from pathlib import Path

from zpljet import ZplJet

zpljet = ZplJet(api_key=os.environ["ZPLJET_API_KEY"])

# Raw PDF. Set format, dpmm, width_mm, or height_mm as needed.
label = zpljet.convert(zpl="^XA^FO50,50^A0N,50,50^FDHello^FS^XZ")
Path("label.pdf").write_bytes(label.data)

# Hosted URL (paid plans):
hosted = zpljet.convert(zpl="^XA…^XZ", output="url")
print(hosted.url, hosted.expires_at)

# Async: await AsyncZplJet(api_key=...).convert(zpl=...)

Typed error handling

from zpljet import BadRequestError, QuotaExceededError, RateLimitError

try:
    zpljet.convert(zpl=zpl)
except BadRequestError as err:
    print(f"Invalid {err.param}: {err.message}")
except QuotaExceededError as err:
    print(f"Quota {err.used}/{err.quota}, resets {err.resets_at}")
except RateLimitError as err:
    print(f"Rate limited — retry in {err.retry_after}s")

C# / .NET

Install

dotnet add package ZplJet

Runtime support: .NET 8/10, .NET Framework 4.7.2+

Convert

using ZplJet;

using var zpljet = new ZplJetClient(Environment.GetEnvironmentVariable("ZPLJET_API_KEY")!);

// Raw PDF. Set Format, Dpmm, WidthMm, or HeightMm as needed.
LabelData label = await zpljet.ConvertAsync(
    new ConvertRequest("^XA^FO50,50^A0N,50,50^FDHello^FS^XZ"));
await File.WriteAllBytesAsync("label.pdf", label.Data);

// Hosted URL (paid plans):
HostedLabel hosted = await zpljet.ConvertToUrlAsync(new ConvertRequest("^XA…^XZ"));
Console.WriteLine($"{hosted.Url} (until {hosted.ExpiresAt})");

Typed error handling

try
{
    LabelData label = await zpljet.ConvertAsync(new ConvertRequest(zpl));
}
catch (BadRequestException ex)
{
    Console.WriteLine($"Invalid {ex.Param}: {ex.Message}");
}
catch (QuotaExceededException ex)
{
    Console.WriteLine($"Quota {ex.Used}/{ex.Quota}, resets {ex.ResetsAt}");
}
catch (RateLimitException ex)
{
    Console.WriteLine($"Rate limited — retry after {ex.RetryAfter}");
}

Go

Install

go get github.com/zpljet/zpljet-go

Runtime support: Go ≥ 1.21

Convert

import zpljet "github.com/zpljet/zpljet-go"

client, err := zpljet.New(os.Getenv("ZPLJET_API_KEY"))
if err != nil {
    log.Fatal(err)
}

// Raw PDF. Set Format, DPMM, WidthMm, or HeightMm as needed.
label, err := client.Convert(ctx, zpljet.ConvertRequest{
    ZPL: "^XA^FO50,50^A0N,50,50^FDHello^FS^XZ",
})
if err != nil {
    log.Fatal(err)
}
if err := os.WriteFile("label.pdf", label.Data, 0o644); err != nil {
    log.Fatal(err)
}

// Hosted URL (paid plans):
hosted, err := client.ConvertToURL(ctx, zpljet.ConvertRequest{ZPL: "^XA…^XZ"})
if err != nil {
    log.Fatal(err)
}
fmt.Println(hosted.URL, hosted.ExpiresAt)

Typed error handling

_, err := client.Convert(ctx, zpljet.ConvertRequest{ZPL: zpl})
if err != nil {
    var apiErr *zpljet.Error
    if errors.As(err, &apiErr) {
        switch apiErr.Code {
        case zpljet.CodeInvalidRequest:
            log.Printf("invalid %s: %s", apiErr.Param, apiErr.Message)
        case zpljet.CodeQuotaExceeded:
            log.Printf("quota %d/%d, resets %s", apiErr.Used, apiErr.Quota, apiErr.ResetsAt)
        case zpljet.CodeRateLimitExceeded:
            log.Printf("rate limited — retry after %s", apiErr.RetryAfter)
        }
    }
}

Each repo ships runnable examples, config docs, and changelog. Missing your language? The API is one HTTP endpoint — easy to call from anywhere.