Menu
Full ZPL II Manual

ZPL Reference: Programming Language, Fonts & Format

The complete Zebra Programming Language manual — anatomy, commands, fonts, barcodes and copy-paste examples for shipping, retail and logistics labels.

TL;DR

ZPL (Zebra Programming Language) is the de-facto standard for thermal label printing since the 1980s. Every label starts with ^XA and ends with ^XZ. Commands prefixed with ^ go inside the format; ~ commands configure the printer. Coordinates use dots (203 dpi = 8 dots/mm, 300 dpi = 12 dots/mm). Built-in fonts 0 and A–H cover most cases — Font 0 is fully scalable. The most-used barcodes are ^BC (Code 128) for shipping, ^BQ (QR) for tracking and ^BE (EAN-13) for retail. Set the field origin with ^FO, write data with ^FD, and close every field with ^FS. Use ^CI28 to enable UTF-8 for international characters.

Try our free ZPL tools right now

Free, no signup required — Instant results

What is ZPL (Zebra Programming Language)?

ZPL stands for Zebra Programming Language, a page-description language created by Zebra Technologies in the 1980s to drive thermal label printers. It is the industry standard for shipping labels, warehouse identification, retail price tags and pharmaceutical packaging because it is compact, deterministic and supported by every Zebra printer model (ZD, ZT, ZE, ZQ, GK, GX, ZM and the older 105SL/110XiIII series).

A ZPL program is a plain-text stream of commands the printer interprets line by line. Each command starts with a control character — ^ (caret) for format commands or ~ (tilde) for setup commands — followed by a two-character code and optional comma-separated parameters. ZPL II, the current revision, adds graphics, downloadable fonts, fixed and serialised fields, multi-format labels and bidirectional communication. The same code prints the same output on every Zebra printer, regardless of model, which is what makes ZPL the lingua franca of label production worldwide.

ZPL Format Anatomy

Every printable label is a self-contained block called a format. The format opens with ^XA, contains one or more fields, and closes with ^XZ. Inside the block, the order of commands matters: the printer applies them sequentially as state. A field — text, barcode or graphic — is defined by a position command (^FO or ^FT), a content command (^A, ^BC, ^GB, etc.) and a separator (^FS). Anything outside ^XA..^XZ is treated as printer configuration and executed immediately.

  • Every label format begins with ^XA and ends with ^XZ. Anything outside is configuration, not printable content.
  • Commands starting with ^ are format commands and live inside the ^XA..^XZ block.
  • Commands starting with ~ are control commands that configure the printer and can be sent standalone (e.g., ~JR resets the printer).
  • Each printable field must close with ^FS (field separator) — forgetting ^FS is the most common cause of garbled output.
  • Parameters are comma-separated and positional. Missing parameters fall back to the printer default or the last set value.
  • Use ^CI28 inside the format to enable UTF-8 for non-ASCII characters (accents, ñ, ç, é, ü, Chinese, Cyrillic).
  • Commands are case-sensitive. ^FO and ^fo are not the same — always uppercase.
  • Whitespace and line breaks between commands are ignored, so you can format your ZPL for readability.
^XA                            ; Start format
^CI28                          ; Enable UTF-8
^CF0,40                        ; Default font 0, size 40
^FO50,50                       ; Position X=50, Y=50
^FDHello ZPL World^FS          ; Print text, close field
^FO50,120^BY3                  ; New field + barcode width
^BCN,100,Y,N,N                 ; Code 128, 100 dots tall
^FD1234567890^FS               ; Barcode data, close field
^XZ                            ; End format → label prints

Coordinate System & DPI

ZPL positions every element using dot coordinates measured from the top-left corner of the label. The conversion between millimetres or inches and dots depends on the printer's print density (DPI). Knowing the exact dot count of your label is essential for pixel-perfect alignment, especially for pre-printed forms and shipping carriers like FedEx, UPS or Mercado Libre that enforce strict label dimensions.

  • 203 dpi printers: 8 dots per mm (203 dots per inch). A 4×6 inch label is 812×1218 dots.
  • 300 dpi printers: 12 dots per mm (300 dots per inch). The same 4×6 label is 1200×1800 dots.
  • 600 dpi printers: 24 dots per mm. Used mostly for ultra-fine retail price tags and jewellery labels.
  • ^FO x,y places a field by the top-left corner of its bounding box.
  • ^FT x,y places a field by the text baseline — useful when mixing font sizes.
  • Y grows downward. ^FO0,0 is the top-left corner; ^FO0,1218 is the bottom of a 6-inch label at 203 dpi.
  • Always test at 100% scale; rendering tools may rescale the preview but the printer applies dot coordinates literally.

ZPL Programming Guide: From Hello World to a Shipping Label

Three progressively richer examples. Paste each one into the ZPL viewer to see exactly what comes out of the printer.

1

Step 1 — Hello World

The minimal valid ZPL program. Opens a format, prints a single text field at position (50,50) using the default scalable Font 0 at 40 dots tall, and closes the format.

^XA
^CF0,40
^FO50,50^FDHello ZPL^FS
^XZ
2

Step 2 — Text + Code 128 barcode

Adds a Code 128 barcode (^BC), the standard for shipping labels. ^BY sets the module width before declaring the barcode. The barcode renders the human-readable digits below itself thanks to the Y flag.

^XA
^CF0,40
^FO50,50^FDOrder #1042^FS
^FO50,120^BY3
^BCN,100,Y,N,N
^FD1234567890^FS
^XZ
3

Step 3 — Complete shipping label

Combines variable text, a multi-line address block, a QR code and a Code 128 tracking barcode — the structure of a real e-commerce shipping label.

^XA
^CI28
^CF0,32
^FO40,40^FDShip To:^FS
^FO40,90^FB540,4,0,L,0^FDJane Doe\&123 Main St\&Brooklyn, NY 11201\&United States^FS
^FO40,260^FDOrder #A-7782^FS
^FO40,310^BY3^BCN,90,Y,N,N^FD1Z999AA10123456784^FS
^FO450,260^BQN,2,5^FDQA,https://example.com/track/A-7782^FS
^XZ

ZPL Commands Reference

The most-used ZPL II commands grouped by purpose. For every command we list a short description, a working example you can paste into a viewer, and the parameter meaning.

Format & control

CommandDescriptionExampleParameters
^XAStart of label format. Required at the beginning of every printable label.^XA ... ^XZNone
^XZEnd of label format. Sends the label to the print queue.^XA^FO50,50^FDHi^FS^XZNone
^FSField separator. Closes the current field. Mandatory after every printable element.^FO50,50^FDText^FSNone
^CIChange international character set. ^CI28 enables UTF-8 for accents and non-Latin scripts.^CI2828 = UTF-8, 13 = Latin-1
^CFDefault font, height and width for the entire label. Saves repeating ^A per field.^CF0,30,30font,height,width
^LHLabel home — shifts the origin (0,0) of all coordinates.^LH30,30x,y in dots
^PQPrint quantity. Issues the same label N times after ^XZ.^PQ5,0,0,Nqty,pause,replicate,override
~JRPrinter reset. Sent outside a format; the printer reboots.~JRNone

Positioning & text

CommandDescriptionExampleParameters
^FOField origin — places the next field by its top-left corner.^FO50,80x,y in dots
^FTField typeset — places the next field by the text baseline. Best for mixed font sizes.^FT50,80x,y in dots
^AFont selection for the next field. Overrides ^CF locally.^A0N,40,40font,orientation,height,width
^FDField data. The literal text or numeric value to print.^FDOrder #42^FStext (up to 3072 chars)
^FBField block — multi-line text with word wrap and alignment.^FB400,3,0,L,0^FD…^FSwidth,maxLines,lineGap,alignment,indent
^FNField number — template placeholder filled later with ^FN data.^FN1^FS1–999
^SNSerial number — auto-increments across copies in a print job.^SN001,1,Ystart,increment,zero-pad

Barcodes

CommandDescriptionExampleParameters
^BYDefault barcode module width and ratio. Must precede the barcode command.^BY3,3,100moduleWidth,ratio,height
^BCCode 128 barcode — the standard for shipping/logistics.^BCN,100,Y,N,Norientation,height,line-below,line-above,checkDigit
^BQQR Code — URLs, JSON, tracking IDs. Up to 7089 numeric chars.^BQN,2,5orientation,model,magnification
^BEEAN-13 — global retail product code (13 digits).^BEN,100,Y,Norientation,height,line-below,line-above
^BUUPC-A — North American retail product code (12 digits).^BUN,100,Y,Norientation,height,line-below,line-above
^BXData Matrix — high-density 2D code for small items and pharma.^BXN,200,200orientation,height,quality
^B0Aztec — 2D code used in transport tickets and SmartCard tags.^B0N,7,N,0,Norientation,magnification(1-10),ECI(Y/N),errorControl(0-300),menu(Y/N)
^B7PDF417 — stacked 2D barcode used on driver licences and shipping.^B7N,8,5,10,30,Norientation,rowHeight,security(0-8),cols(1-30),rows(3-90),truncate(Y/N)

Graphics

CommandDescriptionExampleParameters
^GBGraphic box — rectangles, borders, separators.^GB300,2,2,B^FSwidth,height,thickness,colour
^GCGraphic circle.^GC100,3,B^FSdiameter,thickness,colour
^GDGraphic diagonal line.^GD200,200,2,B,R^FSwidth,height,thickness,colour,orientation
^GFGraphic field — embedded bitmap (ASCII or compressed).^GFA,1024,1024,32,…format,bytes,total,bytesPerRow,data
^FRField reverse-print — inverts black/white inside the field.^FO50,50^FR^GB100,30,30^FSNone

ZPL Fonts: Built-in & Scalable

Zebra printers ship with a fixed set of bitmap fonts (A through H) plus one fully scalable font (0). Font 0 is the only one that can be set to any height and width via ^CF or ^A; the bitmap fonts have fixed sizes you can stretch but not redraw cleanly. The ^A command selects font + size for a single field; ^CF sets the default for the whole label.

CodeNameSizeNotes
0Font 0 (CG Triumvirate)Scalable, any height/widthDefault scalable font. Best for prices, titles, dynamic-size content.
AFont A9 × 5 dots (fixed)Smallest bitmap. Ideal for fine print and dense labels.
BFont B11 × 7 dots (fixed)Slightly bigger than A. Common for line items.
C / DFont C, D18 × 10 dots (fixed)Mid-size bitmaps used for variable fields.
EFont E28 × 15 dots (OCR-B)Optical-character-recognition friendly.
FFont F26 × 13 dotsGeneral-purpose larger bitmap.
GFont G60 × 40 dotsDisplay-size, used for headers.
HFont H (OCR-A)21 × 13 dotsOCR-A standard, designed for machine reading.
P–VSoft fonts P–VVariableLetters P, Q, R, S, T, U, V — bitmap legacy fonts on older firmware.
^XA
^CF0,50,50                ; Default Font 0 at 50x50
^FO50,50^FDPrice: $19.99^FS
^FO50,120^ABN,30,15      ; Font B explicit
^FDSKU: ABC-001^FS
^FO50,170^A0N,80,80      ; Big Font 0 inline
^FDSALE^FS
^XZ

Barcodes in ZPL

ZPL natively renders every common 1D and 2D symbology. Always declare ^BY (module width and ratio) before the barcode command to keep scanners happy.

Code 128

^BC

Shipping, logistics, parcel tracking. Numbers + letters. Industry default for FedEx, UPS, USPS.

^FO50,50^BY3^BCN,100,Y,N,N^FD1234567890^FS

QR Code

^BQ

URLs, JSON payloads, tracking IDs. Up to 7089 numeric chars. Wide reader support.

^FO50,50^BQN,2,6^FDQA,https://zplpdf.com^FS

EAN-13

^BE

Retail products worldwide. Exactly 12 digits — 13th is the auto-checksum.

^FO50,50^BY2^BEN,100,Y,N^FD750123456789^FS

UPC-A

^BU

North American retail. 11 digits + auto checksum.

^FO50,50^BY2^BUN,100,Y,N^FD01234567890^FS

Data Matrix

^BX

Pharmaceutical UDI, electronics, very small items. Reads at any angle.

^FO50,50^BXN,200,200^FDPharmaCode-42^FS

Aztec

^B0

Transport tickets, boarding passes. Compact, no quiet-zone required.

^FO50,50^B0N,7,N,0,N^FDBOARDING-A14^FS

PDF417

^B7

Driver licences, ID cards, shipping. Stacked 2D, holds ~1.1 KB.

^FO50,50^B7N,8,5,10,30,N^FDLastName/FirstName/DOB^FS

Code 39

^B3

Internal inventory, asset tags. Alphanumeric but lower density than 128.

^FO50,50^BY3^B3N,N,100,Y,N^FDASSET-001^FS

Complete ZPL Examples (Copy & Paste)

Working programs ready to drop into the ZPLPDF viewer. Each example is a full ^XA..^XZ block tested at 203 dpi on a 4×6 inch label.

Shipping label — e-commerce parcel

Sender, receiver, Code 128 tracking barcode and QR for tracking URL.

^XA
^CI28
^PW812
^LL1218
^CF0,28
^FO40,40^FDFROM:^FS
^FO40,80^FB400,3,0,L,0^FDZPLPDF Warehouse\&500 Logistics Ave\&Miami, FL 33101^FS
^FO40,210^FDTO:^FS
^FO40,250^A0N,38,38^FB500,4,0,L,0^FDJane Doe\&123 Main St, Apt 4B\&Brooklyn, NY 11201\&United States^FS
^FO40,520^GB720,2,2,B^FS
^FO40,540^FDTracking:^FS
^FO40,580^BY3^BCN,110,Y,N,N^FD1Z999AA10123456784^FS
^FO520,540^BQN,2,6^FDQA,https://zplpdf.com/track/1Z999AA10123456784^FS
^FO40,820^FDOrder #A-7782^FS
^FO40,860^FD2026-05-21^FS
^XZ

Retail price tag with EAN-13

Product name, SKU, EAN-13 barcode and price highlighted with a reverse-print box.

^XA
^CI28
^CF0,40
^FO40,30^A0N,50,50^FDOrganic Coffee 250g^FS
^FO40,100^FDSKU: COF-ORG-250^FS
^FO40,150^BY2^BEN,100,Y,N^FD750123456789^FS
^FO40,290^GB300,80,80,B^FS
^FO50,300^FR^A0N,60,60^FD$ 12.99^FS
^XZ

Pharmacy label with Data Matrix (GS1)

Drug name, batch and expiry, with a Data Matrix carrying GS1 application identifiers — common in pharma supply chains.

^XA
^CI28
^CF0,32
^FO40,40^A0N,44,44^FDAcetaminophen 500 mg^FS
^FO40,100^FDBatch: B25C-0481^FS
^FO40,150^FDExp: 2027-09^FS
^FO40,200^BXN,200,200^FD>;(01)07640123456789(17)270930(10)B25C-0481^FS
^XZ

Serialised batch — 50 unique labels

^PQ50 prints 50 copies; ^SN auto-increments the serial number on each one.

^XA
^CF0,40
^FO50,50^FDBatch SN^FS
^FO50,120^A0N,80,80^SN0001,1,Y^FS
^PQ50,0,0,N
^XZ

Common ZPL Errors & How to Fix Them

Label prints blank or skips paper.

Missing ^XZ at the end, or extra characters between ^XA and ^XZ.

Make sure the format starts with ^XA, ends with ^XZ, and that no stray bytes break the stream.

Text shows ? instead of accents (á, é, ñ).

Default encoding is CP-850, which doesn't carry UTF-8 bytes.

Add ^CI28 right after ^XA to switch the printer to UTF-8.

Barcode prints but scanner can't read it.

Module width too small or ratio out of spec.

Set ^BY3,3,100 before the barcode and verify quiet zones around it.

Field appears in the wrong position.

Mixing ^FO and ^FT — they use different reference points.

Pick one: ^FO (top-left of bounding box) or ^FT (text baseline). Don't switch mid-label.

Multi-line text overflows the label edge.

^FD wraps only when ^FB is used.

Wrap multi-line text in ^FBwidth,maxLines,lineGap,alignment,indent before ^FD.

Image (^GF) prints corrupted.

Byte count or bytes-per-row don't match the data length.

Re-encode the image with a known tool — bytesPerRow must equal ceil(width/8).

ZPL Reference — Frequently Asked Questions

What is ZPL used for?

ZPL is the programming language Zebra thermal printers interpret to produce labels. It is the de-facto standard for shipping labels (FedEx, UPS, USPS), retail price tags, pharmaceutical UDI labels, warehouse identification and any high-volume label printing scenario.

Is ZPL the same as Zebra Programming Language?

Yes. ZPL is an acronym for Zebra Programming Language. The current revision is ZPL II, used by every modern Zebra printer.

How do I learn ZPL fast?

Start with the three-step guide on this page (Hello World → barcode → shipping label), paste each example into the ZPL viewer to see immediate output, and consult the commands table when you need a new feature. Most production labels use fewer than 15 commands.

Which ZPL command sets the font?

Use ^CF font,height,width to set the default font for the entire label, or ^A font,orientation,height,width before a single ^FD to override it for one field. Font 0 is the only scalable font; A through H are fixed bitmaps.

How do I add a QR code in ZPL?

Use ^BQN,2,magnification before ^FD. The data payload must start with QA, (auto-error-correction, alphanumeric). Example: ^FO50,50^BQN,2,6^FDQA,https://example.com^FS.

How do I print a Code 128 barcode?

Declare module width with ^BY (e.g., ^BY3), then ^BCN,height,Y,N,N for orientation N (normal), human-readable line below = Y. Follow with ^FD<digits>^FS.

What is the difference between ^FO and ^FT?

^FO (Field Origin) positions a field by the top-left corner of its bounding box. ^FT (Field Typeset) positions it by the text baseline. ^FT is useful when mixing font sizes because the baseline stays aligned even when heights change.

How many DPI is my Zebra printer?

Most desktop and industrial Zebra printers ship at 203 dpi (8 dots/mm). Higher-resolution models (ZT411, ZT421, ZD621) come in 300 dpi (12 dots/mm) and a small range at 600 dpi. Multiply mm by 8, 12 or 24 to get the dot count for your model.

Can I test ZPL without a printer?

Yes — paste your ZPL code into our free online ZPL viewer to render an exact preview, validate the syntax with the ZPL validator, or export to PDF for proofreading and sharing.

Is ZPL the same as EPL?

No. EPL (Eltron Programming Language) is the older, simpler precursor that Zebra also supports for legacy compatibility. ZPL is more powerful and is what every modern Zebra printer uses. See our ZPL vs EPL comparison for migration tips.

Test your ZPL right now

Paste any of the examples on this page into our free online ZPL viewer to see exactly what your printer will produce — no signup, no download.