Skip to main content
POST
Create image generation

Sample output

Generated image sample
Generated with Nano Banana (nano-banana). Works unchanged with the OpenAI SDK: client.images.generate(...).

Response formats

  • response_format: "url" (default) → a URL, ephemeral (~1 hour). Download within that window if you need to keep it.
  • response_format: "b64_json" → inline base64 PNG. DALL-E models honour this; GPT Image models always return base64 regardless.
Some models are served through our durable job path, and those responses carry a file_id next to each url — already a permanent handle on bytes in your workspace storage. When file_id is absent, upload the decoded bytes via POST /v1/files to persist them. A generation that runs past the 5-minute wait budget answers 504 with a job_id in the error body rather than an image. The job continues and is still billed; collect the result from GET /v1/images/jobs/{job_id}.

Supported models

See Models catalog filtered to image modality. OpenAI (DALL·E), Google (Imagen, Gemini Image), xAI (Grok Image), Alibaba (Qwen Image), Suno-music, FLUX (self-hosted) — all accessed by slug.

Aspect ratios and sizes

Per-model; common values: 1024x1024, 1792x1024, 1024x1792, 512x512. Check a model’s _infery.allowed_params.sizes in GET /v1/models.

Authorizations

Authorization
string
header
required

API key in format: Bearer inf_***

Body

application/json
model
string
required

Model ID to use for generation

prompt
string
required

Text prompt describing the image to generate

stream
boolean
default:false

Read the generation as Server-Sent Events instead of waiting for a JSON body. A BODY field, and a real boolean — the handler reads body.stream. /v1/music/generations made the opposite choice and takes its flag as the QUERY parameter ?stream=true, so the two are not interchangeable: ?stream=true is ignored here, and a stream key in music’s body is ignored there. A streaming request also never takes the durable media-job path and has no fallback, because the SSE headers are flushed before the provider is called.

n
integer
default:1

Number of images (model-specific max: DALL-E 3=1, Imagen=4, GPT Image=4, DALL-E 2=10)

size
string

Image size. DALL-E: 256x256-1792x1024. GPT Image: 1024x1024/1024x1536/1536x1024/auto

quality
string

DALL-E: standard/hd. GPT Image: low/medium/high/auto

style
enum<string>

DALL-E only

Available options:
vivid,
natural
response_format
enum<string>
default:url

DALL-E only. GPT Image always returns b64_json

Available options:
url,
b64_json
aspect_ratio
string

Aspect ratio (Google models, see /v1/models for allowed values)

image_size
string

Output resolution: Imagen Standard/Ultra "1K"|"2K", Gemini 3 image "1K"|"2K"|"4K"

strength
number

How much an existing image steers the result. Clamped to the range the chosen model's own input schema declares and dropped entirely for a model that does not declare it, so on this endpoint it is silently inert almost everywhere rather than an error.

This is the image-EDIT parameter (POST /v1/images/edits), accepted here because both routes share one schema-grounded parameter gate. If you are editing an image, send it there instead — this endpoint takes no input image, so on almost every model there is nothing for it to steer.

Example:

0.35

person_generation
enum<string>

Person generation policy (Google models)

Available options:
dont_allow,
allow_adult,
allow_all
background
enum<string>

Background type (GPT Image models only)

Available options:
transparent,
opaque,
auto
output_format
enum<string>

Output file format (GPT Image models only)

Available options:
png,
webp,
jpeg
output_compression
integer

Compression 0-100 (GPT Image, jpeg/webp only)

input_fidelity
enum<string>

Match style of input images (GPT Image 1/1.5 only)

Available options:
high,
low
moderation
enum<string>

Content filter level (GPT Image only)

Available options:
auto,
low
negative_prompt
string

What to exclude from the image (Imagen 4)

seed
integer

Seed for reproducibility (Imagen 4)

steps
integer

Diffusion steps. Refused with 400 unless it is a whole number in 1–100 — this endpoint's own ceiling, checked before anything is billed, not the chosen model's (read that from GET /v1/models, and expect it to be far lower: FLUX defaults to 4).

It is a BILLING dimension on per-megapixel models, which is why the ceiling exists: the cost is megapixels × $/MP × max(1, steps ÷ the model's default steps), so asking for more steps than the default multiplies the price of the call rather than leaving it unchanged.

Only the Together path forwards it to a provider. On every other image source it still validates and still prices, but the image comes back rendered with the model's own step count.

Required range: 1 <= x <= 100
Example:

4

prompt_extend
boolean

Let the model rewrite the prompt before rendering. Read by the Alibaba/DashScope path only, which treats an absent value as true; every other image source ignores it.

It also SELECTS A PRICE on z-image-turbo, where prompt extension is the expensive mode: the credit hold and the settle look that model's rate up under extend, or under noextend when this is explicitly false. Sending false is how you ask for the cheaper rate.

Example:

false

Response

Without stream (the default) this is application/json — one result object, shown below.

With stream: true IN THE BODY it is text/event-stream instead: a sequence of data: <json>\n\n lines terminated by a literal data: [DONE]. OpenAPI 3.0 has no vocabulary for "repeat this, then terminate with a sentinel", so the text/event-stream schema below describes the JSON payload of a SINGLE data: line — never the whole body — which is the precedent chat/completions (PR #766) and music/generations (#819) set.

One schema rather than music’s three-member oneOf, because there is one frame shape here: status is a STATE, not a discriminant. Frames run queuedprocessing → a terminal completed or failed, and the images arrive on the completed frame’s data — there is no separate result frame after it.

Two things the stream does NOT carry, both of which the JSON body does. credits_used: settlement runs AFTER the stream is closed, so a streamed generation never reports what it cost in band — the x-request-id response header is what ties the call to its usage record. And file_id on an artifact: registering images as durable files belongs to the media-job path, which a streaming request never takes.

created
integer
required

Unix timestamp, in seconds, of when the result was produced.

Example:

1713204900

data
object[]
required

One entry per produced image, in the order the provider returned them.

credits_used
number
required

Credits actually settled for this request (1 credit = $0.01). May be fractional.

Example:

40