Printers, agents & quota

Read the printers, zplCloud CLI agents, label quota and webhooks behind an API key. The printer lists supply the target values for batch jobs, /v1/webhooks the IDs for webhook callbacks.

All endpoints on this page are GET requests on https://api.zplcloud.com, need an API key (X-API-Key or Basic Auth) and accept the webhook parameters webhookId and webhookResult. They count no renders and are never limited by the quota. Company always means the company of the API key; keys without a company get the personal records of the key owner instead (scope: "personal"). The JSON responses below are example data.

Printers of the API key

GET /v1/printers returns only the printers bound to the API key used for the call:

  • Weblink cloud printers whose certificate was issued for this key - the key stored with the printer is the calling key.
  • Remote printers whose agent connects with this key - the printer's agent name matches an agent that is online with this key or has a configuration stored for it. Remote printers without an agent are not listed.
  • Virtual printers are not bound to keys; they appear in GET /v1/company/printers.

Useful when one key per site or per application should only see "its" printers. Weblink printers come first (online first, most recent connection first), then remote printers by name.

curl https://api.zplcloud.com/v1/printers -H "X-API-Key: sk_zplcloud_YOUR_KEY"
{
  "scope": "apiKey",
  "apiKey": "sk_zplcloud_…9f3a",
  "count": 2,
  "printers": [
    {
      "target": "wl:17",
      "type": "weblink",
      "id": 17,
      "name": "Packing station 1",
      "serial": "D4J223104587",
      "model": "ZT411",
      "hostname": "ZT411-PACK1",
      "online": true,
      "blocked": false,
      "firmware": "V92.21.39Z",
      "linkOsVersion": "7.0",
      "lastConnectUtc": "2026-09-11T08:02:13.52",
      "lastKeepAliveUtc": "2026-09-11T10:14:58.107",
      "apiKeyBound": true,
      "apiKey": null,
      "owner": null
    },
    {
      "target": "rp:5",
      "type": "remote",
      "id": 5,
      "name": "Shipping ZD421",
      "online": true,
      "host": "192.168.10.41",
      "port": 9100,
      "usb": false,
      "agent": "warehouse-pi",
      "agentOnline": true,
      "agentVersion": "1.8.2",
      "owner": null,
      "createdUtc": "2026-06-02T13:40:11.803"
    }
  ]
}
FieldMeaning
scopeAlways apiKey.
apiKeyThe calling key, masked (prefix and last 4 characters).
countNumber of entries in printers.
printersPrinter entries - fields see printer entry. apiKey and owner are always null here.

Webhook event: api.printers.listed, summary { scope, count, weblink, remote }.

Printers of the company

GET /v1/company/printers returns every printer the key's company can use, regardless of which key it was set up with.

scopeWhenContent
companyThe API key belongs to a company.Weblink printers visible to the company, all remote and virtual printers of the company.
personalThe API key has no company.Printers of the key owner's e-mail; company is null.
typePrintertarget
weblinkZebra printer connected to zplCloud through Weblink.wl:{id} (the serial number works too)
remoteLAN or USB printer reached through a zplCloud CLI agent.rp:{id}
virtualVirtual test printer (watermarked PNG) - only listed where virtual printers are available.vp:{id}
curl https://api.zplcloud.com/v1/company/printers -H "X-API-Key: sk_zplcloud_YOUR_KEY"
{
  "scope": "company",
  "company": "example-logistics",
  "count": 3,
  "printers": [
    {
      "target": "wl:17",
      "type": "weblink",
      "id": 17,
      "name": "Packing station 1",
      "serial": "D4J223104587",
      "model": "ZT411",
      "hostname": "ZT411-PACK1",
      "online": true,
      "blocked": false,
      "firmware": "V92.21.39Z",
      "linkOsVersion": "7.0",
      "lastConnectUtc": "2026-09-11T08:02:13.52",
      "lastKeepAliveUtc": "2026-09-11T10:14:58.107",
      "apiKeyBound": false,
      "apiKey": "sk_zplcloud_…c71b",
      "owner": "ops@example.com"
    },
    {
      "target": "rp:5",
      "type": "remote",
      "id": 5,
      "name": "Shipping ZD421",
      "online": false,
      "host": "192.168.10.41",
      "port": 9100,
      "usb": false,
      "agent": "warehouse-pi",
      "agentOnline": false,
      "agentVersion": null,
      "owner": "ops@example.com",
      "createdUtc": "2026-06-02T13:40:11.803"
    },
    {
      "target": "vp:3",
      "type": "virtual",
      "id": 3,
      "name": "Test 100x150",
      "online": true,
      "widthMm": 100,
      "heightMm": 150,
      "dpi": 203,
      "owner": "dev@example.com",
      "createdUtc": "2026-08-19T09:05:44.61"
    }
  ]
}
FieldMeaning
scopecompany or personal.
companyCompany of the API key; null for personal.
countNumber of entries in printers.
printersWeblink, then remote, then virtual printers.

Webhook event: api.company.printers.listed, summary { scope, count, weblink, remote, virtual }.

Printer entry

FieldTypeMeaning
targetallPrinter target for batch jobs: wl:{id}, rp:{id}, vp:{id}.
typeallweblink, remote or virtual.
idallID within its type.
nameallDisplay name. Weblink: display name, otherwise hostname, otherwise serial.
onlineallWeblink: printer connected. Remote: its agent is online. Virtual: always true.
ownerallE-mail of the user who set the printer up. Only in the company list.
serial, model, hostnameweblinkDevice data reported by the printer.
firmware, linkOsVersionweblinkFirmware and Link-OS version.
blockedweblinkPrinter blocked in zplCloud.
lastConnectUtc, lastKeepAliveUtcweblinkLast Weblink connection and last keep-alive (UTC).
apiKeyBoundweblinktrue if the printer is bound to the calling key.
apiKeyweblinkMasked key the printer is bound to. Only in the company list.
host, port, usbremoteAddress the agent prints to (TCP, usually port 9100) or USB.
agent, agentOnline, agentVersionremoteAgent name, whether it is online, zplCloud CLI version (null while offline).
widthMm, heightMm, dpivirtualLabel size and resolution.
createdUtcremote, virtualCreated (UTC).

Using target in batch jobs

Pass target unchanged as printer to POST /v1/batch/design/{designId}. The job resolves it in the key owner's scope before rendering - a wrong target fails immediately with 400 or 404 - and prints in blocks of 100 labels: wl: through the Weblink connection, rp: through the agent (it must be online), vp: into the virtual printer's history.

curl -X POST "https://api.zplcloud.com/v1/batch/design/shipping-label.42?webhookId=12" \
  -H "X-API-Key: sk_zplcloud_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"records":[{"sku":"A-1001"},{"sku":"A-1002"}],"output":"none","printer":"rp:5","async":true}'

Details on batch jobs: Rendering.

Agents of the API key

GET /v1/agents lists zplCloud CLI agents (zplcloud proxy) that connect with this key: all live connections plus agents that are offline but have a configuration stored for this key. Entries are merged by agent name - several connections under the same name are counted in connections, and the most recent one supplies version, OS and host.

curl https://api.zplcloud.com/v1/agents -H "X-API-Key: sk_zplcloud_YOUR_KEY"
{
  "scope": "apiKey",
  "apiKey": "sk_zplcloud_…9f3a",
  "count": 2,
  "online": 1,
  "agents": [
    {
      "name": "office-win",
      "online": false,
      "connections": 0,
      "version": null,
      "os": null,
      "hostname": null,
      "ips": [],
      "connectedAt": null,
      "lastSeenUtc": null,
      "lastHealthCheckUtc": null,
      "configVersion": 2,
      "configUpdatedUtc": "2026-07-14T15:30:00",
      "printers": 1,
      "apiKey": null,
      "owner": null
    },
    {
      "name": "warehouse-pi",
      "online": true,
      "connections": 1,
      "version": "1.8.2",
      "os": "Linux 6.6 arm64",
      "hostname": "raspberrypi",
      "ips": ["192.168.10.20"],
      "connectedAt": "2026-09-10T22:03:41.2210473Z",
      "lastSeenUtc": "2026-09-11T10:14:30.0071210Z",
      "lastHealthCheckUtc": "2026-09-11T10:14:30.0071210Z",
      "configVersion": 4,
      "configUpdatedUtc": "2026-08-28T09:12:05.4",
      "printers": 3,
      "apiKey": null,
      "owner": null
    }
  ]
}
FieldMeaning
scope, apiKeyAlways apiKey; the calling key, masked.
count, onlineNumber of agents and how many of them are online.
agents[].nameAgent name (sorted alphabetically).
online, connectionsAt least one live connection; number of live connections under this name.
version, os, hostname, ipszplCloud CLI version and host data of the most recent connection; null / empty while offline.
connectedAt, lastSeenUtc, lastHealthCheckUtcConnection start, last sign of life, last health check (UTC); null while offline.
configVersion, configUpdatedUtcVersion and last change of the stored agent configuration; null without configuration.
printersNumber of remote printers in the account assigned to this agent name.
apiKey, ownerAlways null here; filled in the company list.

Webhook event: api.agents.listed, summary { scope, count, online }.

Agents of the company

GET /v1/company/agents lists all agents of the key's company across all API keys - live connections and offline agents with a stored configuration. Keys without a company get the key owner's personal agents (scope: "personal"). The entries have the same fields as GET /v1/agents, plus apiKey (masked key the agent connects with) and owner (e-mail).

curl https://api.zplcloud.com/v1/company/agents -H "X-API-Key: sk_zplcloud_YOUR_KEY"
{
  "scope": "company",
  "company": "example-logistics",
  "count": 1,
  "online": 1,
  "agents": [
    {
      "name": "warehouse-pi",
      "online": true,
      "connections": 1,
      "version": "1.8.2",
      "os": "Linux 6.6 arm64",
      "hostname": "raspberrypi",
      "ips": ["192.168.10.20"],
      "connectedAt": "2026-09-10T22:03:41.2210473Z",
      "lastSeenUtc": "2026-09-11T10:14:30.0071210Z",
      "lastHealthCheckUtc": "2026-09-11T10:14:30.0071210Z",
      "configVersion": 4,
      "configUpdatedUtc": "2026-08-28T09:12:05.4",
      "printers": 3,
      "apiKey": "sk_zplcloud_…9f3a",
      "owner": "ops@example.com"
    }
  ]
}
FieldMeaning
scopecompany or personal.
companyCompany of the API key; null for personal.
count, onlineNumber of agents and how many of them are online.
agents[].apiKeyMasked API key of the most recent connection, otherwise of the stored configuration.
agents[].ownerE-mail of the key owner.

Webhook event: api.company.agents.listed, summary { scope, count, online }.

Label quota

GET /v1/quota returns the current label quota of the key owner - the same numbers the platform shows under Billing. How labels are counted: Label quota and render counting.

curl https://api.zplcloud.com/v1/quota -H "X-API-Key: sk_zplcloud_YOUR_KEY"
{
  "plan": "starter",
  "status": "active",
  "billing": "monthly",
  "labels": {
    "limit": 15000,
    "used": 4211,
    "remaining": 10789,
    "percentUsed": 28.1,
    "includedInPlan": 10000,
    "purchasedTopUps": 5000
  },
  "period": {
    "start": "2026-09-01",
    "end": "2026-09-30",
    "resetsUtc": "2026-10-01T00:00:00Z"
  },
  "subscription": {
    "currentPeriodEnd": "2026-10-14T09:31:22",
    "cancelAt": null
  },
  "counting": "Labels are counted per account (the API key owner) per calendar month in UTC. Design renders (ZPL, PDF, PNG) and batch jobs return 429 when the limit is reached; ZPL tools and label enrichment are counted but never blocked."
}
FieldMeaning
planfree (Developer), starter or pro. Without an active subscription: free. Batch jobs and label enrichment need pro; other plans get 403 there.
statusSubscription status, e.g. none, active, past_due, canceled.
billingmonthly or annual.
labels.limitMonthly limit: includedInPlan + purchasedTopUps.
labels.usedLabels counted in the current calendar month (platform and API). New API renders are included immediately.
labels.remaininglimit - used, never below 0.
labels.percentUsedused / limit in percent, one decimal.
labels.includedInPlanLabels included in the plan: 100, 10,000 or 100,000.
labels.purchasedTopUpsLabels from all purchased render top-ups.
period.start, period.endFirst and last day of the current calendar month (UTC).
period.resetsUtcWhen used starts again at 0: the 1st of next month, 00:00 UTC.
subscription.currentPeriodEndEnd of the current billing period; null without subscription.
subscription.cancelAtSet when the subscription is cancelled at the end of the period.
countingThe counting rule in one sentence.

Reading the quota

  • Before a design render (ZPL, PDF, PNG) or batch job: the call goes through if the number of labels is at most labels.remaining; otherwise it gets 429 before anything is rendered.
  • used can exceed limit (then remaining stays 0), because ZPL tools and label enrichment are never blocked.
  • Counting period ≠ billing period: the label counter follows the calendar month (period), not subscription.currentPeriodEnd.
  • Buffered counting: limit and usage are cached for 60 seconds per account; renders on api.zplcloud.com count in memory at once and are written to the database every 5 seconds. GET /v1/quota therefore shows new API renders immediately and labels from the platform after at most 60 seconds, while Billing in the platform can lag a few seconds behind.
  • Plan: plan tells you before the call whether batch jobs and label enrichment are available (pro).
  • Monitoring: a scheduled GET /v1/quota?webhookId=12 sends api.quota.checked with summary { plan, limit, used, remaining } to your webhook.

Webhooks

GET /v1/webhooks lists the stored webhooks of the key owner - company-wide, or personal for keys without a company - newest first. Use id as webhookId. Secrets are never returned; they are shown in the platform under Webhooks, where each webhook also displays its ID as ID n.

curl https://api.zplcloud.com/v1/webhooks -H "X-API-Key: sk_zplcloud_YOUR_KEY"
{
  "count": 2,
  "webhooks": [
    {
      "id": 12,
      "url": "https://erp.example.com/hooks/zplcloud",
      "status": "active",
      "events": ["label.rendered", "export.completed"],
      "lastDeliveryUtc": "2026-09-11T10:15:03.117",
      "lastHttpStatus": 204,
      "consecutiveFailures": 0,
      "createdUtc": "2026-08-02T07:45:19.5"
    },
    {
      "id": 7,
      "url": "https://hooks.example.org/labels",
      "status": "disabled",
      "events": ["print.status_changed"],
      "lastDeliveryUtc": "2026-07-30T16:02:41.9",
      "lastHttpStatus": 500,
      "consecutiveFailures": 4,
      "createdUtc": "2026-05-19T12:00:00"
    }
  ],
  "usage": "Pass id as ?webhookId=<id> on the design rendering (PDF, PNG), /v1/tools, /v1/enrich, /v1/batch, printer, agent, quota and webhook endpoints to be called when the request has finished; add &webhookResult=true to receive the result as well. Deliveries are signed with X-ZplCloud-Signature (HMAC-SHA256 of the body with the webhook secret)."
}
FieldMeaning
countNumber of webhooks.
webhooks[].idValue for webhookId.
urlReceiver URL.
statusactive or disabled. Only active webhooks are accepted as webhookId (400 otherwise).
eventsSubscribed platform events - not relevant for API callbacks.
lastDeliveryUtc, lastHttpStatusLast delivery attempt and the receiver's status code; null before the first delivery.
consecutiveFailuresFailed attempts since the last successful delivery.
createdUtcCreated (UTC).
usageShort usage note for the webhook parameters.

Webhook event: api.webhooks.listed, summary { count }. Payload, signature and retries: Webhook callback.