Sign In
Products
ZPL ViewerBarcode GeneratorImage → ZPLZPL cheat sheetLabel DesignerTemplate Gallery
Developers
API QuickstartAPI ReferenceMCP ServerBulk GenerationWebhooksSDKs & ExamplesLimitsDirectPrint agent NewGitHub ActionVS Code extensionOn-Premise
Solutions
Logistics & ShippingE-CommerceERP & WMSManufacturingRetailHealthcare & LaboratoryAll solutions
Tools
ZPL Diagnostics HubZPL DebuggerSize & DPI AnalyzerDPI ConverterBarcode fit calculatorShipping Label AnalyzerFont InspectorOrientation DebuggerCalibration AssistantPrinter Compatibility CheckerBarcode Readability CheckerPrinter Language DetectorThermal Printer Test PackZPL ToolsEPL ToolsTSPL ToolsCPCL ToolsPrinter Language ConverterAll ToolsGuidesPricing
Language
EnglishTürkçeDeutsch
Home›Guides›UPS ZPL labels: request, preview and fix

UPS ZPL labels: request, preview and fix

Published:

Result

The UPS Shipping API returns a thermal label as base64 ZPL, one per package, when the request asks for it. Compared with FedEx the request is smaller — an image format code and a stock size — and there is no resolution field at all, which moves one important question (which density are the dots written for?) from the request to the file. This page lists the fields, the path to the label in the response and the checks to run before printing. The rules that apply to every carrier label are in working with carrier ZPL labels; the FedEx counterpart is FedEx ZPL labels.

Field names and values below were read from the UPS Shipping API OpenAPI specification that UPS publishes on GitHub, on 2026-09-14. They change between API versions; confirm them against the current specification before you rely on them. Labelixa is not affiliated with UPS — this is a workflow description, not an integration.

The request fields that shape the ZPL

The call is POST /shipments/{version}/ship — against wwwcie.ups.com for the Customer Integration Environment and onlinetools.ups.com for production. The label is controlled by ShipmentRequest.Shipment.LabelSpecification:

"LabelSpecification": {
  "LabelImageFormat": { "Code": "ZPL" },
  "LabelStockSize": { "Height": "6", "Width": "4" }
}

There is no resolution field. The specification does not say which density the ZPL is written for, so do not assume one: read it from the file (below).

Where the label is in the response

The path is ShipmentResponse.ShipmentResults.PackageResults[] — one entry per package, each with its TrackingNumber and a ShippingLabel object whose GraphicImage is the base64 label and whose ImageFormat.Code confirms the format actually returned. The specification notes that from version v2403 package results are always an array, while older versions return a bare object when there is a single package — a classic cause of "works with one parcel, breaks with two".

jq -r '.ShipmentResponse.ShipmentResults.PackageResults[0].ShippingLabel.GraphicImage'    response.json | base64 -d > label.zpl
head -c 40 label.zpl          # ^XA expected

Two more fields matter for thermal output. InternationalSignatureGraphicImage is returned for non-US shipments in EPL2, ZPL and SPL — one image per shipment, in the first package result — and is a second label to print, not an attachment to ignore. HTMLImage is only returned for GIF and PNG, so its absence with ZPL is normal. The specification also notes that for multi-piece COD shipments the first package's label is always GIF, whatever format was requested — check ImageFormat.Code per package instead of assuming.

Find the density, then preview

Because the request carries no resolution, the only reliable source is the file. The size and DPI analyzer reads the declared width and length out of the ZPL and reports the density that makes them a 4×6 (or 4×8) label; if the file does not declare them, it says so rather than guessing. Then preview at that density and stock:

curl -X POST "https://api.labelixa.com/v1/printers/8dpmm/labels/4x6/0"      --data-binary @label.zpl --output label.png

Keep the decoded bytes exactly as they are. If you requested a character set other than the default, the label bytes follow that encoding; decoding the file as UTF-8 and re-encoding it can replace or reject every accented or Turkish character, and the preview will show precisely that damage. Feed the raw bytes to the preview and, unchanged, to the printer.

Checks worth running before printing

curl -X POST "https://api.labelixa.com/v1/diagnostics?dpmm=8&w=4&h=6"      --data-binary @label.zpl

The same gate runs from a shell or CI as npx labelixa validate label.zpl, which exits non-zero on error-level findings.

Failures that look like UPS problems but are not

Frequently asked questions

How do I request a ZPL label from the UPS Shipping API?

Set LabelSpecification.LabelImageFormat.Code to ZPL and give LabelStockSize with Width 4 and Height 6 (or 8) in whole inches. The specification notes that the image only scales up to 4×6 even when 4×8 is requested.

Where is the ZPL in the UPS response?

ShipmentResponse.ShipmentResults.PackageResults[].ShippingLabel.GraphicImage, base64-encoded, one entry per package; ImageFormat.Code confirms the format. From v2403 the package results are always an array.

Does the UPS request say which dpi the ZPL is written for?

No — the specification has no resolution field. Read the density from the file with the size and DPI analyzer, then preview and print at that density.

Related guides

How to Print ZPL Labels from Excel or CSV Data

Turn a spreadsheet into hundreds of ZPL labels: template variables, CSV column mapping, batch generation and the honest limits of each step.

FedEx ZPL labels: request, preview and fix

The Ship API fields that decide the ZPL (image type, stock, 203 or 300 dpi), where the label sits in the response and the checks to run before printing.

ERP label printing with ZPL

Where ERP label pipelines break, and the validation gate that stops a bad template before it reaches a warehouse printer.

Working with carrier ZPL labels

Carrier APIs hand back ZPL, not a picture. How to decode it, check it before it burns media, and what you must not change.

Try your own ZPL code →