ข้ามไปที่เนื้อหา

ZPL rendering API: ZPL เป็น PNG และ PDF ผ่าน HTTP

หนึ่ง endpoint ใช้ในการแสดงผล ZPL เป็น PNG หรือ PDF ซึ่งเข้ากันได้กับ Labelary's v1 API: เส้นทาง, headers และข้อผิดพลาดเหมือนกัน

เรนเดอร์ป้าย

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ความหนาแน่นการพิมพ์: 6dpmm, 8dpmm, 12dpmm, 24dpmm.
width, heightขนาดฉลากเป็นนิ้ว, เช่น 4x6 หรือ 2.25x1.25. สูงสุด 15 นิ้วแต่ละอัน.
indexป้ายใดที่จะเรนเดอร์ เริ่มจาก 0 หากไม่มีจะถูกสร้างทุกป้ายใน PDF หนึ่งป้ายต่อหน้า
zplสำหรับ GET, ZPL ที่เข้ารหัส URL-encoded. เข้ารหัส # เป็น %23. ใช้ POST สำหรับสิ่งที่ยาว.

ใช้ POST ส่ง ZPL เป็นเนื้อหาคำขอดิบ หรือเป็นฟอร์มฟิลด์แบบหลายส่วนชื่อ file.

คีย์ API

หากไม่มีคีย์คุณจะได้รับ 3 ฉลากต่อวันต่อที่อยู่ IP ซึ่งเพียงพอในการทดลอง หากมีคีย์จากแดชบอร์ดของคุณ ให้ส่งในส่วนหัว X-API-Key และข้อจำกัดของแผนพื้นที่ทำงานของคุณจะถูกใช้

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

ตัวอย่าง

แต่ละรายการจะส่ง label.zpl บันทึก label.pdf และแสดงข้อความแสดงข้อผิดพลาดของ API หากมีข้อผิดพลาดเกิดขึ้น สำหรับ PNG ให้ขอ image/png และเพิ่มดัชนีของฉลาก (/0/) ลงใน 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"

หัวข้อคำขอ

หัวข้อค่าค่าเริ่มต้น
Acceptimage/png, application/pdfPNG
X-QualityGrayscale (8-bit, ขอบเรียบ) หรือ Bitonal (1-bit, ไฟล์ขนาดเล็กกว่า)Grayscale
X-Rotation0, 90, 180, 270, ตามเข็มนาฬิกา0
X-Languagezpl, epl, tspl, auto: ภาษาเครื่องพิมพ์ของเนื้อหา หากไม่มีมัน เนื้อหาที่ไม่มี ^ หรือ ~ จะถูกอ่านว่าเป็น EPL หรือ TSPL เมื่อมันดูเหมือนหนึ่งzpl
X-API-Keyคีย์พื้นที่ทำงานของคุณ, ไม่บังคับ—

ข้อจำกัด

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

การตอบกลับและข้อผิดพลาด

การตอบกลับที่สำเร็จมี X-Total-Count ซึ่งเป็นจำนวนป้ายที่ ZPL ผลิต ^PQ สำเนารวมอยู่ด้วย ข้อผิดพลาดคือข้อความธรรมดาที่เริ่มต้นด้วย ERROR:.

สถานะความหมาย
400พารามิเตอร์ไม่ถูกต้อง, ป้ายมีขนาดใหญ่เกินไป, หรือดัชนีอยู่นอกขอบเขต
401คีย์ API ไม่รู้จักหรือถูกเพิกถอน.
406Accept กำลังร้องขอรูปแบบข้อมูลส่งออกที่ยังไม่พร้อมใช้งาน.
413ขนาดไฟล์เกิน 1 MB หรือ ZPL สร้างป้ายมากกว่า 50 ป้าย.
429มีคำขอหรือป้ามากเกินไปสำหรับแผนของคุณ รอจำนวนวินาทีใน Retry-After.
503การเรนเดอร์ป้ายใช้เวลานานกว่า 10 วินาที หรือตัวบริการมีความจุเต็ม ลองใหม่ หรือปรับลดความหนาแน่นหรือขนาด.

สิ่งที่เครื่องยนต์วาด, มองข้ามหรือยังไม่สนับสนุนคือที่ the compatibility page; ความเร็วในการเรนเดอร์, วัดจากเซิร์ฟเวอร์การผลิต, บน the benchmarks page.

แม่แบบ: เติมการออกแบบที่บันทึกด้วยข้อมูลของคุณ

ออกแบบป้ายด้วย {{variables}} สถานที่แทนและบันทึก จากนั้นคัดลอก ID จากแดชบอร์ดของคุณ: d123 สำหรับการออกแบบ, l45 สำหรับป้ายที่บันทึก. แล้วระบบของคุณจะส่งเฉพาะข้อมูลด้วย API key.

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

ใช้ {"data": {...}} สำหรับป้ายหนึ่งใบหรือ {"rows": [...]} สำหรับสูงสุด 50 ใบ Accept ให้ PDF หรือ PNG, หรือ text/plain ZPL ที่กรอกให้ส่งไปยังเครื่องพิมพ์ ค่าจะถูกเข้ารหัส ดังนั้นข้อมูลของคุณจึงไม่สามารถเริ่มคำสั่ง ZPL ได้.

พิมพ์บนเครื่องพิมพ์ท้องถิ่น

ด้วย print agent ที่ทำงานอยู่ข้างเครื่องพิมพ์ POST /v1/print-jobs จะจัดคิว ZPL สำหรับมัน และ POST /v1/templates/{id}/print จะเติมการออกแบบที่เก็บไว้ ทั้งสองต้องการชื่อ printer และคืนค่า job ID; GET /v1/print-jobs/{id} จะแจ้งให้คุณทราบว่ามันได้พิมพ์หรือไม่

คำถาม

API มีค่าใช้จ่ายเท่าไหร่?

หากไม่มีคีย์คุณสามารถทดลองใช้งานได้ 3 ป้ายต่อวัน คีย์ฟรีอนุญาต 20 ป้ายต่อวัน และ paid plans เริ่มต้นที่ $29 ต่อเดือนสำหรับ 100,000 ป้าย

มันเข้ากันได้กับ Labelary หรือไม่?

ใช่: เส้นทางเดียวกัน, ส่วนหัวและข้อผิดพลาดเดียวกัน เปลี่ยนชื่อโฮสต์และส่งคีย์ของคุณ ตามที่ migration guide แสดง

คุณเก็บฉลากของฉันหรือไม่?

ไม่ใช้ API key: ป้ายจะถูกเรนเดอร์และส่งกลับ. privacy page มีรายละเอียดและกำหนดเวลาต่างๆ.

ผู้ช่วย AI สามารถใช้มันได้หรือไม่?

ใช่ ผ่าน MCP server: Claude, Cursor และผู้ช่วยอื่น ๆ สามารถเรนเดอร์ฉลากด้วยมัน

OpenAPI และ Markdown

สัญญาเดียวกันเผยแพร่เป็น OpenAPI 3.1 และ Markdown สำหรับการสร้างโค้ดและผู้ช่วยเขียนโค้ด

คู่มือทีละขั้นตอน: Python, Node.js, PHP, C#. ย้ายจาก Labelary: migration guide.

ข้อเสนอแนะแสดงความคิดเห็น