Language
Inference Space Docs

Nano Banana Image Generation and Editing

Inference Space Nano Banana (Gemini image generation) series text-to-image and image-to-image API, centered on the native Google generateContent protocol, compatible with OpenAI Images, with unified asynchronous jobs and per-image billing.

Nano Banana is Inference Space's integration of the Gemini image series. It includes Nano Banana 2 (Small Banana, fast), Nano Banana Pro (Big Banana, quality-first), and Nano Banana 2 Lite (Small Banana Lite, ultra-fast and low-cost). All three models support text-to-image generation and reference-image editing.

Parameters and capabilities align with Google's official Gemini image documentation: Gemini 3.1 Flash Lite Image and Image generation · Aspect ratios and image sizes.

The gateway provides two equivalent protocols, with the native Google protocol as the primary interface:

  • Native Google (recommended): POST /v1beta/models/{model}:generateContent, directly compatible with the google-genai SDK and Gemini-compatible tools.
  • OpenAI-compatible: POST /v1/images/generations and /v1/images/edits, allowing existing OpenAI image clients to connect without code changes.
  • Asynchronous jobs: POST /api/jobs; use asynchronous submission and polling for long-running jobs (4K / multi-image fusion). gpt-image-2 and Gemini share the same asynchronous protocol.

Authentication, routing, and billing are identical across all three interfaces. The gateway adapts them to the underlying Gemini contract, so callers do not need to know the underlying protocol.

Authentication and Base

  • API Base: https://ai.inf.space (the browser console and API share this host; use the documented API path)
  • Authentication header: Authorization: Bearer $AI_TOS_API_KEY

Create an API Key in the console. In production, keep the Key on the server and do not expose it in the browser. Authentication and Base are identical to gpt-image-2.

Choosing a model

All three models support every interface; only the model field differs. Choose according to the scenario:

Nano Banana 2 (Small Banana)Nano Banana Pro (Big Banana)Nano Banana 2 Lite (Small Banana Lite)
modelgemini-3.1-flash-imagegemini-3-pro-imagegemini-3.1-flash-lite-image
PositioningSpeed-firstQuality-firstUltra-fast / low-cost
Typical scenariosQuick previews, batch drafts, everyday lightweight generationComplex compositions, commercial posters, and work requiring more consistent detailHigh-concurrency real-time interaction, stickers / recoloring / background changes, and other lightweight editing
Quality tiers1K / 2K / 4K1K / 2K / 4K1K only (enforced by the gateway; higher tiers are ignored)
BillingPer image, same price at every sizePer image, same price at every sizePer image
LatencyLowerHigherLowest (official target below 2s)

Use Small Banana when speed and batch generation matter; use Big Banana for quality and complex commercial layouts; use Small Banana Lite for high-concurrency real-time scenarios requiring the lowest latency and lowest unit price (stickers, recoloring, background changes, and other lightweight edits). All three models are billed per image, independent of size tier; Lite outputs 1K only.

Native Google protocol (generateContent)

The native Google Generative Language (Gemini) protocol is the preferred interface for this series. Point the Base URL of the google-genai SDK or any Gemini-compatible tool to https://ai.inf.space.

  • Text-to-image / image editing: POST https://ai.inf.space/v1beta/models/{model}:generateContent
  • Model list: GET https://ai.inf.space/v1beta/models

Text-to-image

curl "https://ai.inf.space/v1beta/models/gemini-3.1-flash-image:generateContent" \
  -H "Authorization: Bearer $AI_TOS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "contents": [{ "parts": [{ "text": "A seaside café terrace at sunset, warm tones, cinematic landscape composition" }] }],
    "generationConfig": {
      "responseModalities": ["IMAGE"],
      "imageConfig": { "aspectRatio": "16:9", "imageSize": "2K" }
    }
  }'

The image is in candidates[0].content.parts[].inlineData.data (raw base64):

{
  "candidates": [
    { "content": { "role": "model", "parts": [
      { "inlineData": { "mimeType": "image/png", "data": "iVBORw0KGgo..." } }
    ] } }
  ],
  "usageMetadata": { "totalTokenCount": 1290 }
}

For Big Banana, replace gemini-3.1-flash-image with gemini-3-pro-image; everything else is unchanged. For Small Banana Lite, replace it with gemini-3.1-flash-lite-image; imageSize supports 1K only, and higher tiers are forced back to 1K.

Image-to-image and image editing

Place the reference image in an inlineData part inside contents[].parts and submit it together with the text. For multi-image fusion, include multiple inlineData parts and refer to them in prompt order as “image 1 / image 2” (up to 6 images, each ≤ 20 MB, in png/jpeg/webp format):

curl "https://ai.inf.space/v1beta/models/gemini-3-pro-image:generateContent" \
  -H "Authorization: Bearer $AI_TOS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "contents": [{ "parts": [
      { "inlineData": { "mimeType": "image/png", "data": "'"$(base64 -i banana.png)'" } },
      { "text": "Add a small straw party hat to the top of the banana and keep everything else unchanged" }
    ] }],
    "generationConfig": { "responseModalities": ["IMAGE"], "imageConfig": { "aspectRatio": "1:1", "imageSize": "1K" } }
  }'

Image editing does not require a mask. For mask-based local redrawing, use gpt-image-2.

Sizes and aspect ratios

The Gemini series supports only discrete aspect ratios and quality tiers; it does not provide an arbitrary widthxheight pixel contract. First choose an available aspect ratio for the model, then choose 1K / 2K / 4K. Supported aspect ratios vary by model (data aligned with the official Google documentation):

ModelSupported aspectRatioQuality tiers
gemini-3.1-flash-image (Small Banana)1:1, 2:3, 3:2, 3:4, 4:3, 4:5, 5:4, 9:16, 16:9, 21:9, 1:4, 4:1, 1:8, 8:11K / 2K / 4K
gemini-3-pro-image (Big Banana)1:1, 2:3, 3:2, 3:4, 4:3, 4:5, 5:4, 9:16, 16:9, 21:91K / 2K / 4K
gemini-3.1-flash-lite-image (Small Banana Lite)1:1, 2:3, 3:2, 3:4, 4:3, 4:5, 5:4, 9:16, 16:9, 21:91K only
  • The native ratio field is imageConfig.aspectRatio; the OpenAI-compatible interface uses the extension aspectRatio. The default is 1:1.
  • The native quality field is imageConfig.imageSize; the OpenAI-compatible interface uses size: 1K / 2K / 4K. Small Banana Lite outputs 1K only; the gateway forces higher tiers back to 1K.
  • Only Small Banana supports the ultra-wide / ultra-tall banner ratios (1:4, 4:1, 1:8, 8:1). Big Banana and Small Banana Lite do not support these four ratios; an unsupported value may be rejected by the upstream or fall back to the nearest ratio.

The following are reference pixel dimensions for each tier while preserving the aspect ratio (aligned with the official documentation; actual output governs):

aspectRatio1K2K4K
1:11024×10242048×20484096×4096
2:3848×12641696×25283392×5056
3:21264×8482528×16965056×3392
3:4896×12001792×24003584×4800
4:31200×8962400×17924800×3584
4:5928×11521856×23043712×4608
5:41152×9282304×18564608×3712
9:16768×13761536×27523072×5504
16:91376×7682752×15365504×3072
21:91584×6723168×13446336×2688
1:4 (Small Banana only)512×20481024×40962048×8192
4:1 (Small Banana only)2048×5124096×10248192×2048
1:8 (Small Banana only)384×3072768×61441536×12288
8:1 (Small Banana only)3072×3846144×76812288×1536
  • The table shows official reference pixels. Different interfaces and upstream providers may return slightly different pixels while preserving the aspect ratio; a 1K landscape image is not guaranteed to be exactly 1024 pixels wide.

When you need a reproducible fixed pixel size, use gpt-image-2 and send one of the recommended widthxheight values directly. Gemini is better suited to generation by composition ratio and quality tier.

Billing depends only on the model, not the size—1K / 2K / 4K cost the same. 4K generation is slower and more likely to encounter upstream congestion. Start with 1K while refining prompts, use 2K for production delivery, and use the Asynchronous Jobs API for long-running jobs.

Asynchronous Jobs API (/api/jobs)

For long-running generation such as 4K and multi-image fusion, use asynchronous jobs: submit once to receive a job ID, then poll for the result so long-lived connections are not interrupted by releases or timeouts.

This asynchronous protocol is fully unified between Gemini and gpt-image-2—submission, polling, and cancellation endpoints and response structures are identical. Only the generation request body differs at submission time (Gemini uses contents; OpenAI uses prompt). Job status follows the five states in the ComfyUI contract: pending → in_progress → completed | failed | cancelled (after the retention period, expired).

Submission

POST https://ai.inf.space/api/jobs. A native Gemini body must include model at the top level because the asynchronous endpoint URL does not contain a model segment:

# Native Gemini shape
curl "https://ai.inf.space/api/jobs" \
  -H "Authorization: Bearer $AI_TOS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gemini-3-pro-image",
    "contents": [{ "parts": [{ "text": "A cyberpunk city at night, 4K cinematic quality" }] }],
    "generationConfig": { "imageConfig": { "aspectRatio": "16:9", "imageSize": "4K" } }
  }'
# OpenAI shape (same for gpt-image-2; only model differs)
curl "https://ai.inf.space/api/jobs" \
  -H "Authorization: Bearer $AI_TOS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "model": "gpt-image-2", "prompt": "A cyberpunk city at night", "size": "4K", "aspectRatio": "16:9" }'

For image-to-image or fusion, use multipart/form-data with reference images uploaded as image[], or place inlineData parts in contents in the native Gemini body.

Submission returns a job object:

{
  "id": "b1a2c3...",
  "status": "pending",
  "model": "gemini-3-pro-image",
  "create_time": 1751540000000,
  "progress": 5,
  "progress_message": "Queued",
  "outputs_count": 0,
  "outputs": [],
  "execution_error": null
}

Polling

GET https://ai.inf.space/api/jobs/{id}. When complete, outputs contains downloadable URLs rather than inline base64:

{
  "id": "b1a2c3...",
  "status": "completed",
  "progress": 100,
  "outputs_count": 1,
  "outputs": [{ "url": "https://ai.inf.space/api/files/serve/generated/xxx.png", "mime_type": "image/png" }],
  "execution_error": null
}

When a job fails, status is "failed", and the top-level execution_error contains the actual error, including provider-side safety rejections:

{
  "id": "b1a2c3...",
  "status": "failed",
  "execution_error": { "type": "image_unsafe", "message": "content rejected by provider", "provider": "adobe-gemini" }
}

Cancellation

POST https://ai.inf.space/api/jobs/{id}/cancel is idempotent: queued jobs are cancelled immediately, running jobs are stopped on a best-effort basis (if an image has already been generated, the job is still considered complete), and terminal jobs or unknown IDs are no-ops.

{ "cancelled": true }

Bulk cancellation: POST /api/jobs/cancel, with a body of { "job_ids": ["id1", "id2"] }.

Listing

GET https://ai.inf.space/api/jobs?limit=20&offset=0{ "jobs": [...], "pagination": { "offset": 0, "limit": 20, "has_more": false } }.

Job records and results are retained for 7 days; after expiration, polling returns status:"expired". The synchronous interface remains suitable for short-running real-time generation (1K / 2K); use asynchronous jobs for long-running generation.

OpenAI-compatible protocol (/v1/images/*)

Existing OpenAI image clients can connect without code changes by switching only the Base, Key, and model.

  • Text-to-image: POST https://ai.inf.space/v1/images/generations, application/json.
  • Image-to-image / editing: POST https://ai.inf.space/v1/images/edits, multipart/form-data (image / repeated image[]), or JSON with input_images (public URL / data URL / base64).
curl "https://ai.inf.space/v1/images/generations" \
  -H "Authorization: Bearer $AI_TOS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "model": "gemini-3.1-flash-image", "prompt": "A seaside café terrace, cinematic landscape", "size": "2K", "aspectRatio": "16:9" }'

The response uses the standard OpenAI shape, with the image in data[0].b64_json (raw base64):

{ "created": 1717488000, "data": [{ "b64_json": "/9j/4AAQSkZJRg..." }], "usage": { "generated_images": 1 } }

The gateway forwards only the parameters it actually supports (model / prompt / size / extension aspectRatio, plus image / image[] / input_images for edits); other OpenAI parameters are silently ignored. The synchronous interface has no caller-facing streaming and always returns one complete JSON response.

Differences from gpt-image-2 / selection guidance

Nano Banana (Gemini)gpt-image-2
Preferred protocolNative Google generateContentOpenAI Images
Asynchronous protocolUnified /api/jobsUnified /api/jobs (same protocol)
modelgemini-3.1-flash-image / gemini-3-pro-image / gemini-3.1-flash-lite-imagegpt-image-2
Size controlDiscrete aspect ratios + tiersExplicit widthxheight is recommended; final size is aligned to provider capabilities, so validate returned pixels
BillingPer image, independent of sizeSize × quality tier
Mask-based local redrawingUnsupportedSupported

Selection guidance:

  • For speed and batch drafts → Small Banana gemini-3.1-flash-image.
  • For quality, complex compositions, and commercial posters → Big Banana gemini-3-pro-image.
  • For high-concurrency real-time interaction with the lowest latency and unit price, and lightweight edits (stickers / recoloring / background changes) → Small Banana Lite gemini-3.1-flash-lite-image (1K only).
  • For precise pixel dimensions or mask-based local redrawing → prefer gpt-image-2.
  • For ultra-wide / ultra-tall banners (1:4, 4:1, 1:8, 8:1) → only Small Banana gemini-3.1-flash-image supports them.
  • For long-running jobs (4K / multi-image fusion) → use the Asynchronous Jobs API.

Pricing

All three models are billed per image at the same price for each size (1K / 2K / 4K); Small Banana Lite outputs 1K only and has a lower unit price. For exact prices, billing rules, and organization-specific pricing, see the Pricing and billing page and the console.

On this page