ZPL label printing API

Zebra label printers take ZPL, not PDFs. PrintSocket sends your ZPL through untouched, and gives you the two things a shipping label actually needs: never print it twice, and know whether it came out.

ZPL goes as raw content

curl https://api.printsocket.com/v1/jobs \
  -H "Authorization: Bearer sk_live_..." \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: shipment-99417" \
  -d '{
    "printer_id": "prn_8f2k1",
    "title": "Label for shipment 99417",
    "content": { "format": "raw", "url": "https://example.com/labels/99417.zpl" },
    "queue_if_offline": false
  }'

url is convenient when your carrier already hands you a hosted label. base64 works if you have the bytes. If the same label goes to several printers, upload it once with POST /v1/documents and reference it by document_id.

Never print a label twice

A duplicate shipping label is not a cosmetic bug. It is a second parcel with the same tracking number, or a carrier charge you did not expect. The dangerous moment is a network retry: your request succeeded, the response did not reach you, and your code tries again.

Send an Idempotency-Key header on the create call and that stops being a risk. A replay of the same key within 24 hours returns the stored original response, the same status and the same body. There is no conflict to handle and nothing to reconcile: retry with the same key until you get an answer.

Use something from your own domain as the key, not a random value. A shipment id is ideal, because it is the same on the retry.

Know whether the label actually printed

Some drivers can confirm that a page physically came out. Some can only tell you the spooler finished with it. Rather than presenting both as the same thing, a successful job carries completion_confidence:

If marking an order shipped depends on a label existing on the bench, check that field rather than status alone. This is the failure a label workflow actually hits, and it is invisible in an API that only reports success.

queue_if_offline: false is the other half. A label queued against a printer that is switched off is a parcel that misses the courier. With that flag the call is rejected immediately with printer_offline, and you can put it in front of a human while there is still time.

What this does not do

  • It does not generate ZPL. No label designer, no template engine, no barcode rendering. Your carrier's API or your own library produces the ZPL; we deliver it.
  • It does not validate the ZPL. Raw content is passed through unchanged, so a malformed label prints as a malformed label rather than returning an error.
  • It does not convert a PDF label to ZPL, or the reverse. Send the format the printer takes.
  • It does not read printer-specific status beyond what the platform reports: no ribbon level, no media-out sensor.

Weighing and labelling together

If the scale on the packing bench is a USB scale on the same machine, its weight is readable over the same API: see read a USB shipping scale over HTTP. Read the weight, buy the postage, print the label, in one server-side flow.

Start free Job reference