Skip to content

OpenAI Image Format

RouteAPI exposes image generation through the OpenAI-compatible images endpoints. This page covers the shared request envelope and the OpenAI gpt-image family — gpt-image-2 is the model on sale. Other vendors are adapted into the same endpoints; their model-specific behavior is documented separately: Nano Banana for Gemini image models, Seedream for ByteDance.

Whether a model can generate images is visible in the model list: its supported_endpoint_types contains image-generation. See Models for how to read that field.

POST /v1/images/generations
POST /v1/images/edits

Full URLs:

https://api.routeapi.ai/v1/images/generations
https://api.routeapi.ai/v1/images/edits

/v1/images/generations takes a JSON body. /v1/images/edits takes multipart/form-data — or, on OpenAI-compatible channels, a JSON body that references images by URL or Base64 (see JSON edits).

FieldTypeRequiredDescription
modelstringYesModel ID from GET /v1/models, for example gpt-image-2
promptstringYesText description of the image to generate
nintegerNoNumber of images, up to 128. Omitted or 0 is treated as 1
sizestringNoOutput size such as 1024x1024, 1024x1536, or a tier such as 1K / 2K, depending on the model. In a JSON body use x as the separator — a full-width × is rejected with 400
qualitystringNoQuality level such as standard, hd, high, medium, low, or auto. Accepted values depend on the model
response_formatstringNourl or b64_json. Forwarded upstream; which value a model honors is decided by the provider
stylestringNoStyle hint (for example vivid or natural). Only meaningful for models that accept it
userstringNoEnd-user identifier forwarded upstream
watermarkbooleanNoWhether to watermark the output, for providers that support it

Additional fields understood by the gateway include background, output_format, output_compression, input_fidelity, moderation, and partial_images; they are forwarded to OpenAI-compatible upstreams when present. Unknown JSON fields are dropped rather than forwarded, unless the channel is in request-body passthrough mode.

Terminal window
curl https://api.routeapi.ai/v1/images/generations \
-H "Authorization: Bearer $ROUTEAPI_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "gpt-image-2",
"prompt": "A calico cat playing a piano on a small stage, soft studio lighting",
"size": "1024x1024",
"n": 1
}'
import os
from openai import OpenAI
client = OpenAI(
api_key=os.environ["ROUTEAPI_KEY"],
base_url="https://api.routeapi.ai/v1",
)
result = client.images.generate(
model="gpt-image-2",
prompt="A calico cat playing a piano on a small stage, soft studio lighting",
size="1024x1024",
n=1,
)
for item in result.data:
print(item.url or item.b64_json[:40])

OpenAI-compatible channels return the upstream body as-is. Depending on the model, data[] carries b64_json, url, or both — read whichever is present.

{
"created": 1740000000,
"data": [
{
"b64_json": "iVBORw0KGgoAAAANSUhEUgAA..."
}
],
"usage": {
"input_tokens": 12,
"output_tokens": 4160,
"total_tokens": 4172
}
}
FieldDescription
createdUnix timestamp of the generation
dataArray of generated images, one entry per image
data[].urlImage URL, when the upstream returns URLs
data[].b64_jsonBase64-encoded image bytes, when the upstream returns Base64
data[].revised_promptRewritten prompt, if the model reports one
usageToken usage, present only when the upstream reports it

Use whichever of url / b64_json is present; do not assume both, and treat usage as optional when parsing.

POST /v1/images/edits changes an existing image using prompt and, optionally, a mask.

FieldTypeRequiredDescription
modelstringYesModel ID from GET /v1/models
imagefileYesThe source image. Repeat the field, or use image[], to send several
promptstringYesInstruction describing the edit
maskfileNoMask image marking the region to edit. Mask semantics are defined by the upstream model
nintegerNoNumber of results, up to 128 (defaults to 1)
sizestringNoOutput size, following the same rules as generation
qualitystringNoQuality level accepted by the model
watermarkbooleanNoWhether to watermark the output

Other form fields are forwarded unchanged to OpenAI-compatible upstreams, so parameters such as response_format or input_fidelity pass through.

Terminal window
curl https://api.routeapi.ai/v1/images/edits \
-H "Authorization: Bearer $ROUTEAPI_KEY" \
-F model="gpt-image-2" \
-F prompt="Replace the background with a sunset beach" \
-F image=@"cat.png" \
-F size="1024x1024"
import os
from openai import OpenAI
client = OpenAI(
api_key=os.environ["ROUTEAPI_KEY"],
base_url="https://api.routeapi.ai/v1",
)
with open("cat.png", "rb") as image:
result = client.images.edit(
model="gpt-image-2",
image=image,
prompt="Replace the background with a sunset beach",
size="1024x1024",
)
print(result.data[0].b64_json[:40])

On OpenAI-compatible channels, /v1/images/edits also accepts a JSON body. RouteAPI downloads or decodes each image reference and rebuilds a multipart request upstream — use this when your images already live at a URL or are Base64 strings.

Terminal window
curl https://api.routeapi.ai/v1/images/edits \
-H "Authorization: Bearer $ROUTEAPI_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "gpt-image-2",
"prompt": "Repaint this photo as a watercolor illustration",
"images": [
{ "image_url": "https://example.com/photo.png" }
],
"size": "1024x1024"
}'

Each entry in images may hold image_url (or url) as either an http(s) link or a data:image/...;base64,... string. mask uses the same shape. The images array is required on this path; a bare image field is not read for JSON edits. Other channel families may still expect a real multipart body, so test the target model before relying on JSON edits.

The endpoints and the prompt / n / size envelope are shared, but each vendor adaptor maps them differently.

Vendor familyPage
Google Gemini image models (gemini-*-image*)Nano Banana
ByteDance Seedream (seedream-5.0-pro, seedream-5.0-lite)Seedream

gpt-image models are billed by tokens: generated images count as output tokens at the output price, and the prompt and any reference images count as input tokens. Larger and higher-quality outputs consume more tokens. See Model Pricing for the full rules, and the model detail page to confirm which method applies.

On per-image models that use size tiers, the price is picked from the pixel count of the requested size before a channel is selected; n is billed per image, and an omitted or unrecognized size falls back to the highest unit price.

StatusMeaningTypical cause
400Invalid requestmodel missing, n above 128, unsupported size for the model, × used as the size separator in a JSON body
401Authentication failedMissing, invalid, expired, or exhausted API Key
403Balance or quota exhaustedinsufficient_user_quota or pre_consume_token_quota_failed; top up or raise the Key quota
429Rate limitedReduce concurrency
500Conversion or internal errorThe request could not be converted for the selected channel, or an edit had no usable image
501api_not_implementedEndpoint exists but is not supported

POST /v1/images/variations is not supported and returns 501 with code api_not_implemented; use a prompt-based edit instead. /v1/images/edits needs at least one image — image, image[], and image[0]-style form field names are all recognized.

  • Nano Banana — Gemini image models, including the native generateContent path.
  • Seedream — ByteDance Seedream sizes, sequential generation, and edits.
  • Models — find image models and confirm image-generation support.
  • Model Pricing — token vs per-image billing and size tiers.
  • Common Errors — shared status codes and error body format.