Errors
The genkiln error format, every HTTP error code, task error codes, and which errors are safe to retry.
Errors use standard HTTP status codes and a JSON body with a stable, machine-readable code:
JSON
{
"error": {
"code": "invalid_request",
"message": "input.duration: Invalid input",
"param": "input.duration",
"request_id": "req_01JC8ZW4H7J2K5M8N1P3Q6R9TV"
}
}| Field | Description |
|---|---|
code | Stable error code from the table below. Branch on this, not on message. |
message | Human-readable explanation. The wording may change. |
param | Only on some invalid_request and not_found errors: the field that caused it, e.g. input.image_urls.0. |
task | Only when a task was created but could not be started: the failed, refunded task. See Create task. |
request_id | ID of this request. Also sent as the X-Request-Id header on every response, successful or not. |
Include the request_id when you contact support.
HTTP error codes
| HTTP | Code | Meaning | Retry? |
|---|---|---|---|
| 400 | invalid_request | The request is malformed or failed validation: invalid JSON, body over 64 KB, unknown field, invalid input, unsafe URL, metadata too large, bad cursor or status. | No. Fix the request. |
| 401 | invalid_api_key | The API key is missing, malformed, deleted or expired. | No. |
| 402 | insufficient_credits | Your balance is lower than the task cost. No task was created. | After adding credits. |
| 403 | account_suspended | The account that owns this API key is suspended. No task was created. | No. Contact support. |
| 403 | content_rejected | The prompt or input media was rejected by our content policy. | No. Change the prompt or media. |
| 404 | not_found | The model or task does not exist, or the task belongs to another account. | No. |
| 409 | idempotency_conflict | The Idempotency-Key was already used with a different request body. | No. Use a new key or the original body. |
| 422 | model_unavailable | The model is temporarily unavailable. | Later. |
| 429 | rate_limited | Too many requests, or too many tasks in progress at once. | Yes, after Retry-After seconds. |
| 500 | internal_error | Something went wrong on our side. | Yes, with backoff. |
| 503 | service_busy | Temporarily unable to start the task. Any charge was refunded. | Yes, after Retry-After seconds. |
429 and 503 responses include a Retry-After header with the number of seconds to wait.
Task error codes
A task that fails after it was accepted reports its reason in the task's own error object, not as an HTTP error. See Get task.
| `error.code` | Meaning |
|---|---|
generation_failed | Generation failed. |
content_rejected | The prompt or input media was rejected by our content policy. |
invalid_input | The input could not be processed, e.g. an image URL that cannot be downloaded. |
timeout | The task did not finish in time. |
service_busy | The service was temporarily busy. |
canceled | The task was canceled. |
All of them are refunded automatically.
Retrying safely
- Retry only
429,500and503, and network errors where you got no response. - Use exponential backoff with jitter, and respect
Retry-After. - Always send an
Idempotency-KeyonPOST /v1/tasks, so a retry after a lost response returns the first task instead of charging you twice.