Printing labels and documents

Updated Nov 8, 2026
DataMagik Automate

Printing labels and documents

Send ZPL labels and PDF or HTML documents to your printers from scripts, automations and the API, at the right size on every printer.

How a print job runs

Every print becomes a job in the print queue. The site's connector picks it up and sends it to the printer.

StatusDescription
PendingQueued, waiting for a connector to pick it up.
ProcessingThe connector is sending it to the printer.
HeldThe printer reported a fault, such as paper out. The job prints by itself when the printer is ready. See Printer status and held jobs.
CompletedPrinted.
FailedAn error occurred. It may retry automatically.
CancelledCancelled by a user.

Priority, retries and failover

  • Higher-priority jobs are sent first.
  • Jobs for one printer print in the order they were queued, including after being held.
  • If a connector fails, a network printer's job is sent through another connector at the same site. A USB printer's jobs only go to the computer it is plugged into.
  • Failed jobs retry with a short backoff (5s, 10s, 15s) up to the maximum attempt count.

Jobs that are pending, held or failed can be cancelled from Print Jobs.

Formats

FormatDescription
zplRaw ZPL for Zebra printers.
pdfA PDF document.
pdf_base64A base64-encoded PDF.
htmlAn HTML document, converted to PDF for printing.

ZPL labels

^XA
^FO50,50^A0N,50,50^FDHello World^FS
^FO50,120^BY3^BCN,100,Y,N,N^FD12345678^FS
^XZ

Label templates

Use a ZPL Label template in the Document Designer for labels with data. Placeholders such as {{.partNumber}} are replaced with your data at print time. You can write the template's ZPL by hand or design it with the Visual ZPL label designer.

In a hand-written template, data that could contain ^, ~ or _ (for example a value from your ERP or a scan) should be written with zplfh in a field that starts with ^FH_, so it always prints as text:

^FO50,50^A0N,40,40^FH_^FD{{zplfh .partNumber}}^FS

The visual designer does this for every field automatically.

Printing on printers with different DPI

A ZPL label is drawn in printer dots, so a label written for a 203 dpi printer prints at two-thirds of its size on a 300 dpi printer. DataMagik scales ZPL labels to the printer's DPI as they print, so they come out the same size everywhere:

  • Labels designed visually are always scaled. The label records the density it was designed at.
  • Hand-written label templates are scaled when Scale to the printer's DPI is turned on in the template's ZPL Label Settings. The label's print density setting says what density the ZPL was written for. It is off by default, so existing labels print exactly as before.
  • Raw ZPL from a script or the API is scaled when you say what density it was written for: sourceDpmm in scripts or source_dpmm in the API.

A scaled job's message says what was done, for example "Label scaled from 8 to 12 dots/mm for this 300 dpi printer." Scaling needs the printer's DPI to be right. Discovery and Identify read it from the printer, and a printer whose DPI does not match shows a DPI mismatch warning (see Printers). Barcode bars are whole printer dots, so a barcode can be very slightly wider or narrower after scaling. Test prints from the Plex Label Designer are not scaled.

ZPL preview

Preview ZPL output in the template editor before printing. DataMagik renders the ZPL as an image, matched against a real Zebra printer, so you can check the layout. Notes about commands that affect the printed label are listed under the preview.

Printing from scripts

The Script Engine's connectors object prints and reads printers:

function main(context) {
  // List available printers, or get one by name
  const printers = connectors.getPrinters();
  const printer = connectors.getPrinter("Line1-Zebra");

  // Check the printer can print before sending a batch
  const st = connectors.getPrinterStatus("Line1-Zebra");
  if (st.success && st.ready === false) {
    return { success: false, message: "Line1-Zebra cannot print: " + st.problems.join(", ") };
  }

  // Send raw ZPL
  connectors.printLabel("Line1-Zebra", "^XA^FO50,50^A0N,50,50^FDHello^FS^XZ");

  // Send raw ZPL written for a 203 dpi (8 dots/mm) printer;
  // it is scaled to Line1-Zebra's DPI
  connectors.printLabel("Line1-Zebra", "^XA^FO50,50^A0N,50,50^FDHello^FS^XZ", { sourceDpmm: 8 });

  // Print using a template with data
  connectors.printFromTemplate("Shipping-Printer", "ShippingLabel", {
    orderNumber: context.order_id,
    customerName: context.customer
  });

  // Batch print multiple labels
  connectors.printBatch("Line1-Zebra", "PartLabel",
    context.parts.map(p => ({ partNumber: p.number, serialNumber: p.serial }))
  );

  // Check printhead wear and maintenance
  const h = connectors.getPrinterHealth("Line1-Zebra");
  if (h.success && h.health && h.health.maintenanceDue.length) {
    console.log("Line1-Zebra needs:", h.health.maintenanceDue.join(", "));
  }

  return { success: true };
}
FunctionWhat it does
getPrinters(), getPrinter(name)List your printers, or get one by name (null if there is none).
printLabel(printer, zpl, options)Send raw ZPL. sourceDpmm is the density it was written for, in dots per millimeter: 6 (152 dpi), 8 (203 dpi), 12 (300 dpi) or 24 (600 dpi). Without it, the ZPL is sent as written.
printFromTemplate(printer, template, data), printBatch(printer, template, rows)Print one label, or one per row, from a label template. Template labels are scaled as described above.
getPrinterStatus(printer)The printer's last status: ready (true, false, or null for a printer that does not report one), online, problems, warnings and checkedAt.
getPrinterHealth(printer)The printer's last health report in health, or null if it has not reported: labelsPrinted, printheadCm, printheadRatedCm, printheadWornPct, sinceCleanedCm, cleanDue, replacePrinthead, calibrationNeeded, labelsNearlyOut, maintenanceDue, darkness, speed and collectedAt.

A script can only reach its own company's printers.

Printing from automations and the API

  • Automations: add a print action in DataMagik Automate.
  • API: POST /api/print-job/{printerId} with the print data. For ZPL, add "source_dpmm" (6, 8, 12 or 24) to scale the label from that density to the printer's DPI. A request_id makes the call safe to repeat: sending the same request ID again returns the first job instead of printing twice. The printer must belong to your company.

If the printer already has held jobs, the response says the new job is held behind them, and why. A job sent to a printer that turns out not to be ready is held a moment later; its status shows in Print Jobs.

Related pages

Was this page helpful?