Rendering, Anreicherung & Batch-Jobs

Gespeicherte Designs als PDF, PNG oder ZPL rendern, eigene Felder auf Carrier-Labels drucken und Batch-Jobs mit bis zu 10.000 Etiketten ausführen - mit Druck, Pickliste und Webhook, sobald der Job fertig ist. Alles auf api.zplcloud.com mit API-Key.

Authentifizierung (Header X-API-Key oder Basic Auth), Fehlerformat, der Header X-ZplCloud-Request-Id und der Webhook-Callback sind für alle Endpunkte gleich und in der API-Übersicht beschrieben. Alle Endpunkte dieser Seite außer dem älteren ZPL-Renderpfad akzeptieren die optionalen Query-Parameter webhookId=<id> und webhookResult=true|false; das Event steht jeweils beim Endpunkt (Payload und Signatur).

Design-IDs

Design-Endpunkte adressieren ein gespeichertes Design als <name>.<id>: das beim Speichern vergebene Design-Tag (Kleinbuchstaben, Ziffern, _ und -) und die numerische Design-ID, getrennt durch den letzten Punkt - zum Beispiel shipping-label.42.

  • Wo steht sie: Nach Speichern im Designer zeigen der Speichern-Dialog und die Statusleiste die vollständige ID (shipping-label.42). Dieselbe ID gilt für ZPL, PDF, PNG und Batch-Jobs.
  • Scope: Das Design muss zur Firma des API-Key-Besitzers gehören (Keys ohne Firma: zu dessen E-Mail). Name und Nummer müssen beide passen - sonst 404 Design "shipping-label" not found.
  • Formatfehler: 400 Invalid design ID - expected format "<name>.<id>" (e.g. my-label.42).
  • Datensätze: ein JSON-Array mit einem Objekt je Etikett; die Schlüssel sind die Binding-Namen im Design, z. B. [{"sku":"A-1001","qty":"2"}].

Design als PDF rendern

POST https://api.zplcloud.com/v1/pdf/render/design/{designId}

Eine PDF-Seite je Datensatz in Labelgröße und Auflösung des Designs. Ohne Body (oder mit []) wird das Design einmal mit seinem eigenen Inhalt gerendert. Das Kontingent wird vor dem Rendern geprüft.

ParameterTypHinweise
designId (Pfad)string<name>.<id>
BodyarrayOptional. Datensätze, max. 2.000 je Aufruf und 5 MB. Größere Mengen: Batch-Jobs.
webhookId, webhookResultQueryOptionaler Webhook-Callback, Event api.design.pdf.
curl -X POST "https://api.zplcloud.com/v1/pdf/render/design/shipping-label.42?webhookId=12" \
  -H "X-API-Key: sk_zplcloud_…" -H "Content-Type: application/json" \
  -d '[{"sku":"A-1001","qty":"2"},{"sku":"A-1002","qty":"5"}]' \
  -o labels.pdf -D -
HTTP/1.1 200 OK
Content-Type: application/pdf
Content-Disposition: attachment; filename=shipping-label.42.pdf; filename*=UTF-8''shipping-label.42.pdf
X-ZplCloud-Request-Id: 3f0c9a7e-5b1d-4c2e-9a41-7d0e6b2f8c13
X-ZplCloud-Webhook: queued
StatusFehler
400Ungültige Design-ID, ungültiges JSON, PDF rendering failed: …, ungültige webhookId.
401API-Key fehlt oder ist ungültig.
404Design nicht gefunden (oder nicht im Scope des Key-Besitzers).
413Body über 5 MB oder mehr als 2.000 Datensätze.
429Monatliches Label-Kontingent verbraucht, siehe Kontingent.

Renders: einer je Seite. Webhook api.design.pdf, Summary { design, format: "pdf", pages, bytes, widthMm, heightMm, dpi }; mit webhookResult=true kommt das PDF als Base64 mit.

Design als PNG rendern

POST https://api.zplcloud.com/v1/png/render/design/{designId}?record=0

Ein Etikett als PNG. Der Body ist dasselbe optionale Datensatz-Array; record wählt den Datensatz über den nullbasierten Index.

ParameterTypStandardHinweise
designId (Pfad)string-<name>.<id>
record (Query)int0Index im Datensatz-Array. Außerhalb: 400 record must be between 0 and n.
Bodyarray-Optionale Datensätze, max. 5 MB.
webhookId, webhookResultQuery-Optional, Event api.design.png.
curl -X POST "https://api.zplcloud.com/v1/png/render/design/shipping-label.42?record=1" \
  -H "X-API-Key: sk_zplcloud_…" -H "Content-Type: application/json" \
  -d '[{"sku":"A-1001"},{"sku":"A-1002"}]' -o preview.png

Antwort: 200 image/png, Dateiname <name>.<id>.png. Fehler: 400, 401, 404, 413 und 429 wie beim PDF. Renders: 1. Webhook api.design.png, Summary { design, format: "png", record, bytes, widthMm, heightMm, dpi }.

Design als ZPL rendern

POST https://api.zplcloud.com/v1/zpl/render/design/{designId}

Der bestehende ZPL-Pfad: gleiche Design-ID und gleiches Datensatz-Array, Antwort application/x-zpl; charset=utf-8 mit einem ^XA…^XZ-Block je Datensatz. Grenzen: 500 Datensätze, 1 MB Body. Wie PDF und PNG wird er gegen das monatliche Label-Kontingent geprüft: ein Render je Datensatz (mindestens 1), 429 { error, hint, limit, used, requested }, wenn das Kontingent aufgebraucht ist. Er erscheint zusätzlich in der API-Statistik und hat keinen Webhook-Callback. Für PDF-Ausgabe, Druck oder mehr Datensätze die Endpunkte oben (jeder Tarif) oder einen Batch-Job (Pro-Tarif) verwenden.

Label-Anreicherung

POST https://api.zplcloud.com/v1/enrich/zpl[?format=zpl]

Ergänzt jedes Etikett in fremdem ZPL - Amazon, UPS, FedEx, DHL, USPS - um eigene Textfelder: SKU, Lagerplatz, Menge, Bestellnummer, freier Text. Die Original-Kommandos bleiben byte-identisch; die Overlay-Kommandos werden je Etikett direkt vor dessen abschließendem ^XZ eingefügt. Der Carrier-Barcode wird nie angefasst.

Feature-Schalter

Den Endpunkt gibt es nur, solange die Label-Anreicherung in zplCloud aktiviert ist. Sonst antwortet er mit 404 Label enrichment is not available.

Pro-Tarif

Aufrufe der Label-Anreicherung setzen den Pro-Tarif des Key-Besitzers voraus. Andere Tarife erhalten 403, bevor der Body gelesen wird - ein angeforderter Webhook-Callback meldet den Fehler. Ist der Tarif nicht lesbar, lautet die Antwort 503. Die Antworttexte sind wie überall in der API Englisch:

HTTP/1.1 403 Forbidden

{
  "error": "Label enrichment calls require the Pro plan.",
  "plan": "starter",
  "hint": "Upgrade to Pro under Billing in the platform. GET /v1/quota shows your current plan.",
  "requestId": "3f0c9a7e-5b1d-4c2e-9a41-7d0e6b2f8c13"
}

Request-Body

FeldTypStandardHinweise
zplstringPflichtCarrier- oder Amazon-ZPL mit einem oder mehreren ^XA…^XZ-Etiketten, max. 4.000.000 Zeichen.
dpiint203Auflösung dieses ZPL: 203, 300 oder 600. Rechnet Millimeter in Dots um.
fieldsarrayPflicht1 bis 50 Overlay-Felder (Tabelle unten).
recordsarray-Objekte Spalte → Wert, max. 10.000. Werte müssen JSON-Strings sein.
clearZoneboolfalseZuerst eine weiße Fläche zeichnen, damit Overlays auf bedruckten Bereichen lesbar bleiben.
zoneX, zoneY, zoneW, zoneHmm0Position und Größe der weißen Fläche; nur wenn zoneW und zoneH größer 0 sind.
Feld-EigenschaftTypStandardHinweise
x, ymm-Linke obere Ecke des Textblocks (^FO).
wmm-Breite des Textblocks (^FB), mindestens eine Zeichenhöhe.
hmm-Höhe. Zeilen im Block = h ÷ Schrifthöhe, abgerundet, mindestens 1.
fontPtnumber9Schriftgröße in Punkt, skalierbare Schrift ^A0; Dots = fontPt × dpi / 72 (min. 6).
alignstringLL, C oder R innerhalb von w.
columnstring-Wert aus dem Datensatz des Etiketts. Schlüssel ohne Beachtung der Groß-/Kleinschreibung, ein führendes $ wird ignoriert; fehlt der Schlüssel, wird nichts gedruckt.
textstring-Statischer Text; gilt, wenn keine column gesetzt ist oder das Etikett keinen Datensatz hat.
labelstring-Optionales Präfix, gedruckt als label: Wert.

Felder mit leerem Wert werden übersprungen. Text geht als UTF-8 (^CI28) raus; ^ und ~ in Werten werden per ^FH hex-kodiert, Daten können also keine Kommandos einschleusen.

Zuordnung Datensatz → Etikett

  • Das ZPL wird in seine ^XA…^XZ-Blöcke geteilt; Datensatz n gehört zu Etikett n (beide ab 0, in Reihenfolge).
  • Genau ein Datensatz: Er gilt für alle Etiketten (z. B. dieselbe Bestellnummer auf allen Paketen einer Sendung).
  • Keine Datensätze: Nur text-Felder werden gedruckt, auf jedem Etikett.
  • Weniger Datensätze als Etiketten: Die übrigen Etiketten bekommen nur ihren statischen text. Überzählige Datensätze werden ignoriert.
  • Alles zwischen den Blöcken bleibt erhalten. ZPL ohne ^XA…^XZ-Block kommt unverändert mit labels: 0 zurück.

Antwort: JSON { "zpl": "…", "labels": 2 }; mit ?format=zpl das rohe ZPL als application/x-zpl; charset=utf-8, direkt druckbar. Renders: einer je Etikett (mindestens 1), nie durch das Kontingent blockiert. Webhook api.enrich.completed, Summary { labels, fields, records, dpi, zplBytes }.

StatusFehler
400zpl is required …, fields is required …, Too many fields (max 50)., dpi must be 203, 300 or 600., format must be json (default) or zpl., ungültiges JSON (z. B. eine Zahl statt eines Strings in records).
403Label enrichment calls require the Pro plan. - der Key-Besitzer hat nicht den Pro-Tarif (Body mit plan und hint).
404Label-Anreicherung ist nicht aktiviert.
413zpl über 4.000.000 Zeichen, mehr als 10.000 Datensätze oder Body über 24 MB.
503Der Tarif konnte nicht geprüft werden (Datenbank) - später erneut versuchen.

Beispiel: SKU und Lagerplatz auf dem Carrier-Label

Ein 4 × 6 Zoll großes Carrier-Label (101,6 × 152,4 mm, 203 dpi) bekommt unten auf einem weißen Streifen links die SKU und rechts den Lagerplatz:

{
  "zpl": "^XA…Carrier-Label 1…^XZ^XA…Carrier-Label 2…^XZ",
  "dpi": 203,
  "clearZone": true, "zoneX": 3, "zoneY": 136, "zoneW": 96, "zoneH": 12,
  "fields": [
    { "label": "SKU",   "column": "sku", "x": 5,  "y": 139, "w": 60, "h": 6, "fontPt": 14 },
    { "label": "Platz", "column": "bin", "x": 66, "y": 139, "w": 31, "h": 6, "fontPt": 14, "align": "R" }
  ],
  "records": [
    { "sku": "A-1001", "bin": "R04-B2" },
    { "sku": "A-1002", "bin": "R11-A1" }
  ]
}
# Carrier-ZPL aus einer Datei in den Body setzen und druckfertiges ZPL zurückbekommen
jq --rawfile zpl carrier-labels.zpl '.zpl = $zpl' enrich.json \
  | curl -X POST "https://api.zplcloud.com/v1/enrich/zpl?format=zpl" \
      -H "X-API-Key: sk_zplcloud_…" -H "Content-Type: application/json" \
      --data-binary @- -o enriched.zpl

Jedes Etikett erhält vor seinem ^XZ ^FO40,1111^A0N,39,39^FB480,1,0,L,^CI28^FDSKU: A-1001^FS und das rechtsbündige Lagerplatz-Feld.

Batch-Jobs

POST https://api.zplcloud.com/v1/batch/design/{designId}

Rendert ein gespeichertes Design mit vielen Datensätzen in einem Aufruf: Ausgabe als ZPL oder PDF, optional eine Pickliste als PDF und optional der Druck. Standardmäßig synchron; "async": true antwortet sofort und ruft den Webhook, wenn der Job fertig ist.

Pro-Tarif

Batch-Jobs - auch mit Pickliste und Druck - setzen den Pro-Tarif des Key-Besitzers voraus. Andere Tarife erhalten 403, bevor der Body gelesen wird - ein angeforderter Webhook-Callback meldet den Fehler. Ist der Tarif nicht lesbar, lautet die Antwort 503. Job-Status, Ausgabe und Pickliste (GET /v1/batch/jobs/…) werden nicht auf den Tarif geprüft; Jobs gibt es nur, wenn sie im Pro-Tarif gestartet wurden. In anderen Tarifen je Aufruf bis zu 500 Datensätze als ZPL oder 2.000 als PDF rendern.

HTTP/1.1 403 Forbidden

{
  "error": "Batch jobs require the Pro plan.",
  "plan": "starter",
  "hint": "Upgrade to Pro under Billing in the platform. GET /v1/quota shows your current plan.",
  "requestId": "3f0c9a7e-5b1d-4c2e-9a41-7d0e6b2f8c13"
}
FeldTypStandardHinweise
recordsarrayPflicht1 bis 10.000 Objekte, eines je Etikett (PDF-Ausgabe: max. 5.000). Werte dürfen Strings, Zahlen oder Booleans sein.
outputstringzplzpl, pdf oder none. none braucht einen printer oder eine pickList.
printerstring-Druckziel wl:{id}, Weblink-Seriennummer, rp:{id} oder vp:{id}, siehe Drucken.
pickListobject-Pickliste als PDF aus denselben Datensätzen, siehe Pickliste.
asyncboolfalsetrue: 202 mit jobId, der Job läuft im Hintergrund.

Body max. 32 MB. Vor dem Rendern wird in dieser Reihenfolge geprüft: Tarif (Pro), Body, Datensätze, Ausgabe, Design, Kontingent (Anzahl Datensätze), Druckziel - ein Tippfehler beim Drucker fällt also sofort auf. Query-Parameter webhookId / webhookResult: Event api.batch.completed.

Drucken

ZielDruckerZustellung
wl:{id} oder SeriennummerWeblink-Cloud-DruckerÜber die Weblink-Verbindung des Druckers. Muss für den Key-Besitzer sichtbar sein; ein gesperrter Drucker antwortet mit 409.
rp:{id}Remote-DruckerÜber den zplCloud-CLI-Agenten (zplcloud proxy) im eigenen Netz; der Agent muss online sein.
vp:{id}Virtueller DruckerLandet in der Historie des virtuellen Druckers; max. 512 KB je Block. Nur wenn virtuelle Drucker aktiviert sind.

Die Ziele liefern GET /v1/printers (an den Key gebundene Drucker) und GET /v1/company/printers (alle Drucker der Firma) - verwendet wird das Feld target eines Eintrags. Etiketten gehen in Blöcken zu je 100 raus, eine Anfrage je Block. Der erste fehlgeschlagene Block stoppt den Druck: Der Job endet mit print_failed, print.error nennt den Grund, sentChunks / sentLabels zeigen den Fortschritt. Ausgabe und Pickliste werden trotzdem geliefert; ein print_failed-Job antwortet mit HTTP 200 und zählt alle Datensätze.

Fehler beim Ziel: 400 Invalid remote printer target - expected rp:{id}. (analog für vp: und wl:), 400 Virtual printers are not available., 404 Printer not found. / Remote printer not found. / Virtual printer not found., 409 The printer is blocked.

Pickliste

FeldTypStandardHinweise
titlestringDesign-IDÜberschrift auf Seite 1.
subtitlestringDatum, Uhrzeit, ZeilenStandard: 2026-09-11 10:15 UTC · 250 Positionen.
columnsstring[]alle SchlüsselSpalten in dieser Reihenfolge; Standard sind alle Schlüssel des ersten Datensatzes. Max. 20.
groupBystring-Gruppiert die Zeilen nach dieser Spalte (Gruppenzeile Spalte: Wert), Gruppen sortiert.
sortBystring-Sortiert die Zeilen (innerhalb der Gruppen) natürlich: A-7 vor A-10.
checkboxbooltrueAnkreuzkästchen am Anfang jeder Zeile.
paperstringA4A4 oder Letter.

Nur verfügbar, wenn Picklisten aktiviert sind (sonst 400 Pick lists are not available.). Eine Pickliste fasst höchstens 5.000 Datensätze; Werte, die keine Strings sind, erscheinen als JSON-Text.

Synchrone Antwort

{
  "jobId": "3f0c9a7e-5b1d-4c2e-9a41-7d0e6b2f8c13",
  "status": "succeeded",
  "design": "shipping-label.42",
  "labels": 250,
  "durationMs": 1840,
  "output": {
    "format": "zpl",
    "contentType": "application/x-zpl; charset=utf-8",
    "bytes": 91234,
    "encoding": "utf-8",
    "data": "^XA…^XZ"
  },
  "pickList": { "contentType": "application/pdf", "bytes": 48211, "encoding": "base64", "data": "JVBERi0x…" },
  "print": {
    "printer": "rp:12", "type": "remote", "name": "Packtisch 1",
    "chunks": 3, "chunkSize": 100, "sentChunks": 3, "sentLabels": 250, "error": null
  },
  "outputUrl": "/v1/batch/jobs/3f0c9a7e-5b1d-4c2e-9a41-7d0e6b2f8c13/output",
  "pickListUrl": "/v1/batch/jobs/3f0c9a7e-5b1d-4c2e-9a41-7d0e6b2f8c13/picklist"
}
  • jobId entspricht dem Header X-ZplCloud-Request-Id. status ist succeeded oder print_failed.
  • output ist bei none null; PDF-Ausgabe kommt als base64. pickList und print sind null, wenn nicht angefordert.
  • outputUrl ist null, wenn die Ausgabe größer als 20 MB ist (sie steht dann nur in dieser Antwort).
  • Renderfehler: 400 { "error": "Rendering failed: …", "jobId": "…", "requestId": "…" }.

Asynchrone Jobs

HTTP/1.1 202 Accepted

{
  "jobId": "3f0c9a7e-5b1d-4c2e-9a41-7d0e6b2f8c13",
  "status": "queued",
  "design": "shipping-label.42",
  "labels": 250,
  "output": "none",
  "printer": "rp:12",
  "statusUrl": "/v1/batch/jobs/3f0c9a7e-5b1d-4c2e-9a41-7d0e6b2f8c13",
  "webhook": { "id": 12, "includeResult": false, "event": "api.batch.completed" }
}
  • Alle Prüfungen (Tarif, Datensätze, Design, Kontingent, Druckziel) laufen vor dem 202; diese Fehler kommen also weiterhin direkt zurück.
  • Je Server laufen höchstens zwei Batch-Jobs gleichzeitig; weitere warten als queued.
  • Ist der Job fertig, wird der Webhook mit api.batch.completed aufgerufen; requestId ist die jobId. Mit webhookResult=true enthält result die komplette synchrone Antwort als JSON (bis 10 MB).
  • Der status im Payload folgt dem HTTP-Ergebnis: Ein print_failed-Job kommt als "status": "succeeded" mit summary.jobStatus: "print_failed" und summary.printError an. Maßgeblich ist summary.jobStatus.
  • Ohne webhookId die statusUrl abfragen. Renders werden am Ende gezählt, und nur, wenn der Job nicht fehlgeschlagen ist.
  • Ein Server-Neustart bricht laufende Jobs ab: failed, The job was cancelled (server restart).
StatusBedeutung
queuedAngenommen, wartet auf einen freien Platz.
runningAusgabe und Pickliste werden erzeugt, danach wird gedruckt.
succeededFertig; alle Blöcke wurden vom Drucker angenommen (falls einer angegeben war).
print_failedAusgabe und Pickliste sind fertig, aber ein Druckblock ist fehlgeschlagen (print.error).
failedRendern fehlgeschlagen oder Job abgebrochen (error).
GrenzeWert
Datensätze je Job10.000 (PDF-Ausgabe 5.000, Pickliste 5.000)
Request-Body32 MB
Druckblock100 Etiketten
Parallele Jobs2 je Server, weitere warten
Gespeicherte Ausgabe / Aufbewahrung20 MB / 1 Stunde

Komplettbeispiel: asynchroner Job mit Druck auf rp:12

1. Druckziel ermitteln:

curl -u sk_zplcloud_…: https://api.zplcloud.com/v1/company/printers

{ "scope": "company", "company": "Beispiel GmbH", "count": 3,
  "printers": [ { "target": "rp:12", "type": "remote", "id": 12, "name": "Packtisch 1", "online": true, … }, … ] }

2. Job mit Webhook 12 starten (GET /v1/webhooks listet die IDs; der Key-Besitzer braucht den Pro-Tarif):

curl -X POST "https://api.zplcloud.com/v1/batch/design/shipping-label.42?webhookId=12" \
  -H "X-API-Key: sk_zplcloud_…" -H "Content-Type: application/json" \
  -d '{
    "records": [
      { "auftrag": "SO-5001", "sku": "A-1001", "platz": "R04-B2", "menge": 2 },
      { "auftrag": "SO-5001", "sku": "A-1002", "platz": "R11-A1", "menge": 1 }
    ],
    "output": "none",
    "printer": "rp:12",
    "pickList": { "title": "Welle 14", "columns": ["auftrag", "sku", "platz", "menge"], "groupBy": "auftrag", "sortBy": "platz" },
    "async": true
  }'

3. Der Aufruf antwortet sofort mit 202 und der jobId (siehe oben). 4. Hat der letzte Block den Drucker erreicht, erhält die Webhook-URL einen POST mit den Headern X-ZplCloud-Event: api.batch.completed, X-ZplCloud-Delivery, X-ZplCloud-Timestamp und X-ZplCloud-Signature:

{
  "event": "api.batch.completed",
  "timestamp": "2026-09-11T10:15:07Z",
  "requestId": "3f0c9a7e-5b1d-4c2e-9a41-7d0e6b2f8c13",
  "operation": "POST /v1/batch/design/{designId}",
  "status": "succeeded",
  "httpStatus": 200,
  "durationMs": 5120,
  "renders": 2,
  "summary": {
    "jobId": "3f0c9a7e-5b1d-4c2e-9a41-7d0e6b2f8c13",
    "jobStatus": "succeeded",
    "design": "shipping-label.42",
    "labels": 2,
    "output": "none",
    "outputBytes": null,
    "printer": "rp:12",
    "printedLabels": 2,
    "printError": null,
    "error": null
  },
  "error": null,
  "resultIncluded": false
}

5. Die Pickliste innerhalb der Stunde abholen: GET /v1/batch/jobs/3f0c9a7e-…/picklist.

Job-Status und Downloads

RouteAntwortWebhook-Event
GET /v1/batch/jobs/{jobId}Status als JSONapi.batch.status
GET /v1/batch/jobs/{jobId}/outputZPL (application/x-zpl) oder PDF, bis 20 MBapi.batch.output
GET /v1/batch/jobs/{jobId}/picklistPickliste als PDFapi.batch.picklist
curl -u sk_zplcloud_…: https://api.zplcloud.com/v1/batch/jobs/3f0c9a7e-5b1d-4c2e-9a41-7d0e6b2f8c13

{
  "jobId": "3f0c9a7e-5b1d-4c2e-9a41-7d0e6b2f8c13",
  "status": "running",
  "design": "shipping-label.42",
  "labels": 2500,
  "output": "zpl",
  "outputBytes": 912340,
  "pickList": false,
  "createdUtc": "2026-09-11T10:15:02Z",
  "startedUtc": "2026-09-11T10:15:02Z",
  "finishedUtc": null,
  "durationMs": null,
  "error": null,
  "print": { "printer": "wl:5", "type": "weblink", "name": "Rampe 3", "chunks": 25, "chunkSize": 100, "sentChunks": 9, "sentLabels": 900, "error": null },
  "outputUrl": "/v1/batch/jobs/3f0c9a7e-5b1d-4c2e-9a41-7d0e6b2f8c13/output",
  "pickListUrl": null,
  "expiresUtc": "2026-09-11T11:15:02Z"
}
  • Jobs liegen 1 Stunde im Speicher (expiresUtc) des Servers, der sie angenommen hat. Danach oder auf einer anderen Server-Instanz: 404 Batch job not found. Jobs are kept for 1 hour on the server that accepted them.
  • Einen Job sieht nur dieselbe Firma (Keys ohne Firma: dieselbe E-Mail).
  • /output antwortet mit 404, solange der Job läuft, bei output: none und bei Ausgaben über 20 MB; /picklist mit 404, solange er läuft oder ohne pickList.
  • Status und Downloads zählen keine Renders und werden nicht auf den Tarif geprüft.

Kontingent und Render-Zählung

EndpunktGeprüft (429)Gezählte Renders
POST /v1/zpl/render/design/{designId}jaeiner je Datensatz (mindestens 1)
POST /v1/pdf/render/design/{designId}jaeiner je Seite (Datensätze, mindestens 1)
POST /v1/png/render/design/{designId}ja1
POST /v1/batch/design/{designId}ja, Anzahl Datensätzeeiner je Datensatz, auch bei print_failed
POST /v1/enrich/zplnein, nie blockierteiner je Etikett (mindestens 1)
GET /v1/batch/jobs/…nein0

Batch-Jobs und Label-Anreicherung setzen zusätzlich den Pro-Tarif voraus (403, siehe oben). Fehlgeschlagene Aufrufe (HTTP 400 und höher) zählen nichts. Ist das monatliche Label-Kontingent verbraucht, antworten die geprüften Endpunkte, bevor gearbeitet wird:

HTTP/1.1 429 Too Many Requests

{
  "error": "Render limit reached (9900/10000 labels this month, this request needs 250).",
  "hint": "GET /v1/quota shows your current label quota. Upgrade your plan or buy a render top-up under Billing in the platform. The ZPL tools under /v1/tools are not limited.",
  "limit": 10000,
  "used": 9900,
  "requested": 250,
  "requestId": "3f0c9a7e-5b1d-4c2e-9a41-7d0e6b2f8c13"
}

Tarifgrenzen, Top-ups, gepufferte Zählung und GET /v1/quota: API-Übersicht → Kontingent. Auch die ZPL-Tools-API wird nie blockiert.