Before you integrate
These details save debugging time when something does not print on the first try.
GET /status requires X-PrintBridge-Api-Key: <key>. Copy the key from the PrintBridge desktop app. You can rotate it at any time. The npm SDK sends it automatically when you pass apiKey to the constructor.http://127.0.0.1 (localhost is a secure context). If blocked by mixed-content policy, proxy print calls through your own backend using the npm SDK server-side.npm Package
The printbridge package is a zero-dependency TypeScript SDK for the local agent API. Use it server-side in Next.js, Express, Nuxt, or any Node.js runtime.
Install
npm install printbridge
# or
pnpm add printbridge
# or
yarn add printbridgeQuick start
import { PrintBridge } from "printbridge";
const pb = new PrintBridge({ apiKey: process.env.PRINTBRIDGE_API_KEY });
// List printers
const printers = await pb.getPrinters();
// Send a print job
await pb.print({
printer: "Zebra ZT410",
format: "zpl",
content: "^XA^FO50,50^A0N,50,50^FDHello, World^FS^XZ",
});Framework examples
// app/actions/print.ts
"use server";
import { PrintBridge } from "printbridge";
const pb = new PrintBridge({
apiKey: process.env.PRINTBRIDGE_API_KEY,
});
export async function printShippingLabel(zpl: string) {
return await pb.print({
printer: "Zebra ZT410",
format: "zpl",
content: zpl,
});
}Error handling
The SDK throws PrintBridgeError for all known failure modes. Switch on err.code for granular handling.
import { PrintBridge, PrintBridgeError } from "printbridge";
const pb = new PrintBridge({ apiKey: process.env.PRINTBRIDGE_API_KEY });
try {
await pb.print({
printer: "Zebra ZT410",
format: "zpl",
content: "^XA^FO50,50^FDTest^FS^XZ",
});
} catch (err) {
if (err instanceof PrintBridgeError) {
switch (err.code) {
case "AGENT_OFFLINE":
console.error("PrintBridge agent is not running on the target machine");
break;
case "AUTH_FAILED":
console.error("Invalid API key — check PRINTBRIDGE_API_KEY");
break;
case "PRINTER_NOT_FOUND":
console.error("Printer name not found — call pb.getPrinters() to list");
break;
case "PRINT_FAILED":
console.error("Job was dispatched but failed on the printer");
break;
case "TIMEOUT":
console.error("Agent did not respond in time — increase timeout option");
break;
}
// err.statusCode — HTTP status returned by the agent
// err.jobId — job ID if the job was created before failing
console.error(err.statusCode, err.jobId, err.message);
}
}AGENT_OFFLINEDesktop agent is not runningAUTH_FAILEDAPI key is missing or wrongPRINTER_NOT_FOUNDPrinter name not in the listPRINT_FAILEDJob dispatched but printer rejected itTIMEOUTAgent did not respond in timeUNKNOWNUnexpected error — check err.messageSDK API reference
Full constructor and method signatures. All methods return Promises and throw PrintBridgeError on failure.
// Constructor
new PrintBridge({
host?: string; // default: "localhost"
port?: number; // default: 1337
apiKey?: string; // required if auth is enabled
timeout?: number; // ms — default: 5000
})
// Send a print job
pb.print({
printer: string;
content: string;
format: "zpl" | "epl" | "tspl" | "dpl" | "cpcl" | "sbpl"
| "escpos" | "star" | "fgl" | "pcl"
| "pdf" | "html" | "png" | "jpeg";
encoding?: "utf8" | "base64"; // default: "utf8"
copies?: number; // default: 1
jobName?: string;
}): Promise<{ success: boolean; jobId: string; message?: string }>
// List printers
pb.getPrinters(): Promise<Array<{
name: string;
isDefault: boolean;
status: "ready" | "offline" | "error";
healthScore: number;
healthLabel: string;
}>>
// Agent status
pb.getStatus(): Promise<{
online: boolean;
version: string;
agentId: string;
}>
// Job status
pb.getJob(jobId: string): Promise<{
jobId: string;
status: "pending" | "printing" | "complete" | "failed";
printer: string;
createdAt: string;
completedAt?: string;
error?: string;
}>Full changelog and source on npmjs.com/package/printbridge · See also the HTTP API reference for all endpoints including /print-batch, /logs, and the WebSocket stream.
Direct API — browser & raw fetch
Call the local agent directly from browser JavaScript with fetch(). Useful for client components, Electron renderers, or any environment where you cannot install npm packages.
1 · Status check (no auth)
// Check that PrintBridge is running (no API key needed)
const res = await fetch("http://127.0.0.1:1337/status");
const body = await res.json();
// { running: true, version: "...", entitled: true, trialDaysRemaining: 30, ... }
console.log(body);2 · List printers
// List installed printers (API key required)
const res = await fetch("http://127.0.0.1:1337/printers", {
headers: { "X-PrintBridge-Api-Key": YOUR_API_KEY },
});
const printers = await res.json();
// [{ name: "Zebra ZD620", displayName: "Zebra ZD620", isDefault: false,
// healthScore: 100, healthLabel: "ready" }, ...]
console.log(printers);3 · Send a print job
// Print a ZPL shipping label (Zebra, TSC, Honeywell)
const res = await fetch("http://127.0.0.1:1337/print", {
method: "POST",
headers: {
"Content-Type": "application/json",
"X-PrintBridge-Api-Key": YOUR_API_KEY,
},
body: JSON.stringify({
printerName: "Zebra ZD620", // exact name from GET /printers
format: "zpl",
content: `^XA
^FO50,50^ADN,36,20^FDShip To: John Smith^FS
^FO50,100^ADN,28,16^FD456 Main St, New York NY 10001^FS
^FO50,160^BY3^BCN,100,Y,N,N^FD794051896347^FS
^XZ`,
// copies: 3, // optional — loops the job 3×, no re-sending content
}),
});
const result = await res.json(); // { success: true }HTTP request shape
The canonical JSON body for POST /print. All fields except printerName and content are optional.
POST http://127.0.0.1:1337/print
X-PrintBridge-Api-Key: <your-key>
Content-Type: application/json
{
"printerName": "Zebra ZD620", // exact name from GET /printers
"format": "zpl", // see /docs/formats for full list
"content": "^XA...^XZ", // raw language or HTML/base64 PDF
"encoding": "utf8", // "utf8" (default) or "base64"
"copies": 1, // optional — loops raw jobs N times
"options": {
"silent": true, // no print dialog (default: true)
"printBackground": true // include CSS backgrounds
}
}See the full API reference for all endpoints including /print-batch, /printers, /logs, and the WebSocket stream.
Ready to cut the print dialog out of your workflow?
Start a free trial, install PrintBridge on your Windows machine, and wire your first silent print in minutes.