Errors & Limits
Error shapes and limits to design around.
Error format
Errors return non-2xx status and JSON body with structured error object. Branch on error.code — it's stable and machine-readable. error.message is human-readable and may change; don't parse it. Code-specific fields (like retryAt) sit alongside, and all timestamps are ISO 8601 UTC.
{
"error": {
"code": "rate_limit_exceeded",
"message": "Rate limit exceeded for this account. Retry in 1s, at 2026-07-06T18:04:05.000Z (UTC).",
"retryAfter": 1,
"retryAt": "2026-07-06T18:04:05.000Z",
"docUrl": "https://zpljet.com/docs/errors#rate_limit_exceeded"
}
}Error codes
| Code | Status | Description |
|---|---|---|
| invalid_request | 400 | The body failed validation (e.g. missing or malformed zpl). The message says what's wrong. param — the offending field |
| missing_api_key | 401 | No X-API-Key header was sent. |
| invalid_api_key | 401 | The API key is invalid, disabled, or expired. |
| payload_too_large | 413 | The JSON request body exceeded 1 MiB. ZPL content is limited to 512 KB. |
| quota_exceeded | 402 | Monthly conversion quota exceeded for your plan. plan, quota, used, resetsAt — when the quota resets (UTC) |
| hosting_not_allowed | 403 | output:"url" requested on a data-only plan. Use output:"data" or upgrade. plan |
| no_retention_enforced | 403 | output:"url" requested while enforced no-retention mode is on for the account. |
| rate_limit_exceeded | 429 | Too many requests for this account. Also sent as a Retry-After header (seconds). Per-key limits are a secondary control. retryAfter — seconds, retryAt — ISO 8601 timestamp (UTC) |
| conversion_failed | 502 | The engine could not render the ZPL. conversionId — reference this when contacting support |
| service_unavailable | 503 | Render engine temporarily unavailable; the request was not charged against quota. Retry after the retry-after interval. retryAfter — seconds |
| wrong_domain | 404 | Wrong host for this request: /v1/* only works on api.zpljet.com, and api.zpljet.com serves nothing but the API. |
Limits
- ZPL size: up to 512 KB per request.
- Labels per request: up to 50 (multi-page PDF).
- Hosted file retention: data mode stores nothing. Hosted files (
output:"url") follow your dashboard retention window: up to 3 days (Starter), 30 (Pro), or 90 (Scale). - Hosted URLs: public links that work until the file is deleted at its
expiresAt. - Monthly quota: per plan; exceeding returns
402 quota_exceededwithresetsAt. - Rate limits: account-wide, per second, by plan; per-key limits are secondary. Exceeding returns
429 rate_limit_exceededwithretryAfter/retryAtfields and aRetry-Afterheader (seconds).