ZPL API za renderiranje: ZPL u PNG i PDF preko HTTP
Jedna točka krajnjeg priključka generira ZPL u PNG ili PDF. Kompatibilna je s Labelaryjevim v1 API: isti putovi, zaglavlja i pogreške.
Generirajte oznaku
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}/
dpmm | Gustoća ispisa: 6dpmm, 8dpmm, 12dpmm, 24dpmm. |
width, height | Veličina oznake u inčima, na primjer 4x6 ili 2.25x1.25. Do 15 inča svaki. |
index | Koju oznaku prikazati, počinjući od 0. Ostavite to prazno za PDF izlaz da dobijete svaku oznaku, jednu po stranici. |
zpl | Za GET, URL-enkodirani ZPL. Kodirajte # kao %23. Koristite POST za sve dugotrajne zahtjeve. |
S POST-om pošaljite ZPL kao neobrađeno tijelo zahtjeva ili kao višekratno polje obrasca nazvano file.
API ključevi
Bez ključa dobivate 3 oznake dnevno po IP adresi, dovoljno za probati. S ključem iz vašeg kontrolnog panela, šaljete ga u X-API-Key zaglavlju i primjenjuju se ograničenja plana vašeg radnog prostora.
curl https://api.openzpl.com/v1/printers/8dpmm/labels/4x6/0/ \ -H "X-API-Key: oz_live_…" --data-binary @label.zpl > label.png
Primjeri
Svaka šalje label.zpl, sprema label.pdf i prikazuje poruku o grešci API-ja ako nešto nije u redu. Za PNG zatražite image/png i dodajte indeks naljepnice (/0/) u URL.
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"
Zaglavlja zahtjeva
| Zaglavlje | Vrijednosti | Zadano |
|---|---|---|
Accept | image/png, application/pdf | PNG |
X-Quality | Grayscale (8-bit, glatke ivice) ili Bitonal (1-bit, manji fajlovi) | Grayscale |
X-Rotation | 0, 90, 180, 270, u smjeru kazaljke na satu | 0 |
X-Language | zpl, epl, tspl, auto: je jezika pisača tijela. Bez toga, tijelo bez ^ ili ~ se čita kao EPL ili TSPL kada izgleda poput jednog. | zpl |
X-API-Key | Ključ vašeg radnog prostora, opcionalno | — |
Ograničenja
- 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,
^PQcopies 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
429withRetry-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).
Odgovori i greške
Uspješni odgovori uključuju X-Total-Count, broj oznaka koje ZPL proizvodi, uključujući ^PQ kopije. Greške su običan tekst koji počinje s ERROR:.
| Status | Značenje |
|---|---|
| 400 | Parametar je neispravan, etiketa je prevelika ili je indeks izvan raspona. |
| 401 | API ključ je nepoznat ili je opozvan. |
| 406 | Accept zaglavlje traži izlazni format koji još nije dostupan. |
| 413 | Tijelo je veće od 1 MB, ili ZPL proizvodi više od 50 etiketa. |
| 429 | Previše zahtjeva ili etiketa za vaš plan. Pričekajte broj sekundi u Retry-After. |
| 503 | Etiketi je trebalo više od 10 sekundi za renderiranje, ili je usluga na kapacitetu. Ponovno pokušajte, ili smanjite gustoću ili veličinu. |
Što motor crta, ignorira ili još ne podržava je na the compatibility page; koliko brzo renderira, izmjereno na produkcijskom poslužitelju, na the benchmarks page.
Predlošci: popunite spremljeni dizajn s vašim podacima
Dizajnirajte oznaku s {{variables}} mjestima, spremite je i kopirajte njen ID s vašeg kontrolnog panela: d123 za dizajn, l45 za spremljenu oznaku. Tada vaš sustav šalje samo podatke, s API ključem.
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
Koristite {"data": {...}} za jednu oznaku ili {"rows": [...]} za do 50. Accept daje PDF ili PNG, ili text/plain ispunjeni ZPL za slanje na pisač. Vrijednosti su escape-ane, tako da vaši podaci nikada ne mogu započeti ZPL naredbu.
Ispisujte na lokalnom pisaču
S print agent koji radi pored pisača, POST /v1/print-jobs stavlja ZPL u red za njega, a POST /v1/templates/{id}/print ispunjava spremljeni dizajn. Oba uzimaju ime printer i vraćaju ID zadatka; GET /v1/print-jobs/{id} vam govori je li ispisano.
Pitanja
Koliko košta API?
Bez ključa možete isprobati s 3 naljepnice dnevno. Besplatan ključ omogućuje 20 naljepnica dnevno, a paid plans počinju od 29 USD mjesečno za 100,000 naljepnica.
Je li kompatibilan s Labelary?
Da: isti putovi, zaglavlja i greške. Promijenite naziv hosta i pošaljite svoj ključ, kao što migration guide pokazuje.
Čuvate li moje etikete?
Ne s API ključem: oznaka se renderira i vraća. privacy page sadrži detalje i rokove.
Može li AI asistent to koristiti?
Da, putem MCP server: Claude, Cursor i drugi asistenti mogu renderirati oznake s tim.
OpenAPI i Markdown
Isti ugovor je objavljen kao OpenAPI 3.1 i kao Markdown, za generatore koda i pomoćnike u kodiranju.
Vodiči korak po korak: Python, Node.js, PHP, C#. Premještanje s Labelary: migration guide.