Claude Opus 5.5 is live on SeedRouter
LogoSeedRouter

Search models by name, e.g. 'nano banana'

Search models by name, e.g. 'nano banana'

Image

Nano Banana 2.1 (Gemini Nano Banana 2.1)

View Markdown

Generate and edit images with Nano Banana 2.1 through one async endpoint using Google's generateContent body: 1K to 4K, thinking levels, 14 reference images.

Nano Banana 2.1 is Google's gemini-nano-banana-2.1 image model, the update to Nano Banana 2. Send Google's generateContent request body with a model field, keep the returned task ID, and check that task for the finished image. Reference images go in contents as fileData URLs.

Model IDs

Model IDBilling
gemini-nano-banana-2.1One flat price per delivered image, at every size

See the model page for the current price.

Quick example

curl https://api.seedrouter.ai/v1/images/generations \
  -H "Authorization: Bearer $SEEDROUTER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gemini-nano-banana-2.1",
    "contents": [{"parts": [{"text": "A ceramic teapot on a linen tablecloth, soft window light"}]}],
    "generationConfig": {
      "responseModalities": ["IMAGE"],
      "imageConfig": {"aspectRatio": "16:9", "imageSize": "2K"}
    }
  }'

Endpoint

POST https://api.seedrouter.ai/v1/images/generations
HeaderValue
AuthorizationBearer YOUR_API_KEY
Content-Typeapplication/json

The body is Google's generateContent request with one addition: model, because this endpoint carries no model in its path. The response contains a task ID, not the finished image. Keep API keys in server-side code. Calling /v1beta/models/...:generateContent directly is not supported; use this endpoint.

Parameters

NameTypeRequiredDefaultNotes
modelstringYes—gemini-nano-banana-2.1.
contentsContent[]Yes—1–32 turns. Each has parts and an optional role (user or model); the last turn is user.
contents[].parts[].textstring——A text part. At least one text part is required.
contents[].parts[].fileDataobjectNo—{"mimeType": "...", "fileUri": "https://..."}; an image, video, or PDF reference. Up to 14 in total.
systemInstructionobjectNo—{"parts": [{"text": "..."}]}.
safetySettingsobject[]No—{"category", "threshold"} pairs; see below.
toolsobject[]No—[{"googleSearch": {}}] for web search, or {"googleSearch": {"searchTypes": {"webSearch": {}, "imageSearch": {}}}} with either or both types. Grounds the image in live search results; the price per image does not change.
generationConfig.responseModalitiesenum[]Notext and image["IMAGE"] for images only, or ["TEXT", "IMAGE"].
generationConfig.imageConfig.aspectRatioenumNoInput image ratio, else 1:11:1, 1:4, 4:1, 1:8, 8:1, 2:3, 3:2, 3:4, 4:3, 4:5, 5:4, 9:16, 16:9, 21:9.
generationConfig.imageConfig.imageSizeenumNo1K1K, 2K, 4K. Uppercase K. 512 is not available for this model.
generationConfig.candidateCountintegerNo1Only 1. One request returns one image.
generationConfig.temperaturenumberNoModel default0–2.
generationConfig.topPnumberNoModel default0–1.
generationConfig.topKintegerNoModel default1 or more.
generationConfig.seedintegerNo—32-bit integer.
generationConfig.maxOutputTokensintegerNoModel default1–32,768.
generationConfig.stopSequencesstring[]No—Up to 5.
generationConfig.mediaResolutionenumNoModel defaultMEDIA_RESOLUTION_LOW, MEDIA_RESOLUTION_MEDIUM, MEDIA_RESOLUTION_HIGH. Sets how many tokens input media use.
generationConfig.thinkingConfig.thinkingLevelenumNoMEDIUMMINIMAL, MEDIUM, HIGH. How much the model reasons before drawing; higher levels take longer.
generationConfig.thinkingConfig.includeThoughtsbooleanNofalseReturn the model's thought summaries as output.thoughts.

Safety categories: HARM_CATEGORY_HARASSMENT, HARM_CATEGORY_HATE_SPEECH, HARM_CATEGORY_SEXUALLY_EXPLICIT, HARM_CATEGORY_DANGEROUS_CONTENT. Thresholds: BLOCK_NONE, BLOCK_ONLY_HIGH, BLOCK_MEDIUM_AND_ABOVE, BLOCK_LOW_AND_ABOVE, OFF.

Unknown fields are rejected. Not yet available: cached content and responseFormat; set the ratio and size with imageConfig. inlineData is not accepted; pass media as fileData URLs.

Output size

imageSize1:1 outputImage tokens
1K1024×10241,120
2K2048×20481,680
4K4096×40962,520

Other aspect ratios keep the same token count; for example 16:9 at 1K is 1376×768, and 21:9 at 4K is 6336×2688.

Modes

There is no separate mode parameter or editing endpoint.

OperationParameters
Text to imagea text part
Edit or composetext part + one or more fileData parts
Multi-turn editearlier user and model turns, then a new user turn (see the note below)

To continue a conversation, rebuild the model turn from the previous task's output.parts, in order: a text part becomes {"text": ..., "thoughtSignature": ...} and an image part becomes {"fileData": {"mimeType": "image/<output_format>", "fileUri": <data[image].url>}, "thoughtSignature": ...}. Keep each thoughtSignature exactly as returned: it is the URL of the signature we stored for you (a 4K image's signature is several megabytes), and we restore it before the request reaches the model. Only signatures from your own task results are accepted.

Edit with a reference image

curl https://api.seedrouter.ai/v1/images/generations \
  -H "Authorization: Bearer $SEEDROUTER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gemini-nano-banana-2.1",
    "contents": [{
      "role": "user",
      "parts": [
        {"text": "Turn this photo into a watercolor painting. Keep the composition."},
        {"fileData": {"mimeType": "image/jpeg", "fileUri": "https://example.com/photo.jpg"}}
      ]
    }]
  }'

Replace the example URL with your own accessible image.

Media inputs

This API accepts URL references only. Base64 inlineData, data: URLs, and multipart uploads are not accepted. The Playground uploads selected files to storage before submitting their URLs.

References must be public HTTP(S) URLs, each smaller than 50 MB and 100 MB in total: images (image/png, image/jpeg, image/webp, image/heic, image/heif), videos (video/mp4, video/mpeg, video/mov, video/avi, video/x-flv, video/mpg, video/webm, video/wmv, video/3gpp), or PDF documents (application/pdf). mimeType must match the file. URLs are fetched during processing; an inaccessible image fails the task, and a failed task is not charged.

Pricing dimensions

Check the model pricing section for the current price. gemini-nano-banana-2.1 charges one flat price per delivered image, whatever the size, thinking level, or prompt.

View final charges in your account usage history. Failed tasks are not charged.

Output schema

Submission returns a task reference:

{
  "id": "task_...",
  "model": "gemini-nano-banana-2.1",
  "status": "processing",
  "created_at": 1790310979
}

Poll the task

curl https://api.seedrouter.ai/v1/tasks/YOUR_TASK_ID \
  -H "Authorization: Bearer $SEEDROUTER_API_KEY"

Poll every few seconds until status is completed or failed. A network timeout while polling does not mean generation failed: keep the task ID and resume checking it. Do not create another task to check progress.

Complete polling example

Run this after the Python submission example above.

import time

deadline = time.monotonic() + 600
while time.monotonic() < deadline:
    result = requests.get(
        f"https://api.seedrouter.ai/v1/tasks/{task_id}",
        headers={"Authorization": f"Bearer {os.environ['SEEDROUTER_API_KEY']}"},
        timeout=30,
    )
    result.raise_for_status()
    task = result.json()
    if task["status"] == "completed":
        for image in task["output"]["data"]:
            print(image["url"])
        break
    if task["status"] == "failed":
        raise RuntimeError(task["error"]["message"])
    time.sleep(3)
else:
    raise TimeoutError(f"Still waiting. Resume polling task {task_id}.")

Completed task

{
  "id": "task_...",
  "model": "gemini-nano-banana-2.1",
  "status": "completed",
  "created_at": 1790310979,
  "finished_at": 1790311001,
  "output": {
    "created": 1790310999,
    "data": [{"url": "https://static.seedrouter.ai/media/tasks/task_example/0.jpg"}],
    "output_format": "jpeg",
    "usage": {
      "input_tokens": 22,
      "output_tokens": 2297,
      "total_tokens": 2319
    }
  }
}
FieldMeaning
idKeep this ID for subsequent queries.
statusprocessing, completed, or failed.
created_at, finished_atUnix timestamps in seconds.
output.data[].urlThe generated image URL.
output.textText the model returned alongside the image, when responseModalities includes TEXT. Thoughts are not included.
output.thoughtsThe model's thought summaries, when includeThoughts is true. Interim images the model draws while thinking are not delivered.
output.grounding_metadataWith Google Search: webSearchQueries, imageSearchQueries, searchEntryPoint.renderedContent (the Search Suggestions HTML you must display) and groundingChunks (sources), as Google returns them.
output.output_formatActual image format.
output.partsThe final response parts in order, for multi-turn editing: {"text", "thoughtSignature"} or {"image": <index into data>, "thoughtSignature"}. thoughtSignature is a URL; send it back unchanged.
output.usageToken usage. output_tokens counts text, thinking, and image output.
errorStructured error on a failed task.

Streaming (streamGenerateContent) is not supported; results are delivered through the task.

Errors

Requests rejected before a task is created return an HTTP error with an error object. A task that fails after acceptance returns HTTP 200 when queried, with status: "failed" and an error object. An image withheld by the model's safety filters fails with content_policy_violation; a response with no image fails with no_output.

See the shared error catalog for codes, HTTP statuses, and retry guidance.

{
  "id": "task_...",
  "status": "failed",
  "error": {
    "code": 60001,
    "message": "The request was rejected by the content policy. Please revise the prompt or input images."
  }
}

If submission itself times out, check your task history before submitting again: the first request may have been accepted.

Tips

  • Describe subject, setting, lighting, and style in full sentences.
  • For an edit, say what should change and what must stay the same.
  • The price is the same at every size, so ask for the size you need: 1K for drafts, 2K or 4K for final assets.
  • Put the exact words you want rendered in quotes, and keep them short.
  • Use MINIMAL thinking for faster drafts and HIGH for dense layouts such as infographics.
  • Save returned images to your own storage when you need a durable copy.