Langkau ke kandungan

API pemaparan ZPL: ZPL ke PNG dan PDF melalui HTTP

Satu titik akhir merender ZPL kepada PNG atau PDF. Ia serasi dengan API v1 Labelary: laluan, header dan ralat yang sama.

Render 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}/
dpmmKepadatan cetak: 6dpmm, 8dpmm, 12dpmm, 24dpmm.
width, heightSaiz label dalam inci, contohnya 4x6 atau 2.25x1.25. Hingga 15 inci setiap satu.
indexLabel mana yang hendak dirender, bermula dari 0. Tinggalkan kosong untuk output PDF untuk mendapatkan setiap label, satu per halaman.
zplUntuk GET, ZPL yang di-URL-encode. Kod # sebagai %23. Gunakan POST untuk apa-apa yang panjang.

Dengan POST, hantarkan ZPL sebagai badan permintaan mentah, atau sebagai medan borang pelbagai bahagian bernama file.

Kunci API

Tanpa kunci, anda mendapat 3 label sehari bagi setiap alamat IP, cukup untuk mencubanya. Dengan kunci dari papan pemuka anda, hantarkan dalam header X-API-Key dan had pelan ruang kerja anda dikenakan.

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

Contoh-contoh

Setiap satu menghantar label.zpl, menyimpan label.pdf dan menunjukkan mesej ralat API jika berlaku kesilapan. Untuk PNG, minta image/png dan tambahkan indeks label (/0/) ke 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"

Header permintaan

PenyandarNilaiLalai
Acceptimage/png, application/pdfPNG
X-QualityGrayscale (8-bit, tepi halus) atau Bitonal (1-bit, fail lebih kecil)Grayscale
X-Rotation0, 90, 180, 270, searah jam0
X-Languagezpl, epl, tspl, auto: bahasa pencetak badan. Tanpanya, badan yang tiada ^ atau ~ dibaca sebagai EPL atau TSPL apabila ia kelihatan seperti itu.zpl
X-API-KeyKunci ruang kerja anda, pilihan—

Had

  • 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).

Tanggapan dan ralat

Tanggapan yang berjaya membawa X-Total-Count, jumlah label yang dihasilkan oleh ZPL, termasuk ^PQ salinan. Ralat adalah teks biasa yang bermula dengan ERROR:.

StatusMaksud
400Sebuah parameter tidak sah, label terlalu besar, atau indeks di luar jangkauan.
401Kunci API tidak dikenali atau telah ditarik balik.
406Tajuk Accept meminta format output yang masih tidak tersedia.
413Badan melebihi 1 MB, atau ZPL menghasilkan lebih daripada 50 label.
429Terlalu banyak permintaan atau label untuk rancangan anda. Tunggu bilangan saat dalam Retry-After.
503Label mengambil masa lebih daripada 10 saat untuk dirender, atau perkhidmatan berada pada kapasiti. Cuba lagi, atau kurangkan ketumpatan atau saiz.

Apa yang dilukis oleh enjin, diabaikan atau tidak disokong lagi ada pada the compatibility page; seberapa pantas ia menunjukkannya, diukur pada pelayan pengeluaran, pada the benchmarks page.

Templat: isikan reka bentuk yang disimpan dengan data anda

Reka label dengan penanda tempat {{variables}}, simpan ia, dan salin ID dari papan pemuka anda: d123 untuk reka bentuk, l45 untuk label yang disimpan. Kemudian sistem anda menghantar hanya data, dengan kunci API.

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

Gunakan {"data": {...}} untuk satu label atau {"rows": [...]} untuk maksimum 50. Accept menghasilkan PDF atau PNG, atau text/plain ZPL yang diisi untuk dihantar kepada pencetak. Nilai- nilai akan dipindahkan, jadi data anda tidak pernah boleh memulakan arahan ZPL.

Cetak pada pencetak tempatan

Dengan print agent berjalan bersebelahan pencetak, POST /v1/print-jobs menjadualkan ZPL untuknya dan POST /v1/templates/{id}/print mengisi reka bentuk yang disimpan. Kedua-duanya mengambil nama printer dan mengembalikan ID tugas; GET /v1/print-jobs/{id} memberitahu anda sama ada ia dicetak.

Soalan

Berapakah kos API?

Tanpa kunci anda boleh mencubanya dengan 3 label sehari. Kunci percuma membenarkan 20 label sehari, dan paid plans bermula dari $29 sebulan untuk 100,000 label.

Adakah ia serasi dengan Labelary?

Ya: laluan, header dan ralat yang sama. Tukar nama hos dan hantarkan kunci anda, seperti yang ditunjukkan oleh migration guide.

Adakah anda menyimpan label saya?

Tidak dengan kunci API: label tersebut dihasilkan dan dikembalikan. privacy page mempunyai butiran dan tarikh akhir.

Bolehkah pembantu AI menggunakannya?

Ya, melalui MCP server: Claude, Cursor dan pembantu lain boleh menghasilkan label dengan itu.

OpenAPI dan Markdown

Kontrak yang sama diterbitkan sebagai OpenAPI 3.1 dan sebagai Markdown, untuk penjana kod dan pembantu pengkodan.

Panduan langkah demi langkah: Python, Node.js, PHP, C#. Berpindah dari Labelary: migration guide.

Maklumbalas