Images
Generate and edit images with POST /v1/images/generations and POST /v1/images/edits. Results are returned inline as base64 and never stored.
The Images endpoints accept the familiar Images API request shape and return the generated image inline as b64_json. zrouter does not host image URLs and keeps no server-side history: prompts, source images and results exist only for the duration of the request.
Generate an image#
curl https://api.zrouter.dev/v1/images/generations \
-H "Authorization: Bearer $ZROUTER_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{"model":"gpt-image-2","prompt":"A lighthouse at dusk, watercolor","size":"1024x1024","output_format":"png"}' \
| jq -r '.data[0].b64_json' | base64 --decode > image.pngEdit an image#
Edits only work with models whose catalog capabilities include edit. The image models currently listed support generation only; calling /v1/images/edits with them returns 400 unsupported_endpoint.
curl https://api.zrouter.dev/v1/images/edits \
-H "Authorization: Bearer $ZROUTER_API_KEY" \
-F model=gpt-image-2 \
-F prompt="Make the sky orange" \
-F [email protected] \
| jq -r '.data[0].b64_json' | base64 --decode > edited.pngParameters#
| Field | Values | Notes |
|---|---|---|
model | image model id | Required. |
prompt | 1–32,000 characters | Required. |
n | 1 | One image per request. |
size | auto or WxH | Each edge ≤ 4096 px, total ≤ 16,777,216 px. |
quality | auto, low, medium, high | Optional. |
output_format | png, jpeg, webp | Optional, default png. |
output_compression | 0–100 | jpeg/webp only. |
background | auto, opaque, transparent | Optional. |
image | PNG, JPEG or WebP file | Edits only. Exactly one file, ≤ 10 MiB. Remote URLs are rejected. |
response_format=url, stream, partial_images and mask are not supported and return 400 unsupported_parameter. Unknown fields are rejected rather than forwarded.
Limits#
- One active image request per account; a second concurrent request returns
429 image_concurrency_limit. - Requests time out after 120 seconds (
408 request_timeout). - Generated images larger than 20 MiB are withheld (
502). - Send an
Idempotency-Keyheader to make retries safe: reusing a key never triggers a second generation or a second charge, and returns409 idempotency_key_reusedbecause results are not stored.
Billing#
Image requests are billed from the token usage the provider reports (usage.input_tokens / usage.output_tokens) at the model's listed per-million rates, consuming Token Plan balance first and then PAYG — exactly like text requests. The response header x-zrouter-billing is settled when the charge is recorded. If the provider does not report usage, the image is still delivered, the request is not charged, and it is queued for review (x-zrouter-billing: unmetered).
Image-specific errors#
| Status | Code | Meaning |
|---|---|---|
| 400 | content_policy_violation | The provider declined the prompt or image. Not charged. |
| 400 | unsupported_parameter | A field outside the supported set was sent. |
| 400 | unsupported_endpoint | The model does not support this image operation (for example edits). |
| 402 | insufficient_balance | No Token Plan or PAYG balance for this model. |
| 408 | request_timeout | The image was not ready within 120 seconds. |
| 409 | idempotency_key_reused | This Idempotency-Key was already used. |
| 413 | image_too_large | The source image exceeds the size or pixel limits. |
| 429 | image_concurrency_limit | Another image request from your account is still running. |