Api Endpoint

Copy from your ZeroPrint client

Print Request

POST /api/print
Content-Type: application/json

Request Parameters

FieldTypeRequiredDescription
targetstringYesTarget printer ID, can be copied from the client
datastringYesPrint job data. Plaintext JSON (debug only) or RSA+AES-256-GCM encrypted then Base64 encoded (recommended for production)

Request Example

Plaintext Mode (debug only)

{
  "target": "<Printer ID>",
  "data": "{\"url\":\"https://example.com/document.pdf\",\"copies\":1,\"id\":\"order_123\",\"callbackUrl\":\"https://your-server.com/callback\"}"
}

Encrypted Mode (recommended for production)

{
  "target": "<Printer ID>",
  "data": "SGVsbG8gV29ybGQgZm9yIGVuY3J5cHRlZC9pbnRlcmFjdGlvbiBvbmx5..."
}

Data Field Parameters

pageSize, duplex, color, orientation, resolution — Copy from client for printer-supported values. Uses printer defaults if not provided.

FieldTypeRequiredDescription
urlstringYesURL of the file to print, supports public and internal network addresses
copiesnumberNoNumber of copies, default 1
idstringNoTask ID, for callback correlation
callbackUrlstringNoPrint result callback URL
pageSizestringNoPage size (copy from client)
duplexstringNoDuplex mode (copy from client)
colorstringNoColor mode (copy from client)
orientationstringNoPage orientation (copy from client)
resolutionstringNoPrint resolution (copy from client)

Response

Success: HTTP 200 OK, no response body.

Failure: HTTP 400 Bad Request

{
  "code": "PRINTER_OFFLINE",
  "message": "target printer is offline"
}
codemessage
PRINTER_OFFLINEtarget printer is offline
INVALID_TARGETtarget is required and must be a 64-character lowercase hex string
INVALID_DATAdata is required and must be a non-empty string
INVALID_REQUESTInvalid JSON format

Callback

After the print job completes, the client sends a POST request to callbackUrl to notify the result. Both id and callbackUrl must be provided to trigger the callback.

POST {callbackUrl}
Content-Type: application/json

Callback Parameters

FieldTypeDescription
idstringTask ID (matches the id in request)
successbooleanWhether printing succeeded
errorstringError description (only on failure)

Success Callback

{ "id": "order_123", "success": true }

Failure Callback

{ "id": "order_123", "success": false, "error": "PDF printing failed: ..." }

Callback timeout: 5 seconds. HTTP status 2xx is considered success. Callback is fired regardless of print success or failure.


Encryption

RSA-2048 + AES-256-GCM hybrid encryption is recommended for production. Private key is stored locally on the client only; the cloud cannot decrypt.

Encryption Steps

  1. Copy the public key (from client)
  2. Generate AES-256 key and 12-byte Nonce
  3. Encrypt JSON with AES-256-GCM (with auth tag)
  4. Encrypt AES key with RSA-OAEP(SHA256) (256 bytes)
  5. Concatenate: encrypted key + Nonce + ciphertext + tag
  6. Base64 encode as the data value

Data Structure

[RSA-encrypted AES key (256 bytes)][GCM Nonce (12 bytes)][Ciphertext + auth tag]

Code Examples

const crypto = require("crypto");

function encryptData(publicKey, plaintext) {
  const wrapped = publicKey.match(/.{1,64}/g).join("\n");
  const pemKey = `-----BEGIN PUBLIC KEY-----\n${wrapped}\n-----END PUBLIC KEY-----`;

  const aesKey = crypto.randomBytes(32);
  const nonce = crypto.randomBytes(12);

  const cipher = crypto.createCipheriv("aes-256-gcm", aesKey, nonce);
  const ciphertext = Buffer.concat([
    cipher.update(plaintext, "utf8"),
    cipher.final(),
  ]);
  const tag = cipher.getAuthTag();

  const encryptedAesKey = crypto.publicEncrypt(
    {
      key: pemKey,
      padding: crypto.constants.RSA_PKCS1_OAEP_PADDING,
      oaepHash: "sha256",
    },
    aesKey,
  );

  return Buffer.concat([encryptedAesKey, nonce, ciphertext, tag]).toString("base64");
}

async function sendPrintRequest(target, printData, publicKey) {
  const plaintext = JSON.stringify(printData);
  const data = publicKey ? encryptData(publicKey, plaintext) : plaintext;

  const response = await fetch("https://<Api Endpoint>/api/print", {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({ target, data }),
  });

  if (!response.ok) throw await response.json();
  return { status: "success" };
}

const target = "<Printer ID>";
const publicKey = "MIIBIjANBgkqhkiG9w0BAQEFAAO...";
const printData = {
  url: "https://example.com/document.pdf",
  copies: 1,
  id: "order_123",
  callbackUrl: "https://your-server.com/callback",
};

sendPrintRequest(target, printData, publicKey)
  .then(() => console.log("Encrypted mode - request successful"))
  .catch((error) => console.error("Request failed:", error));

sendPrintRequest(target, printData)
  .then(() => console.log("Plaintext mode - request successful"))
  .catch((error) => console.error("Request failed:", error));
async function encryptData(publicKey, plaintext) {
  const publicKeyBytes = Uint8Array.from(atob(publicKey), c => c.charCodeAt(0));
  const publicKeyObj = await crypto.subtle.importKey(
    "spki", publicKeyBytes,
    { name: "RSA-OAEP", hash: "SHA-256" }, true, ["encrypt"]
  );

  const aesKey = await crypto.subtle.generateKey(
    { name: "AES-GCM", length: 256 }, true, ["encrypt"]
  );
  const nonce = crypto.getRandomValues(new Uint8Array(12));
  const data = new TextEncoder().encode(plaintext);

  const ciphertext = new Uint8Array(
    await crypto.subtle.encrypt({ name: "AES-GCM", iv: nonce }, aesKey, data)
  );

  const aesKeyBytes = new Uint8Array(await crypto.subtle.exportKey("raw", aesKey));
  const encryptedAesKey = new Uint8Array(
    await crypto.subtle.encrypt(
      { name: "RSA-OAEP", hash: "SHA-256" }, publicKeyObj, aesKeyBytes
    )
  );

  const combined = new Uint8Array(encryptedAesKey.length + nonce.length + ciphertext.length);
  combined.set(encryptedAesKey, 0);
  combined.set(nonce, encryptedAesKey.length);
  combined.set(ciphertext, encryptedAesKey.length + nonce.length);
  return btoa(String.fromCharCode(...combined));
}

async function sendPrintRequest(target, printData, publicKey) {
  const plaintext = JSON.stringify(printData);
  const data = publicKey ? await encryptData(publicKey, plaintext) : plaintext;

  const response = await fetch("https://<Api Endpoint>/api/print", {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({ target, data }),
  });

  if (!response.ok) throw await response.json();
  return { status: "success" };
}

const target = "<Printer ID>";
const publicKey = "MIIBIjANBgkqhkiG9w0BAQEFAAO...";
const printData = {
  url: "https://example.com/document.pdf",
  copies: 1,
  id: "order_123",
  callbackUrl: "https://your-server.com/callback",
};

sendPrintRequest(target, printData, publicKey)
  .then(() => console.log("Encrypted mode - request successful"))
  .catch((error) => console.error("Request failed:", error));

sendPrintRequest(target, printData)
  .then(() => console.log("Plaintext mode - request successful"))
  .catch((error) => console.error("Request failed:", error));

For other languages, follow the same logic or use AI-assisted translation.