Skip to main content
Every request to /render needs an API key. You create keys in the console.

Get a key

  1. Sign in to the console and open API keys.
  2. Create a key. Choose Test or Live, and when it expires: after 30 days, 90 days, 1 year, or never.
  3. Copy the key. It’s shown once, so store it somewhere safe, such as a secret manager or an environment variable.
Keys look like zpl_live_… or zpl_test_….

Send the key

Send the key in the Authorization header:
If your client can’t set Authorization, send X-API-Key: <key> instead.
Keep keys on your server. Don’t put them in browser code, mobile apps or public repositories.

Live and test keys

Use a test key while you integrate. The TEST watermark is printed three times across each label and reversed where it covers black areas, so you can’t mistake a test label for a real one. Switch to a live key when you go to production.

Billing

Live keys need an active subscription. Set it up on the Billing page of the console, where you also find the price per label.
  • Every page in the response is one label, including ^PQ copies.
  • A PNG response is one label, because it’s one page.
  • Failed requests are free.
  • Test keys are always free.
The X-Labels-Billed response header tells you how many labels the request was billed for. It’s 0 for a test key.

Safe retries with Idempotency-Key

A request can time out after the labels were rendered. To retry without paying twice, send an Idempotency-Key header with a unique value of up to 255 characters, such as your order or shipment number. A retry with the same API key, Idempotency-Key, labels and query parameters is billed once. Reusing a key for different labels, or for another page or format, is billed as a new request, so use a new value for every new label. A retry is rendered again, and its X-Labels-Billed header shows the full count even though the invoice counts it once.

Rate limits

Each API key can make about 50 requests per second, with bursts of up to 200 at once. The limit is per key, not per account, and it’s approximate. It’s generous on purpose: it’s there to stop runaway loops, not to limit normal use. Several files in one multipart request count as one request. Over the limit, the API returns 429 Too Many Requests with a Retry-After header. Wait that many seconds, then retry the request. A 429 is never billed.
Every successful response has RateLimit-Limit, the burst size, and RateLimit-Remaining, the requests you can still make at once. Need more? Email jaap@jaapelst.nl.

Renew, revoke and expiry

Manage your keys on the API keys page of the console.
  • Renew issues a new token for the same key, with a new expiry. Replace the token in your application. Earlier tokens of the key keep working until they expire.
  • Revoke disables a key and all its tokens for good. It takes effect within about a minute.
  • Expiry is set when you create a key. An expired key returns 401. Renew it to keep going.
The renderer checks keys itself, so rendering keeps working even when the console is unavailable.

Errors

Errors have a plain-text body that says what went wrong and links to the console. For example, a request without a key returns:

Playground

The playground needs no key. It renders in your browser for free, and stamps PREVIEW on every label and PDF.