Nano Banana (Gemini Image Models)
Gemini image models on sale: gemini-3.1-flash-image-preview, gemini-3-pro-image-preview, and gemini-3.1-flash-lite-image. They are image-generation models served by Gemini channels, and there are two ways to reach them (check supported_endpoint_types in Models for the exact list on each model):
| Path | Endpoint | Request body you send |
|---|---|---|
| OpenAI image format | POST /v1/images/generations | OpenAI image JSON, described on OpenAI Image Format |
| Native Gemini | POST /v1beta/models/{model}:generateContent | Gemini contents + generationConfig |
Use the native path when you already speak the Gemini protocol (Google GenAI SDK) and need full control over responseModalities and imageConfig; use /v1/images/generations when your client only speaks the OpenAI image API.
Through /v1/images/generations
Section titled “Through /v1/images/generations”The envelope, authentication, and error body are the same as OpenAI Image Format. RouteAPI converts your image request into a Gemini generateContent call.
Request parameters
Section titled “Request parameters”| Field | Type | Required | Description |
|---|---|---|---|
model | string | Yes | Gemini image model ID such as gemini-3.1-flash-image-preview |
prompt | string | Yes | Sent as a single text part in a user turn |
size | string | No | Mapped to generationConfig.imageConfig.aspectRatio (see the table below) |
n | integer | No | Values greater than 1 are sent as generationConfig.candidateCount; 1 or omitted sends nothing |
quality, response_format, style, user, watermark | — | No | Not converted on this path; they are ignored by the Gemini adaptor |
RouteAPI fills responseModalities with ["TEXT", "IMAGE"] itself, so you do not pass it through this endpoint. Safety settings are applied from the platform’s Gemini settings.
Size to aspect ratio
Section titled “Size to aspect ratio”Only these exact size values map to an aspect ratio:
size | aspectRatio |
|---|---|
256x256, 512x512, 1024x1024 | 1:1 |
1536x1024 | 3:2 |
1024x1536 | 2:3 |
1024x1792 | 9:16 |
1792x1024 | 16:9 |
A value that already contains : is passed through as an aspect ratio. Anything else (for example 2K or auto) sends no imageConfig at all, and the upstream default applies. Pixel dimensions are not requested on this path — the ratio is the only size control.
Request example
Section titled “Request example”curl https://api.routeapi.ai/v1/images/generations \ -H "Authorization: Bearer $ROUTEAPI_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "gemini-3.1-flash-image-preview", "prompt": "A nano banana wearing sunglasses, studio product shot", "size": "1536x1024" }'Response
Section titled “Response”The response is converted to the OpenAI image object; only inline image parts survive, and any text the model returns is dropped.
{ "created": 1740000000, "data": [ { "b64_json": "iVBORw0KGgoAAAANSUhEUgAA..." } ]}URLs are not produced on this path — always read data[].b64_json. If the response contains no image part, the request fails with 500; if Gemini blocks the prompt, it fails with 400 and the block reason is recorded against the request.
Natively with generateContent
Section titled “Natively with generateContent”POST /v1beta/models/{model}:generateContentPOST /v1beta/models/{model}:streamGenerateContent?alt=sseExample:
curl https://api.routeapi.ai/v1beta/models/gemini-3-pro-image-preview:generateContent \ -H "x-goog-api-key: $ROUTEAPI_KEY" \ -H "Content-Type: application/json" \ -d '{ "contents": [ { "role": "user", "parts": [{ "text": "Draw a cat astronaut on the moon" }] } ], "generationConfig": { "responseModalities": ["TEXT", "IMAGE"], "imageConfig": { "aspectRatio": "16:9", "imageSize": "2K" } } }'Request fields
Section titled “Request fields”| Field | Type | Required | Description |
|---|---|---|---|
contents | array | Yes | Gemini conversation content; at least one entry. Roles are user and model |
generationConfig.responseModalities | array of string | Yes in practice | Must include IMAGE, otherwise the model answers with text only |
generationConfig.imageConfig | object | No | Image options, passed through to Gemini. aspectRatio such as 1:1, 3:2, 16:9; imageSize such as 1K, 2K, 4K. Accepted values depend on the model |
generationConfig.candidateCount | integer | No | Number of candidates; not supported by every image model |
safetySettings | array | No | Gemini safety settings, forwarded as-is |
systemInstruction | object | No | System instruction; the snake_case system_instruction is accepted too |
generationConfig accepts both camelCase and snake_case spellings of its fields (for example responseModalities / response_modalities and imageConfig / image_config); if both are present, snake_case wins. imageConfig and its contents are passed through without validation, so an unsupported imageSize is reported by Gemini, not by RouteAPI.
Image input
Section titled “Image input”To edit or reference an image, add an inline image part next to the text:
{ "contents": [ { "role": "user", "parts": [ { "text": "Repaint this photo as a watercolor illustration" }, { "inlineData": { "mimeType": "image/png", "data": "iVBORw0KGgoAAAANSUhEUgAA..." } } ] } ], "generationConfig": { "responseModalities": ["TEXT", "IMAGE"] }}inlineData carries Base64 image bytes; it is forwarded to Gemini unchanged. For files already uploaded to Google, the native fileData.fileUri part is also part of the forwarded request shape. If your client speaks the OpenAI chat format instead, image_url content parts are downloaded server-side and converted to inline parts before reaching Gemini.
Streaming
Section titled “Streaming”Streaming is selected by the ?alt=sse query parameter, not by the action name: with it, the upstream action becomes streamGenerateContent and the response is a stream of Gemini server-sent events. Each chunk has the standard candidates[].content.parts structure. Use it when you want the image to arrive incrementally; otherwise :generateContent returns the whole response in one body.
Response
Section titled “Response”The native path returns Gemini’s own response shape unchanged:
{ "candidates": [ { "content": { "role": "model", "parts": [ { "text": "Here is the image." }, { "inlineData": { "mimeType": "image/png", "data": "iVBORw0KGgoAAAANSUhEUgAA..." } } ] }, "finishReason": "STOP" } ], "usageMetadata": { "promptTokenCount": 12, "candidatesTokenCount": 1120, "totalTokenCount": 1132 }}Read the image from parts[].inlineData; text parts usually accompany it. When Gemini blocks the request, promptFeedback.blockReason is set and candidates is empty.
Billing
Section titled “Billing”Gemini image models are billed by tokens: generated images count as output tokens at the output price, and the prompt and reference images count as input tokens. See Model Pricing and the model detail page for the current rates.
Next steps
Section titled “Next steps”- OpenAI Image Format — the shared
/v1/imagesenvelope and edit behavior. - Seedream — ByteDance Seedream sizes and edit semantics.
- Models — find image models and confirm
image-generationsupport. - Model Pricing — token vs per-image billing.