API reference
https://api-v1.catzprint.com. Bodies are JSON and unknown fields are rejected.Authentication
Send your key as a bearer token: Authorization: Bearer cz_live_…. Keys are created in the console by people with the Developer role or higher. Each key belongs to one organization, has a set of scopes, and can optionally be limited to IP ranges or given an expiry date.
| Prefix | Mode |
|---|---|
cz_live_ | Live: prints are billed. |
cz_test_ | Test: prints on real printers, never billed, up to 200 a day. Jobs have "live": false. |
The console and apps use signed-in sessions instead of keys; stations use their own device tokens. Those are covered by the console and apps, not this guide.
const printers = await cz.printers.list();Which organization a key belongs to
GET /v1/key tells you the organization a key belongs to, whether it's live or test, and its scopes. Any valid key can call it, whatever its scopes. Use it at startup to fill in {org} for the other endpoints instead of configuring the organization ID separately. The SDKs do this for you on first use.
const key = await cz.key(); // { id, org_id, org_name, live, scopes }It only works with an API key; a signed-in session gets 400 invalid. A revoked or expired key gets 401.
Scopes
| Scope | Allows |
|---|---|
jobs:write | Create, cancel, retry and reprint jobs; list templates. |
jobs:read | List and fetch jobs. |
printers:read | List printers. |
locations:read | List and fetch locations. |
Endpoints for API keys
{org} is your organization's ID. A key only works for its own organization; any other ID answers 404.
| Method and path | Scope | Returns |
|---|---|---|
GET /v1/key | Any | { id, org_id, org_name, live, scopes } |
POST /v1/orgs/{org}/jobs | jobs:write | 201 { job } — see Sending jobs |
GET /v1/orgs/{org}/jobs | jobs:read | { items, next_cursor, counts } |
GET /v1/orgs/{org}/jobs/{id} | jobs:read | { job, events } — events are { at, status, detail, actor } |
POST /v1/orgs/{org}/jobs/{id}/cancel | jobs:write | Cancels a scheduled, held, queued or sent job. |
POST /v1/orgs/{org}/jobs/{id}/retry | jobs:write | Queues a failed or held job again. |
POST /v1/orgs/{org}/jobs/{id}/reprint | jobs:write | { job } — a new job with the same content. 410 content_deleted once the document has passed retention. |
GET /v1/orgs/{org}/printers | printers:read | { printers } |
GET /v1/orgs/{org}/locations | locations:read | { locations } |
GET /v1/orgs/{org}/locations/{id} | locations:read | { location } |
GET /v1/orgs/{org}/templates | jobs:write | { templates } |
A key without the scope an endpoint needs gets 403 forbidden, and the message names the missing scope.
Public endpoints
No authentication needed. Limited to 30 requests a minute per IP.
| Method and path | Returns |
|---|---|
GET /v1/public/server-key | { public_key, algorithm } — see Sealing content |
GET /v1/public/status | { status, components: [{ name, status }], notice, checked_at }. status is operational, degraded or outage (the API or print delivery is down). |
GET /v1/public/pricing | Current prices in cents; null when not published. |
GET /v1/public/downloads | Latest stable app release per platform, or null. |
Conventions
- IDs are UUIDs. Times are RFC 3339 in UTC, such as
2026-10-12T09:14:03Z. POSTrequests that create something answer201; other successes answer200, or204with no body.- Lists page with
limitandcursor: pass thenext_cursorfrom one page to get the next. An emptynext_cursormeans you're done. - Job documents are kept for 30 days after the job finishes and uploads for 7 days, by default; CatzPrint administrators configure both. After that, preview, content and reprint answer
410 content_deleted, while the job record (title, status, times) stays. See Retention. - Errors are
{"error": {"code", "message", …}}— see Errors and rate limits.