Api Endpoint
Copy from your ZeroPrint client
Print Request
POST /api/print
Content-Type: application/json
Request Parameters
| Field | Type | Required | Description |
|---|---|---|---|
target | string | Yes | Target printer ID, can be copied from the client |
data | string | Yes | Print 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.
| Field | Type | Required | Description |
|---|---|---|---|
url | string | Yes | URL of the file to print, supports public and internal network addresses |
copies | number | No | Number of copies, default 1 |
id | string | No | Task ID, for callback correlation |
callbackUrl | string | No | Print result callback URL |
pageSize | string | No | Page size (copy from client) |
duplex | string | No | Duplex mode (copy from client) |
color | string | No | Color mode (copy from client) |
orientation | string | No | Page orientation (copy from client) |
resolution | string | No | Print 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"
}
| code | message |
|---|---|
PRINTER_OFFLINE | target printer is offline |
INVALID_TARGET | target is required and must be a 64-character lowercase hex string |
INVALID_DATA | data is required and must be a non-empty string |
INVALID_REQUEST | Invalid 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
| Field | Type | Description |
|---|---|---|
id | string | Task ID (matches the id in request) |
success | boolean | Whether printing succeeded |
error | string | Error 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
- Copy the public key (from client)
- Generate AES-256 key and 12-byte Nonce
- Encrypt JSON with AES-256-GCM (with auth tag)
- Encrypt AES key with RSA-OAEP(SHA256) (256 bytes)
- Concatenate: encrypted key + Nonce + ciphertext + tag
- 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.