Why international labels won't generate as ZPL (customs forms)
Your domestic flow is clean: request a label, ask for ZPL, stream it to the Zebra, done. Then you ship your first international order and the same carrier API either errors on the ZPL format or silently returns a PDF, and nothing in the docs warned you.
This is not a bug in your integration. It's a rule almost nobody writes down:
Once a shipment needs a customs declaration, most carriers stop offering ZPL and only produce documents.
Why carriers do this
A domestic label is one fixed 4×6 layout, easy to express as ZPL. An international shipment carries a customs declaration (CN22 for small stuff, CP72 and friends for the rest), and a declaration is a document: it lists every item you declared, it needs signature and date blocks, and past a handful of items it spills onto continuation pages. Declare 25 items and the "label" is now a multi-page form with a barcode on page one.
Carrier label systems compose that as a paged document (a PDF) because ZPL has
no concept of "as many pages as the content needs." So the API that cheerfully
returned ^XA...^XZ for Ground Advantage returns application/pdf for the same
address in Canada, and your thermal pipeline breaks the week international
launches.
We keep a real specimen of this in our test corpus: a USPS international label with a 25-item declaration comes back from the carrier as a two-page PDF: label plus customs continuation. It's also the sample loaded on our converter if you want to see one without shipping anything.
The fix: convert the PDF, print every page
Your Zebra doesn't care that the carrier thinks in documents. Convert each PDF page to ZPL at your printer's density and print the pages in order: label first, customs pages after, all on the same stock.
STRIPY_HORSE_API_KEY=""
curl https://api.stripyhorse.io/v1/convert \
-H "X-Api-Key: $STRIPY_HORSE_API_KEY" \
-F file=@international-label.pdf -F preset=4x6 -F dpmm=8
One call, one ZPL block per page, ready to send to port 9100 sequentially. The free converter does the same in the browser, and for volume the batch endpoint streams results per page.
Three things worth getting right:
- Match dpmm to the printer. A 203 dpi printer is 8 dpmm; 300 is 12. Convert at the wrong density and barcodes come out the wrong physical size; how to convert PDF to ZPL covers the math.
- Print all the pages. Customs law cares about the continuation pages even though the scanner only cares about page one. Count the ZPL blocks you get back and print every one.
- Verify the barcode survived rasterization. Conversion is pixel-work; run the output through preflight once per template and you'll know the IMpb still scans before a package rides on it.
If you control the declaration
You can sometimes stay under the continuation-page threshold by consolidating line items (many carriers allow grouping like items). Fewer than the magic number of items often keeps the form to one page, but don't build your pipeline on staying lucky. Build it to convert documents, and page count stops mattering.
Published 2026-08-25 · Ben Faerber, software engineer, five years building warehouse fulfillment and label-printing systems; maintainer of pdf-to-zpl (26,000+ installs powering production label generation).