Errors
All error responses use the same envelope and always include a requestId.
Quote that value when contacting support — see Request IDs below.
{
"code": -3,
"message": "Invalid capability mode 'hdr'. Allowed values: general, graphics, portrait, text.",
"requestId": "7f3a1c92-4b8e-4d21-9a6f-2c5e8b1d0437"
}
The HTTP status carries the error category; the code field carries the specific
reason. Check both — several distinct code values share a single HTTP status.
HTTP status codes
| HTTP status | When it occurs |
|---|---|
200 OK | Success. code is 0. |
400 Bad Request | Invalid request parameters (including an unknown mode), account not subscribed, or insufficient credits. |
401 Unauthorized | Missing or invalid API key. |
404 Not Found | The task does not exist, has expired, or belongs to a different account (GET /api/v1/tasks/...). |
429 Too Many Requests | Call-rate or active-task quota exceeded. Honor Retry-After when present; otherwise use exponential backoff with jitter. See Rate limits and task quotas. |
503 Service Unavailable | A protective service or dependency is temporarily unavailable. Honor Retry-After when present and retry with exponential backoff and jitter. |
500 Internal Server Error | Unexpected server-side error. |
Business error codes
| Code | Name | HTTP | Meaning |
|---|---|---|---|
0 | Success | 200 | Request completed successfully. |
-1 | General failure | 401 or 500 | With HTTP 401: missing, invalid, or inactive API key. With HTTP 500: unclassified server error. |
-2 | Parameter invalid | 400 | A request parameter failed validation (missing image, unknown resolution, etc.). |
-3 | INVALID_MODE | 400 | mode is not one of general, graphics, portrait, text. Distinct from -2 so clients can handle it specifically. |
-1000 | Service busy | 429 or 503 | With HTTP 429: a call-rate or active-task quota was exceeded. With HTTP 503: a protective service or dependency is temporarily unavailable. Honor Retry-After when present; otherwise retry with exponential backoff and jitter. |
24403 | Not subscribed | 400 | The API key's account is not on an active subscription or the subscription has expired. |
20601 | Insufficient credits | 400 | The account does not have enough credits for this request. |
-60404 | Task not found | 404 | The taskId does not exist for the given businessType, has expired, or belongs to a different account. |
Task status values
When polling GET /api/v1/tasks/{businessType}/{taskId}, data.status is one of:
| Status | Meaning | Terminal? |
|---|---|---|
REQUESTED | Task created but not yet queued. | No |
PENDING | Task is queued or actively running. | No |
SUCCESS | Processing complete. data.generateUrl is populated. | Yes |
FAIL | Failed after retries or expired. Credits are refunded. | Yes |
ERROR | Failed and not retryable. Credits are refunded. | Yes |
OTHER | Status could not be mapped to a public value. | Treat as terminal — see below |
OTHER as terminalOTHER is returned when the task's internal state has no public equivalent.
This includes tasks that were discarded, which is a permanent condition.
Do not poll indefinitely on OTHER. A client that treats it as a safe
intermediate state will hang forever on discarded tasks. Stop polling when you
receive OTHER, and always cap total polling time regardless of status.
Request IDs
Every response — success or failure, including 401 and 429 — carries a
requestId in the body and the same value in the X-Request-Id response header.
It identifies that one HTTP call.
You can supply your own value on the request to line our logs up with yours:
X-Request-Id: my-job-8f21c
- Maximum 64 characters, from
A-Z a-z 0-9 _ -. - If you omit the header or send a value that doesn't match those rules, one is supplied for you. Treat values you didn't supply as opaque — their format is not part of the contract and may change.
Store the requestId with your own job record, next to the taskId when one
exists. A taskId only exists once a task has been created, so for failures
that happen before that — authentication, rate limiting, invalid parameters,
subscription or credit checks — the requestId is the only handle you have.
Quote it when you contact support and we can locate the exact call.