Images
Three endpoints, one price per image. The model is always <provider>/<model>,
for example openai/gpt-image-1-mini or openrouter/google/gemini-3.1-flash-image-preview.
| Endpoint | Dialect | Notes |
|---|---|---|
POST /v1/images/generations | OpenAI | n up to 10. stream: true on GPT image models. |
POST /v1/images/edits | OpenAI | JSON images: [{image_url}], or multipart image[] + mask. n up to 10, stream as on generations. |
POST /v1/images | OpenRouter AI SDK | Always answers b64_json. Non-empty input_references makes it an edit. |
1curl https://api.aile.sh/v1/images/generations \2-H "Authorization: Bearer $AILE_KEY" \3-H "Content-Type: application/json" \4-d '{ "model": "openai/gpt-image-1-mini", "prompt": "a lighthouse at dusk" }'
Billing
- One unit per image returned. An edit bills at the same per-image price as a generation of that model.
- A response with no image is a
502and is not charged. - A provider refusal you can fix (
400,404,413,422…) passes through. One about the lender's account is a502saying you were not charged. - A
502or504arrives as503with the real code inx-aile-status. - Input images go to the provider as sent.
file_idreferences are refused. - OpenRouter's lender-cost fields (
usage.cost,cost_details,is_byok) are removed from buffered answers. - A key's pins and the routing headers choose the lender here too.
x-aile-providermust match the model's prefix, andx-aile-max-pricedoes not apply to a per-image price. - Where the deployment enables keyless x402, it covers all three endpoints: one image per request (
nabove 1 is a400), base64 only, no streaming.
Slow requests
A keyed request with no answer after 25 seconds is committed to 200 and sent a
space every 15 seconds (SSE keepalives when it streams) until the image arrives,
up to 120 seconds. It carries x-aile-edge-hold in place of the other x-aile-*
headers, and a failure after that is a 200 carrying the error body (an SSE error
frame when streaming). A keyless request is never held: with no image 30 seconds
after its payment is verified (the default), it is voided with a 504 and not charged.
Hosted URLs
Images come back as base64 by default. Where the deployment enables hosted images,
send response_format: "url" or the header x-aile-image-store: url on
/v1/images/generations for a hosted URL (x-aile-image-store: none always wins);
otherwise the answer stays base64. Hosted images expire. /v1/images and
/v1/images/edits always answer base64.
Streaming
stream: true streams GPT image models (openai/gpt-image-*, openrouter/openai/*) as
server-sent events, on all three endpoints (an edit's multipart stream=true too). You pay for
each finished image delivered, and a stream that delivers none is a 200 that bills
nothing. partial_images is not supported, and a streamed image is always base64.
Streaming needs an API key.