API απόδοσης ZPL: ZPL σε PNG και PDF μέσω HTTP
Ένα endpoint αποδίδει ZPL σε PNG ή PDF. Είναι συμβατό με το API v1 της Labelary: οι ίδιες διαδρομές, κεφαλίδες και σφάλματα.
Αποδοχή μιας ετικέτας
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, το URL-encoded ZPL. Κωδικοποιήστε το # ως %23. Χρησιμοποιήστε POST για οτιδήποτε είναι μεγάλο. |
Με POST, στείλτε το ZPL ως το ακατέργαστο σώμα αίτησης, ή ως ένα multipart form field με όνομα 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"
Επικεφαλίδες αίτησης
| Επικεφαλίδα | Τιμές | Προεπιλογή |
|---|---|---|
Accept | image/png, application/pdf | PNG |
X-Quality | Grayscale (8-bit, ομαλές άκρες) ή Bitonal (1-bit, μικρότερα αρχεία) | Grayscale |
X-Rotation | 0, 90, 180, 270, με τη φορά των δεικτών του ρολογιού | 0 |
X-Language | zpl, 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,
^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).
Απαντήσεις και σφάλματα
Οι επιτυχείς απαντήσεις φέρουν X-Total-Count, τον αριθμό των ετικετών που παράγει το ZPL, συμπεριλαμβανομένων ^PQ αντιτύπων. Τα σφάλματα είναι απλό κείμενο που αρχίζει με ERROR:.
| Κατάσταση | Σημασία |
|---|---|
| 400 | Ένας παράμετρος είναι μη έγκυρος, η ετικέτα είναι πολύ μεγάλη ή ο δείκτης είναι εκτός εύρους. |
| 401 | Το κλειδί API είναι άγνωστο ή έχει ανακληθεί. |
| 406 | Η κεφαλίδα Accept ζητάει μια μορφή εξόδου που δεν είναι διαθέσιμη ακόμα. |
| 413 | Το σώμα είναι πάνω από 1 MB ή το ZPL παράγει περισσότερες από 50 ετικέτες. |
| 429 | Πάρα πολλά αιτήματα ή ετικέτες για το σχέδιό σας. Περιμένετε τον αριθμό δευτερολέπτων στο Retry-After. |
| 503 | Η ετικέτα πήρε περισσότερα από 10 δευτερόλεπτα για να αποδοθεί, ή η υπηρεσία είναι πλήρης. Δοκιμάστε ξανά ή μειώστε την πυκνότητα ή το μέγεθος. |
Τι σχεδιάζει ο κινητήρας, αγνοεί ή δεν υποστηρίζει ακόμα βρίσκεται στο the compatibility page; πόσο γρήγορα αποδίδει, μετρημένο στον παραγωγικό διακομιστή, στο the benchmarks page.
Πρότυπα: συμπληρώστε ένα αποθηκευμένο σχέδιο με τα δεδομένα σας
Σχεδιάστε μια ετικέτα με {{variables}} placeholders, αποθηκεύστε την, και αντιγράψτε το 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 και επιστρέφουν ένα ID εργασίας; το GET /v1/print-jobs/{id} σας λέει αν εκτυπώθηκε.
Ερωτήσεις
Πόσο κοστίζει το API;
Χωρίς κωδικό μπορείτε να το δοκιμάσετε με 3 ετικέτες την ημέρα. Ένας δωρεάν κωδικός επιτρέπει 20 ετικέτες την ημέρα, και το paid plans ξεκινά από $29 το μήνα για 100.000 ετικέτες.
Είναι συμβατό με την Labelary;
Ναι: οι ίδιες διαδρομές, κεφαλίδες και σφάλματα. Αλλάξτε το hostname και στείλτε το κλειδί σας, όπως δείχνει το 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.