Skip to content
zoroprint
Developers

Send orders from your own shop.

One endpoint puts a gang sheet in the same queue your ZoroPrint RIP reads, and webhooks tell your shop when it is printed. Use it from Shopify, WooCommerce, an ERP, or a script. There is no commission and no separate plan for the API beyond the one your account is on.

Get a key

Open your account, confirm it is you, then create a key under API & webhooks. The key is shown once. Send it as a bearer token on every request; anything else gets 401.

Create an order

Send the artwork as PNG data URLs with the physical width you want printed. We assemble the project file, so you never deal with our format. Transparent PNG at 300 dpi gives the best result: the RIP builds the white underbase from the transparency.

curl -X POST https://api.zoroprint.com/v1/orders \
  -H "authorization: Bearer zp_live_…" \
  -H "content-type: application/json" \
  -d '{
    "customer": "Ana Popescu",
    "reference": "WC-1042",
    "dueAt": "2026-09-22T10:00:00Z",
    "rush": false,
    "source": "woocommerce",
    "pieces": [
      { "name": "logo.png", "png": "data:image/png;base64,iVBORw0…", "wMm": 80, "copies": 5 }
    ]
  }'

pieces — up to 200, each with name, png (a data:image/png;base64 URL), wMm (printed width in millimetres), optional hMm, copies and dpi. Everything else is optional: title, customer, reference (your own order number, kept in the notes), notes, dueAt, rush and sheet. The whole request may be up to 64 MB.

A deadline is worth sending: the RIP builds its next sheet from the most urgent orders that fit together, so dueAt is what lets it combine yours well.

Read and cancel

GET  https://api.zoroprint.com/v1/orders?status=queued&limit=25
GET  https://api.zoroprint.com/v1/orders/<id>
POST https://api.zoroprint.com/v1/orders/<id>/cancel     # only while it is still queued

An order is queued until a RIP takes it, then printing, then done. The artwork is never sent back.

Webhooks

Add an https endpoint in your account and we POST to it on order.created, order.printing, order.done and order.canceled. Verify the signature before trusting the body.

// Node — the header is: t=<unix seconds>,v1=<hex hmac-sha256 of "<t>.<raw body>">
import { createHmac, timingSafeEqual } from "node:crypto";

function verify(secret, rawBody, header) {
  const p = Object.fromEntries(header.split(",").map((x) => x.split("=", 2)));
  if (Math.abs(Math.floor(Date.now() / 1000) - Number(p.t)) > 300) return false;  // replayed
  const want = Buffer.from(createHmac("sha256", secret).update(p.t + "." + rawBody).digest("hex"));
  const got = Buffer.from(String(p.v1 ?? ""));
  return want.length === got.length && timingSafeEqual(want, got);
}

Verify against the raw request body, before any JSON parsing. Delivery is one attempt with a five second timeout; failures are shown on your account page. If you need certainty, poll GET /v1/orders as well.

Limits and errors

120 requests a minute per key. Errors are JSON with a stable code: unauthorized (401), validation (400), not_found (404), already_taken (409), too_large (413), rate_limited (429). Revoking a key takes effect immediately.

Building a plugin or an integration? Tell us what you need at hello@zoroprint.com — we would rather fix the API than have you work around it.