Skip to content

API docs

One endpoint renders ZPL to PNG or PDF. It is compatible with Labelary's v1 API: same paths, headers and errors.

Render a label

GET  https://api.openzpl.com/v1/printers/{dpmm}/labels/{width}x{height}/{index}/{zpl}
POST https://api.openzpl.com/v1/printers/{dpmm}/labels/{width}x{height}/{index}
POST https://api.openzpl.com/v1/printers/{dpmm}/labels/{width}x{height}/
dpmmPrint density: 6dpmm, 8dpmm, 12dpmm or 24dpmm.
width, heightLabel size in inches, for example 4x6 or 2.25x1.25. Up to 15 inches each.
indexWhich label to render, starting at 0. Leave it out with PDF output to get every label, one per page.
zplFor GET, the URL-encoded ZPL. Encode # as %23. Use POST for anything long.

With POST, send the ZPL as the raw request body, or as a multipart form field named file.

Examples

# PNG from a short ZPL string
curl --get https://api.openzpl.com/v1/printers/8dpmm/labels/4x6/0/ \
  --data-urlencode "^xa^cfa,50^fo100,100^fdHello World^fs^xz" > label.png

# PDF with every label in a file
curl https://api.openzpl.com/v1/printers/8dpmm/labels/4x6/ \
  -H "Accept: application/pdf" --form file=@labels.zpl > labels.pdf
import requests

zpl = "^xa^cfa,50^fo100,100^fdHello World^fs^xz"
res = requests.post("https://api.openzpl.com/v1/printers/8dpmm/labels/4x6/0/", data=zpl)
res.raise_for_status()
open("label.png", "wb").write(res.content)
const zpl = "^xa^cfa,50^fo100,100^fdHello World^fs^xz";
const res = await fetch("https://api.openzpl.com/v1/printers/8dpmm/labels/4x6/0/", {
  method: "POST",
  headers: { Accept: "application/pdf" },
  body: zpl,
});
await require("fs/promises").writeFile("label.pdf", Buffer.from(await res.arrayBuffer()));
$zpl = "^xa^cfa,50^fo100,100^fdHello World^fs^xz";
$ch = curl_init("https://api.openzpl.com/v1/printers/8dpmm/labels/4x6/0/");
curl_setopt_array($ch, [CURLOPT_POST => true, CURLOPT_POSTFIELDS => $zpl, CURLOPT_RETURNTRANSFER => true]);
file_put_contents("label.png", curl_exec($ch));

Request headers

HeaderValuesDefault
Acceptimage/png or application/pdfPNG
X-QualityGrayscale (8-bit, smooth edges) or Bitonal (1-bit, smaller files)Grayscale
X-Rotation0, 90, 180 or 270, clockwise0

Responses and errors

Successful responses carry X-Total-Count, the number of labels the ZPL produces, ^PQ copies included. Errors are plain text that starts with ERROR:.

StatusMeaning
400A parameter is invalid, the label is too large, or the index is out of range.
406The Accept header asks for an output format that isn't available yet.
413The body is over 1 MB, or the ZPL produces more than 50 labels.
429Too many requests. Wait the number of seconds in Retry-After.
503The label took longer than 10 seconds to render. Lower the density or the size.