Nano Banana · Image
Synchronous call (Gemini protocol)NEW
📌 What is this:Generate an image synchronously via the native Gemini generateContent protocol — a single request returns the base64 image, no polling.
💡 When to use:Use when you want the result synchronously (no polling), or already use a Gemini SDK / generateContent client.
⚡ Synchronous call:This synchronous endpoint is offered in parallel with the async nano channel (POST /api/cqt/generator/nano). The public "Nano tier" is backed by Gemini image models; a single request returns the base64 image directly — no taskId, no polling. Besides Authorization: Bearer, x-goog-api-key is also accepted. Two request formats are supported: default JSON (native Gemini protocol, below) and multipart/form-data upload (upload reference image files directly for image-to-image — see the section further down).
Endpoints
| Usage | Method | Path |
|---|---|---|
| Synchronous call | POST | /v1beta/models/{model}:generateContent |
🔗 Protocol:Gemini generateContent protocol · a single request returns the result directly — no taskId, no polling
Request Parameters
| Param | Type | Required | Description |
|---|---|---|---|
| {model} | path | Required | Model id in the URL path (tier mapping): gemini-2.5-flash-image (Nano, 10, 1K) / gemini-3-pro-image-preview (Nano Pro, 20, 1K/2K/4K) / gemini-3.1-flash-image-preview (Nano 2, 20, 1K/2K/4K) |
| contents | array | Required | Native Gemini contents array; each item has role and parts[]. Text-to-image usually needs a single role="user" item. |
| contents[].role | string | — | Role; use "user" for image generation |
| contents[].parts[].text | string | Required | Text prompt describing the image to generate |
| contents[].parts[].inlineData | object | — | Reference image for image-to-image (inline base64): { "mimeType": "image/png", "data": "<base64>" }; omit for text-to-image. You can also pass a URL via fileData.fileUri below. |
| contents[].parts[].fileData.fileUri | string | — | https URL of a reference image for image-to-image (alternative to inline base64); the server downloads and inlines it. https only, up to 4 reference images; if any download fails the whole request errors and is not charged. |
| generationConfig | object | Required | Generation config object; see the sub-fields below |
| generationConfig.responseModalities | string[] | Required | Output modalities; must include "IMAGE" for image output (e.g. ["TEXT","IMAGE"]); omitting it returns text only |
| generationConfig.candidateCount | number | — | Number of images: 1-4, default 1. Charged per image (xN) and settled by the number of successful images (failures refunded) |
| generationConfig.imageConfig.imageSize | string | — | Resolution: 1K / 2K / 4K, default 1K (Nano is 1K only; Nano Pro / Nano 2 support 2K/4K) |
| generationConfig.imageConfig.aspectRatio | string | — | Output ratio: 1:1 / 16:9 / 9:16 / 4:3 / 3:4 / 3:2 / 2:3 / 5:4 / 4:5 / 21:9, default 1:1; follow the official Google imageConfig spec |
Request Example
curl -X POST https://api.cqtai.com/v1beta/models/gemini-2.5-flash-image:generateContent \
-H 'Authorization: Bearer <API_KEY>' \
-H 'Content-Type: application/json' \
-d '{
"contents": [{"role":"user","parts":[{"text":"a cute cat on a windowsill, soft morning light"}]}],
"generationConfig": {
"responseModalities": ["TEXT","IMAGE"],
"imageConfig": {"imageSize": "1K", "aspectRatio": "1:1"}
}
}'
# -> { "candidates": [{ "content": { "parts": [{ "inlineData": { "mimeType": "image/png", "data": "<base64>" } }] } }] }Response Example
{
"candidates": [
{
"content": {
"parts": [
{ "inlineData": { "mimeType": "image/png", "data": "<base64 PNG,原样透传>" } }
]
},
"finishReason": "STOP"
}
]
}multipart form upload (text-to-image / image-to-image)
The same non-stream generateContent endpoint branches by Content-Type: application/json uses the native Gemini protocol above, multipart/form-data uses this entry — upload reference images directly via the image file field for image-to-image (no base64 in JSON), or send only prompt for text-to-image. Image models + non-stream only; request body capped at 20MB (over → 413). Returns inline base64 by default; add the query param ?respFormat=url to return a CDN-link envelope instead. Billing is identical to the JSON path (settled by tier × number of successful images).
POST/v1beta/models/{model}:generateContentmultipart/form-data
| Param | Type | Required | Description |
|---|---|---|---|
| {model} | path | Required | Model id in the URL path (tier mapping): gemini-2.5-flash-image (Nano, 10, 1K) / gemini-3-pro-image-preview (Nano Pro, 20, 1K/2K/4K) / gemini-3.1-flash-image-preview (Nano 2, 20). model comes from the URL path only, never a form field. |
| prompt | string | Required | Text prompt: describes the image for text-to-image, or the edit instruction for image-to-image |
| image | file | — | Reference image file (for image-to-image). Repeat the field for up to 4 images: -F image=@a.png -F image=@b.png; omit for text-to-image. png / jpg / webp |
| n | number | — | Number of images, max 4 (maps to generationConfig.candidateCount), default 1; charged per image (xN) and settled by the number of successful images |
curl -X POST https://api.cqtai.com/v1beta/models/gemini-2.5-flash-image:generateContent \
-H 'Authorization: Bearer <API_KEY>' \
-F prompt='把这张图改成水彩风格' \
-F image=@input.png
# -> { "candidates": [{ "content": { "parts": [{ "inlineData": { "mimeType": "image/png", "data": "<base64>" } }] } }] }Billing & Credits
Nano (gemini-2.5-flash-image) 10/img; Nano Pro (gemini-3-pro-image-preview) 20/img; Nano 2 (gemini-3.1-flash-image-preview) 20/img. Multiple images are charged per image (candidateCount, xN) and settled by the number of successful images (failures refunded). (x your user rate). Auto-refunded on failure.