Spring til indhold

ZPL rendering API: ZPL til PNG og PDF over HTTP

Én slutpunkt gengiver ZPL til PNG eller PDF. Det er kompatibelt med Labelary's v1 API: samme stier, overskrifter og fejl.

Generér en 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}/
dpmmPrinttæthed: 6dpmm, 8dpmm, 12dpmm, 24dpmm.
width, heightEtiket størrelse i tommer, for eksempel 4x6 eller 2.25x1.25. Op til 15 tommer hver.
indexHvilken etiket der skal renderes, startende ved 0. Lad den være ude med PDF output for at få hver etiket, én pr. side.
zplFor GET, den URL-kodede ZPL. Kod # som %23. Brug POST til alt langt.

Med POST, send ZPL som den rå anmodningskrop, eller som et multipart formularfelt med navnet file.

API nøgler

Uden en nøgle får du 3 etiketter om dagen pr. IP-adresse, nok til at prøve det. Med en nøgle fra dit dashboard, send det i X-API-Key header, og grænserne for din arbejdsplads plan gælder.

curl https://api.openzpl.com/v1/printers/8dpmm/labels/4x6/0/ \
  -H "X-API-Key: oz_live_…" --data-binary @label.zpl > label.png

Eksempler

Hver enkelt sender label.zpl, gemmer label.pdf og viser API'ens fejlsmelding, hvis noget er galt. For en PNG, spørg om image/png og tilføj etikettens indeks (/0/) til URL'en.

curl https://api.openzpl.com/v1/printers/8dpmm/labels/4x6/ \
  -H "Accept: application/pdf" \
  --data-binary @label.zpl --fail-with-body -o label.pdf
import requests  # pip install requests

with open("label.zpl", "rb") as f:
    res = requests.post(
        "https://api.openzpl.com/v1/printers/8dpmm/labels/4x6/",
        data=f.read(),
        headers={"Accept": "application/pdf"},
        timeout=30,
    )
if not res.ok:
    raise SystemExit(res.text)
with open("label.pdf", "wb") as f:
    f.write(res.content)
// Node.js 18+; save as label.mjs
import { readFile, writeFile } from "node:fs/promises";

const res = await fetch("https://api.openzpl.com/v1/printers/8dpmm/labels/4x6/", {
  method: "POST",
  headers: { Accept: "application/pdf" },
  body: await readFile("label.zpl"),
});
if (!res.ok) throw new Error(await res.text());
await writeFile("label.pdf", Buffer.from(await res.arrayBuffer()));
<?php
$ch = curl_init("https://api.openzpl.com/v1/printers/8dpmm/labels/4x6/");
curl_setopt_array($ch, [
    CURLOPT_POST => true,
    CURLOPT_POSTFIELDS => file_get_contents("label.zpl"),
    CURLOPT_HTTPHEADER => ["Accept: application/pdf"],
    CURLOPT_RETURNTRANSFER => true,
]);
$pdf = curl_exec($ch);
if (curl_getinfo($ch, CURLINFO_RESPONSE_CODE) !== 200) {
    exit($pdf);
}
file_put_contents("label.pdf", $pdf);
using var http = new HttpClient();
var req = new HttpRequestMessage(HttpMethod.Post,
    "https://api.openzpl.com/v1/printers/8dpmm/labels/4x6/")
{
    Content = new StringContent(File.ReadAllText("label.zpl")),
};
req.Headers.Add("Accept", "application/pdf");

var res = await http.SendAsync(req);
if (!res.IsSuccessStatusCode)
    throw new Exception(await res.Content.ReadAsStringAsync());
File.WriteAllBytes("label.pdf", await res.Content.ReadAsByteArrayAsync());
// Java 11+
import java.net.URI;
import java.net.http.*;
import java.nio.file.Path;

public class Label {
    public static void main(String[] args) throws Exception {
        var req = HttpRequest.newBuilder(
                URI.create("https://api.openzpl.com/v1/printers/8dpmm/labels/4x6/"))
            .header("Accept", "application/pdf")
            .POST(HttpRequest.BodyPublishers.ofFile(Path.of("label.zpl")))
            .build();
        var res = HttpClient.newHttpClient()
            .send(req, HttpResponse.BodyHandlers.ofByteArray());
        if (res.statusCode() != 200)
            throw new RuntimeException(new String(res.body()));
        java.nio.file.Files.write(Path.of("label.pdf"), res.body());
    }
}
package main

import (
	"io"
	"log"
	"net/http"
	"os"
)

func main() {
	zpl, err := os.Open("label.zpl")
	if err != nil {
		log.Fatal(err)
	}
	req, _ := http.NewRequest("POST", "https://api.openzpl.com/v1/printers/8dpmm/labels/4x6/", zpl)
	req.Header.Set("Accept", "application/pdf")
	res, err := http.DefaultClient.Do(req)
	if err != nil {
		log.Fatal(err)
	}
	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)
	if res.StatusCode != 200 {
		log.Fatal(string(body))
	}
	os.WriteFile("label.pdf", body, 0o644)
}
require "net/http"

uri = URI("https://api.openzpl.com/v1/printers/8dpmm/labels/4x6/")
res = Net::HTTP.post(uri, File.binread("label.zpl"), "Accept" => "application/pdf")
abort res.body unless res.is_a?(Net::HTTPSuccess)
File.binwrite("label.pdf", res.body)
Invoke-WebRequest -Method Post `
  -Uri "https://api.openzpl.com/v1/printers/8dpmm/labels/4x6/" `
  -Headers @{ Accept = "application/pdf" } `
  -InFile "label.zpl" -OutFile "label.pdf"

Anmodningsheaders

OverskriftVærdierStandard
Acceptimage/png, application/pdfPNG
X-QualityGrayscale (8-bit, glatte kanter) eller Bitonal (1-bit, mindre filer)Grayscale
X-Rotation0, 90, 180, 270, med uret0
X-Languagezpl, epl, tspl, auto: kroppens printer sprog. Uden det bliver en krop uden ^ eller ~ læst som EPL eller TSPL, når den ligner en.zpl
X-API-KeyDit arbejdsområde nøgle, valgfrit—

Grænser

  • Without a key: 3 requests per second and 3 labels per UTC day, per IP address. With a free key from the dashboard: 20 labels per UTC day.
  • Labels, not requests, count against the allowance (per UTC day on Free, per UTC calendar month on paid plans): every label rendered, ^PQ copies and PDF pages included. A 10-label PDF is 1 request and 10 labels.
  • Every request: up to 50 labels, a 1 MB body, 15 inches per side, and 10 seconds of render time.
  • Paid plans (Pro $29/month: 10 requests/s and 100,000 labels/month, Business $99/month: 20 requests/s and 1,000,000 labels/month): subscriptions, monthly or yearly, from the dashboard's Billing page (card, through Stripe), and you can cancel at any time. The workspace's API keys move to the plan's limits as soon as the payment is approved.
  • Over a limit the API answers 429 with Retry-After (seconds) and a body that names the limit, e.g. ERROR: Daily limit reached: 20 labels per UTC day on this plan (^PQ copies and PDF pages count).

Svar og fejl

Succesfulde svar indeholder X-Total-Count, antallet af etiketter som ZPL producerer, ^PQ kopier inkluderet. Fejl er almindelig tekst, der starter med ERROR:.

StatusBetydning
400En parameter er ugyldig, etiketten er for stor, eller indekset er uden for rækkevidde.
401API-nøglen er ukendt eller blev tilbagekaldt.
406Accept headeren anmoder om et outputformat, som endnu ikke er tilgængeligt.
413Kroppen er over 1 MB, eller ZPL producerer mere end 50 labels.
429For mange anmodninger eller labels til din plan. Vent antallet af sekunder i Retry-After.
503Labelen tog længere end 10 sekunder at gengive, eller tjenesten er ved at være fyldt. Prøv igen, eller sænk densiteten eller størrelsen.

Hvad motoren tegner, ignorerer eller endnu ikke understøtter, er på the compatibility page; hvor hurtigt det gengiver, målt på produktionsserveren, på the benchmarks page.

Skabeloner: udfyld et gemt design med dine data

Design en etiket med {{variables}} pladsholdere, gem den, og kopier dens ID fra dit dashboard: d123 for et design, l45 for en gemt etiket. Så sender dit system kun dataene med en API-nøgle.

curl https://api.openzpl.com/v1/templates/d123 \
  -H "X-API-Key: oz_live_…" -H "Accept: application/pdf" \
  -d '{"rows": [{"sku": "A-100"}, {"sku": "A-101"}]}' > labels.pdf

Brug {"data": {...}} til én label eller {"rows": [...]} til op til 50. Accept giver en PDF eller PNG, eller text/plain den udfyldte ZPL til at sende til en printer. Værdier er undsluppet, så dine data kan aldrig starte en ZPL-kommando.

Print på en lokal printer

Med print agent der kører ved siden af printeren, køer POST /v1/print-jobs ZPL til den, og POST /v1/templates/{id}/print udfylder et gemt design. Begge tager et printer navn og returnerer et job-ID; GET /v1/print-jobs/{id} fortæller dig, om det blev printet.

Spørgsmål

Hvor meget koster API'en?

Uden en nøgle kan du prøve det med 3 labels om dagen. En gratis nøgle tillader 20 labels om dagen, og paid plans starter ved $29 om måneden for 100.000 labels.

Er det kompatibelt med Labelary?

Ja: de samme stier, headers og fejl. Skift værtsnavnet og send din nøgle, som migration guide viser.

Opbevarer I mine labels?

Ikke med en API-nøgle: etiketten bliver gengivet og returneret. privacy page har detaljerne og fristerne.

Kan en AI-assistent bruge det?

Ja, via MCP server: Claude, Cursor og andre hjælpere kan generere mærkater med det.

OpenAPI og Markdown

Den samme kontrakt er offentliggjort som OpenAPI 3.1 og som Markdown, til kodegeneratorer og kodeassistenter.

Trin-for-trin vejledninger: Python, Node.js, PHP, C#. Flytning fra Labelary: migration guide.

Feedback