Skip to main content
POST
Edit an existing image
Models like Nano Banana (Gemini Image) support edits — provide a source image + prompt.
This endpoint takes JSON with a base64 image, not multipart/form-data. The OpenAI SDK’s client.images.edit(...) sends multipart and will not work against it — call it over plain HTTP as below.
image_mime_type defaults to image/png. An optional mask_base64 (transparent = the region to repaint) enables in-painting where the model supports a mask.

Sample output

Source image before edit

Source image — autumn Japanese garden

Image after edit

Edited: 'Transform this into a snowy winter wonderland — keep the layout intact.' (nano-banana)

Image-edit output format matches image generation.

Supported models

Image-edit capability is model-dependent, and it is decided per source rather than per model: a request routed to a source that takes no input image is refused with 400 edit_not_supported before anything is billed. See Models catalog for which models edit.

Authorizations

Authorization
string
header
required

API key in format: Bearer inf_***

Body

application/json
model
string
required
prompt
string
required

Edit instruction

image_base64
string
required

Base64-encoded source image

image_mime_type
string
default:image/png
mask_base64
string

Base64-encoded mask (transparent area = edit region)

mask_mime_type
string
default:image/png
n
integer
default:1
size
string

Must be one of the sizes the chosen model declares (GET /v1/models). Refused with 400 otherwise.

Example:

"1024x1024"

quality
string

Output quality. Checked against the chosen model's own input schema — refused with 400 when that schema is the provider's own and the value is not in it, snapped for a synthesized schema, and dropped for a model that declares no quality at all. OpenAI's standard/hd and GPT Image's low/medium/high/auto are two such sets among many; read the one that applies from GET /v1/models.

What it does on THIS endpoint is select a price, not a rendering: the credit hold and the settle look the image price up by quality, and no edit path forwards the value to a provider (OpenAI's edit is a multipart form that omits it; the FAL and Replicate input mappers exclude it). On POST /v1/images/generations it reaches the provider and changes the image. Declared here because the endpoint accepts, validates and bills on it.

Example:

"high"

aspect_ratio
string

Aspect ratio of the edited image. Honoured by every edit-capable provider that has a field for it — Google Imagen (aspectRatio), Replicate and FAL — and dropped for a model that has none. For a model with a stored input schema the value is checked against that schema's own enum and refused with 400 if it is not a member, so read the allowed set from GET /v1/models rather than assuming a fixed list.

Example:

"16:9"

strength
number

How much the source image steers the result — lower keeps more of the original, higher follows the prompt more freely. Clamped to the range the chosen model's own input schema declares (0–1 on every model that exposes it today) and dropped entirely for a model that does not, so it is silently inert rather than an error on the models that ignore it.

REQUIRED by some models and absent from most: luma-photon-modify and luma-photon-flash-modify will not run an edit without it. It is not marked required here because this one operation is shared by every edit-capable model, the large majority of which neither need nor accept it — check the chosen model's schema in GET /v1/models.

Example:

0.35

image_size
string

Output resolution for the models that size their output by label rather than by pixels (Imagen Standard/Ultra 1K|2K, Gemini 3 image 1K|2K|4K) — the same field POST /v1/images/generations takes. Checked against the chosen model's own input schema and dropped for a model that does not declare it.

Unlike quality above it is carried through on the edit paths that have a field for it (Gemini as imageSize, xAI as resolution). It is also a BILLING dimension: with no size sent, this is what the image price is looked up by.

Example:

"2K"

style
string

Style hint. Checked against the chosen model's own input schema — refused with 400 when that schema is the provider's own and the value is not in it, and dropped for a model that declares no style. Read the allowed set from GET /v1/models rather than assuming DALL-E's vivid/natural.

INERT on this endpoint, like quality: no edit path forwards it to a provider. Declared because the endpoint accepts and validates it — sending an unacceptable value is a 400 you would otherwise meet without warning.

Example:

"natural"

background
string

Background treatment — GPT Image's transparent/opaque/auto is one model family's set, not this endpoint's. Checked against the chosen model's own input schema and dropped for a model that declares no background. INERT here for the same reason as style above: no edit path forwards it. On POST /v1/images/generations it does reach GPT Image and change the result.

Example:

"transparent"

person_generation
enum<string>

Person-generation policy. Accepted and validated here — any other value is refused with 400 — but unlike POST /v1/images/generations, no edit-capable provider currently forwards it upstream, so on this endpoint it constrains what you may send without changing what you get back.

Available options:
dont_allow,
allow_adult,
allow_all
response_format
enum<string>
default:url
Available options:
url,
b64_json
steps
integer

Diffusion steps. Validated and priced here exactly as on POST /v1/images/generations — a whole number in 1–100 or a 400, and on a per-megapixel model the price is multiplied by max(1, steps ÷ the model's default steps).

INERT as a rendering control on this endpoint, like quality and style above: no edit path forwards it to a provider. Declared because sending an out-of-range value is a 400, and sending an in-range one can raise what the edit costs.

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

4

prompt_extend
boolean

Prompt rewriting. Reaches no provider from this endpoint — the edit request object has no such field — but it is read by the shared price-parameter builder, which uses it to pick z-image-turbo's extend (absent or true) or noextend (false) rate. So on this route it selects a price and nothing else.

Example:

false

Response

Image edit result

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