ZPL atvaizdavimo API: ZPL į PNG ir PDF per HTTP
Vienas galas konvertuoja ZPL į PNG arba PDF. Jis yra suderinamas su Labelary v1 API: tos pačios keliai, antraštės ir klaidos.
Generuoti etiketę
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 | Spausdinimo tankis: 6dpmm, 8dpmm, 12dpmm, 24dpmm. |
width, height | Etiketo dydis coliais, pavyzdžiui, 4x6 arba 2.25x1.25. Iki 15 colių kiekvienas. |
index | Kurią etiketę atvaizduoti, pradedant nuo 0. Neišimkite su PDF išvestimi, kad gautumėte kiekvieną etiketę, po vieną puslapyje. |
zpl | GET užklausai URL koduotas ZPL. Koduokite # kaip %23. Naudokite POST ilgesniems užklausoms. |
Naudodami POST, siųskite ZPL kaip žalią užklausos kūną arba kaip daugiapartinį formos lauką, pavadintą file.
API raktai
Be rakto gaunate 3 etiketės per dieną kiekvienam IP adresui, ko pakanka tam, kad tai išbandytumėte. Su raktu iš jūsų valdymo skydelio, siųskite jį X-API-Key antraštėje, o jūsų darbalaukių plano limitai galioja.
curl https://api.openzpl.com/v1/printers/8dpmm/labels/4x6/0/ \ -H "X-API-Key: oz_live_…" --data-binary @label.zpl > label.png
Pavyzdžiai
Kiekvienas siunčia label.zpl, išsaugo label.pdf ir rodo API klaidos pranešimą, jei kažkas negerai. Norėdami gauti PNG, prašykite image/png ir pridėkite etiketės indeksą (/0/) prie 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"
Užklausos antraštės
| Antraštė | Reikšmės | Numatytasis |
|---|---|---|
Accept | image/png, application/pdf | PNG |
X-Quality | Grayscale (8-bit, sklandžiai kraštai) arba Bitonal (1-bit, mažesni failai) | Grayscale |
X-Rotation | 0, 90, 180, 270, laikrodžio rodyklės kryptimi | 0 |
X-Language | zpl, epl, tspl, auto: kūno spausdintuvo kalba. Be jos, kūnas, kuriame nėra ^ ar ~, yra skaitomas kaip EPL arba TSPL, kai jis atrodo kaip toks. | zpl |
X-API-Key | Jūsų darbo vietos raktas, pasirinktinai | — |
Limitai
- 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).
Atsakymai ir klaidos
Sėkmingi atsakymai turi X-Total-Count, etikečių, kurias generuoja ZPL, skaičių, ^PQ kopijos įskaičiuotos. Klaidos yra paprastas tekstas, kuris prasideda nuo ERROR:.
| Statusas | Reikšmė |
|---|---|
| 400 | Parametras neteisingas, etiketė per didelė arba indeksas už ribų. |
| 401 | API raktas nežinomas arba buvo atšauktas. |
| 406 | Accept antraštė prašo išvesties formato, kuris dar nėra prieinamas. |
| 413 | Failo dydis viršija 1 MB, arba ZPL sukuria daugiau nei 50 etikečių. |
| 429 | Per daug užklausų arba etikečių jūsų plane. Palaukite nurodyto laiko Retry-After. |
| 503 | Etiketė sugaišo daugiau nei 10 sekundžių atvaizduoti, arba paslauga yra pilnai užimta. Bandykite dar kartą, arba sumažinkite tankį arba dydį. |
Ką variklis piešia, ignoruoja ar dar nepalaiko, galite rasti the compatibility page; kaip greitai jis vaizduoja, matuojama gamybos serverio, the benchmarks page.
Šablonai: užpildykite išsaugotą dizainą savo duomenimis
Sukurkite etiketę su {{variables}} vietomis, išsaugokite ją ir nukopijuokite jos ID iš savo valdymo skydelio: d123 dizainui, l45 išsaugotai etiketei. Tada jūsų sistema siunčia tik duomenis su API raktu.
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
Naudokite {"data": {...}} vienai etiketėms arba {"rows": [...]} iki 50. Accept suteikia PDF arba PNG, arba text/plain užpildytą ZPL, kad galėtumėte siųsti spausdintuvui. Vertės yra pabėgusios, todėl jūsų duomenys niekada negali pradėti ZPL komandos.
Spausdinti ant vietinio spausdintuvo
Su print agent veikiančiu šalia spausdintuvo, POST /v1/print-jobs sustato ZPL eilę jam, o POST /v1/templates/{id}/print užpildo išsaugotą dizainą. Abu naudoja printer pavadinimą ir grąžina užduoties ID; GET /v1/print-jobs/{id} informuoja, ar buvo atspausdinta.
Klausimai
Kiek kainuoja API?
Be rakto galite išbandyti su 3 etiketėmis per dieną. Nemokamas raktas leidžia 20 etikečių per dieną, o paid plans prasideda nuo 29 USD per mėnesį už 100 000 etikečių.
Ar tai suderinama su Labelary?
Taip: tie patys keliai, antraštės ir klaidos. Pakeiskite hostname ir siųskite savo raktą, kaip nurodyta migration guide.
Ar laikote mano etiketes?
Be API rakto: etiketė yra renderuojama ir grąžinama. privacy page turi detales ir terminus.
Ar AI asistentas gali tai naudoti?
Taip, per MCP server: Claude, Cursor ir kiti asistentai gali atvaizduoti etiketes su juo.
OpenAPI ir Markdown
Tas pats sutartis skelbiama kaip OpenAPI 3.1 ir kaip Markdown, kodų generatoriams ir programavimo asistentams.
Žingsnis po žingsnio gidai: Python, Node.js, PHP, C#. Migracija iš Labelary: migration guide.