Skip to content
,

Gemini Image API Python Tutorial (2026): Nano Banana 2.1 Generation, Editing, Pricing and SynthID

8–12 minutes
Amazed woman in a lab coat in a greenhouse, Gemini logo card, hook $0.03 images nano banana api

Google’s Nano Banana image models can create and edit pictures straight from Python. You send a prompt, or a photo plus an instruction, and the Gemini API returns a finished image.

This guide covers the current model ids, real per-image prices, SynthID, editing, reference images and multi-turn edits. Every example uses the official google-genai SDK.

TLDR

  • Best default model: gemini-nano-banana-2.1 (Nano Banana 2.1), launched October 6, 2026.
  • Price: about $0.0336 per 1K image, $0.0504 at 2K and $0.113 at 4K. Batch halves that.
  • No free API tier: Google’s pricing page lists no free tier for any image model.
  • Watermark: every generated image carries an invisible SynthID watermark.
  • Editing: pass an image and a text instruction together. Use a chat for step-by-step edits.
  • Retiring: gemini-2.5-flash-image is deprecated. Move to a Gemini 3.1 or 2.1 model.

Current Gemini Image Model IDs

Google now sells several “Nano Banana” models. They differ in speed, price and features. Here is the line-up from the official image generation docs.

Model id Nickname Sizes Best for
gemini-nano-banana-2.1 Nano Banana 2.1 1K, 2K, 4K Default choice for new projects
gemini-3.1-flash-lite-image Nano Banana 2 Lite 1K only Fastest and cheapest, simple prompts
gemini-3.1-flash-image Nano Banana 2 512px, 1K, 2K, 4K Older projects, the only one with 512px
gemini-3-pro-image Nano Banana Pro 1K, 2K, 4K The most complex scenes and style references
gemini-2.5-flash-image Nano Banana (original) Up to 1024×1024 Legacy only, deprecated

Google’s docs say new projects should use Nano Banana 2.1 over Nano Banana 2. The Lite model trades features for speed: it has no Search grounding, no multi-reference tuning and no multi-turn tuning.

Note: The old Imagen models are shut down on the Gemini API. If your code still calls an imagen-4.0 model, switch to one of the ids above.

Price Per Image

Image output is billed by tokens, but Google converts that into a per-image price. These numbers are from the official Gemini API pricing page (standard tier).

Model 512px 1K 2K 4K Batch
Nano Banana 2.1 n/a $0.0336 $0.0504 $0.113 Half price ($0.0168 at 1K)
Nano Banana 2 Lite n/a $0.0336 n/a n/a $0.0168 at 1K
Nano Banana 2 $0.045 $0.067 $0.101 $0.151 Not listed
Nano Banana Pro n/a $0.134 $0.134 $0.24 Not listed
Nano Banana (2.5, legacy) n/a $0.039 n/a n/a $0.0195

On top of the image price, you pay a small amount for your text and image input and for thinking tokens. For Nano Banana 2.1, input is $1.50 and text or thinking output is $7.50 per million tokens.

Tip: 1,000 images at 1K on Nano Banana 2.1 cost about $33.60. If you do not need results right away, the Batch API cuts that to about $16.80.

For a wider view of Gemini costs, see my Gemini API pricing guide. To compare with OpenAI’s image models, read my ChatGPT Images 2.6 guide.

Setup in Five Minutes

  1. Create an API key. Sign in to Google AI Studio and create a key. Turn on billing, because image models are paid only.
  2. Install the SDK and Pillow. Run pip install -U google-genai pillow. The latest google-genai release is 3.2.0.
  3. Save the key as an environment variable. Set GEMINI_API_KEY. The client reads it automatically.
  4. Make an output folder. Create a folder such as images so your scripts have somewhere to save files.

If you have never used the SDK, start with my Gemini API Python tutorial. It covers keys, chat and streaming.

Generate Your First Image

Use generate_content with response_modalities=["IMAGE"]. The image comes back as a part with inline_data, and part.as_image() turns it into an image object you can save.

from google import genai
from google.genai import types

client = genai.Client()  # reads GEMINI_API_KEY

response = client.models.generate_content(
    model="gemini-nano-banana-2.1",
    contents="A cosy reading corner with a green armchair, warm lamp light, photo style",
    config=types.GenerateContentConfig(
        response_modalities=["IMAGE"],
    ),
)

for i, part in enumerate(response.parts):
    if part.inline_data:
        part.as_image().save(f"images/corner_{i}.png")
    elif part.text:
        print(part.text)

The loop matters. A response can mix text and image parts, so always check each part instead of assuming the first one is the picture.

Write better prompts

  • Describe the scene: say subject, setting, lighting and mood in full sentences, not a list of keywords.
  • Name the style: “studio product photo”, “flat vector icon” or “watercolour sketch” changes the result a lot.
  • Put text in quotes: if you want words on the image, write them exactly, such as a sign that says “OPEN”.
  • Say what to avoid: describe the clean result you want, such as “an empty street”, rather than a list of bans.

Aspect Ratio, Size and Thinking

Control the shape and resolution with types.ImageConfig. The default size is 1K.

config = types.GenerateContentConfig(
    response_modalities=["IMAGE"],
    image_config=types.ImageConfig(
        aspect_ratio="16:9",
        image_size="2K",   # "1K", "2K" or "4K" (uppercase K)
    ),
)
  • Common ratios: 1:1, 2:3, 3:2, 3:4, 4:3, 4:5, 5:4, 9:16, 16:9 and 21:9.
  • Sizes: 1K, 2K and 4K. 512px works only on gemini-3.1-flash-image, and the Lite model is 1K only.
  • Uppercase K: the docs say lowercase values such as “2k” are rejected.

Thinking levels

Gemini 3 image models always think before drawing, and you cannot switch that off. The model may draw up to two draft images internally, and the last one is your output.

You can change the depth. Nano Banana 2.1 accepts minimal, medium (default) or high. Nano Banana 2 and Lite accept minimal (default) or high. Thinking tokens are billed.

config = types.GenerateContentConfig(
    response_modalities=["IMAGE"],
    thinking_config=types.ThinkingConfig(thinking_level="high"),
)

Edit an Existing Image

To edit, send the image and your instruction in the same request. The SDK accepts a Pillow image directly in contents.

  1. Open the source image. Load it with Pillow.
  2. Write one clear change. For example, “Replace the sky with a sunset. Keep everything else the same.”
  3. Send both together. Put the text and the image in one contents list.
  4. Save the new version. Loop over the parts and save the image part.
from PIL import Image
from google import genai
from google.genai import types

client = genai.Client()
photo = Image.open("images/street.jpg")

response = client.models.generate_content(
    model="gemini-nano-banana-2.1",
    contents=[
        "Replace the grey sky with a warm sunset. Keep the buildings and people unchanged.",
        photo,
    ],
    config=types.GenerateContentConfig(response_modalities=["IMAGE"]),
)

for part in response.parts:
    if part.inline_data:
        part.as_image().save("images/street_sunset.png")

Tip: Always say what must stay the same. “Keep the face, pose and background unchanged” stops the model from redrawing parts you liked.

Use Several Reference Images

Nano Banana models can blend up to 14 reference images in one request. Limits depend on the model and on the type of image.

Model Object images Character images Style references
Nano Banana 2.1 and Nano Banana 2 Up to 10 Up to 4 Not listed
Nano Banana Pro Up to 6 Up to 5 Up to 3
Nano Banana 2 Lite Up to 14 None Not listed
model_photo = Image.open("images/model.png")
jacket = Image.open("images/jacket.png")
shoes = Image.open("images/shoes.png")

response = client.models.generate_content(
    model="gemini-nano-banana-2.1",
    contents=[
        "Show the person from the first image wearing the jacket and shoes, "
        "standing in a bright studio. Full body, catalogue photo.",
        model_photo, jacket, shoes,
    ],
    config=types.GenerateContentConfig(
        response_modalities=["IMAGE"],
        image_config=types.ImageConfig(aspect_ratio="3:4"),
    ),
)

Refer to images by their order (“the first image”, “the second image”). That makes it clear which picture is the person and which are the products.

Multi-Turn Editing with Chat

Real editing is usually a series of small changes. A chat session keeps the history, so each new message edits the latest image instead of starting over.

chat = client.chats.create(
    model="gemini-nano-banana-2.1",
    config=types.GenerateContentConfig(response_modalities=["TEXT", "IMAGE"]),
)

steps = [
    "Create a simple flat logo of a fox reading a book, orange and white.",
    "Make the background dark green.",
    "Add the word FOXREAD under the fox in a bold sans-serif font.",
]

for n, prompt in enumerate(steps, start=1):
    reply = chat.send_message(prompt)
    for part in reply.parts:
        if part.inline_data:
            part.as_image().save(f"images/logo_step{n}.png")
        elif part.text:
            print(n, part.text)

Saving every step lets you go back if a later edit goes wrong. Keep each message to one change for the most predictable results.

Note: Google says the Lite model is not tuned for multi-turn editing. Use Nano Banana 2.1 or Pro for long edit chains.

Interactions API Version

Google’s own image docs now show the newer Interactions API first. It returns the image as base64 in output_image, and it links edit turns with previous_interaction_id.

import base64
from google import genai

client = genai.Client()

first = client.interactions.create(
    model="gemini-nano-banana-2.1",
    input="An infographic about drinking water, simple icons, English labels",
    response_modalities=["IMAGE"],
)
with open("images/water_en.png", "wb") as f:
    f.write(base64.b64decode(first.output_image.data))

second = client.interactions.create(
    model="gemini-nano-banana-2.1",
    input="Translate all labels into Spanish. Keep the layout.",
    response_modalities=["IMAGE"],
    previous_interaction_id=first.id,
)
with open("images/water_es.png", "wb") as f:
    f.write(base64.b64decode(second.output_image.data))

If a reply mixes text and images, loop over interaction.steps instead. Google notes that the output_image shortcut does not capture every part of mixed output.

Grounding with Google Search

Nano Banana 2.1 and Nano Banana 2 can use the Google Search tool, so a prompt like “today’s weather in Paris as a poster” uses live data. Image Search grounding is also available on those two models.

The first 5,000 grounded requests per month are free, then it costs $14 per 1,000. The Lite model does not support grounding.

SynthID and Responsible Use

Google’s docs state that all generated images include a SynthID watermark. Google designs it to be invisible to the eye, so tools can later check that an image was made with Google AI.

  • You cannot turn it off: there is no API setting to remove SynthID.
  • Label AI images: it is still good practice to tell readers when an image is AI generated.
  • People controls: types.ImageConfig has a person_generation field for limiting images of people.
  • Safety filters: some prompts are blocked. Rephrase them in neutral words if you get no image back.

Other providers watermark too. My Grok Imagine API guide shows how xAI handles it.

Troubleshooting: Common Problems and Fixes

  • Response has text but no image: add response_modalities=["IMAGE"], or make the prompt clearly ask for a picture. Also check for a safety block in response.candidates[0].finish_reason.
  • 400 error on image_size: use an uppercase K, such as “2K”. Also check the model supports that size, since Lite is 1K only.
  • 403 or billing error: image models have no free API tier. Turn on billing for the project that owns your key.
  • 404 model not found: check the exact id, for example gemini-nano-banana-2.1. Imagen ids no longer work.
  • Edits change too much: list what must stay the same, and make one change per message.
  • Characters look different each time: pass the same character reference images in every request, and keep within the character limit for your model.
  • 429 RESOURCE_EXHAUSTED: you hit a rate limit. Slow down, retry with backoff, or use Batch. My Gemini API errors guide has retry code.
  • output_image is empty in Interactions: the reply was mixed. Loop over interaction.steps to find the image.

Frequently Asked Questions

What is the best Gemini image model right now?

For most new projects, Google recommends gemini-nano-banana-2.1. Use Nano Banana Pro for the most complex scenes and the Lite model for cheap, fast 1K images.

How much does one Gemini image cost?

Nano Banana 2.1 costs about $0.0336 for a 1K image, $0.0504 at 2K and $0.113 at 4K. The Batch API halves those prices.

Is the Gemini image API free?

No. Google’s pricing page lists no free API tier for any image model, so you need billing turned on.

Can I remove the SynthID watermark?

No. Google says all generated images include SynthID, and the API has no option to disable it.

How many images can I use as references?

Up to 14 in total. Nano Banana 2.1 allows up to 10 object images and up to 4 character images.

Is gemini-2.5-flash-image still available?

Treat it as retired. Google’s pricing page marks it deprecated with a shutdown date of October 2, 2026, and recommends Gemini 3.1 Flash Image or the Lite model instead.

Can I generate images with gemini-3.8-flash?

No. Use one of the image model ids, such as Nano Banana 2.1. The text models return text, not pictures.

Sources

Free weekly email

Get new AI guides every week

One short weekly email with our newest local AI, ComfyUI and AI tool guides. No spam, no pop-ups, just the good stuff.

Free. Unsubscribe anytime in one click. We only use your email to send this newsletter. See our privacy policy.

Amazed woman in a lab coat in a greenhouse, Gemini logo card, hook $0.03 images nano banana api