> ## Documentation Index
> Fetch the complete documentation index at: https://docs.widerouter.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Nano Banana series

> Google's image generation models on WideRouter: which id works on which surface, every parameter they accept, and measured latency.

Nano Banana is Google's series name for this generation of image models.
On WideRouter the **model ids are the official ones** — there are no
platform-specific aliases, and `-preview` suffixed names are not accepted.

All models in the series take the same request shape, so switching between them
is a one-word change to `model`.

## The series at a glance

|                       | Nano Banana Pro      | Nano Banana 2            | Nano Banana              |
| --------------------- | -------------------- | ------------------------ | ------------------------ |
| **Model id**          | `gemini-3-pro-image` | `gemini-3.1-flash-image` | `gemini-2.5-flash-image` |
| Async task API        | yes                  | yes                      | not available yet        |
| Synchronous APIs      | yes                  | yes                      | not available yet        |
| Resolution tiers      | `1K` `2K` `4K`       | `1K` `2K` `4K`           | —                        |
| Images per call (`n`) | 1–4                  | 1–4                      | —                        |
| Reference images      | up to 14             | up to 14                 | —                        |
| Async, 1K, mean       | \~29 s               | \~20 s                   | —                        |
| Sync round trip, 1K   | \~17 s               | \~13 s                   | —                        |

<Warning>
  `gemini-2.5-flash-image` does not currently route on either surface. The async
  API rejects it at submit with `model_not_supported`; the synchronous endpoints
  return a pricing-configuration error. It is listed here so that looking up the
  official id gives you an answer rather than silence — it will be enabled once
  the platform side is fixed.
</Warning>

Reach for **Nano Banana 2** by default: it is meaningfully faster at every
resolution and takes the same parameters, so nothing about your integration
changes. Move to **Nano Banana Pro** when the extra quality is worth roughly ten
more seconds per image.

## Parameters

Everything goes inside `input`. The envelope around it — `model`, `input`,
`callback_url` — is described in the [async task API](/api/async-tasks).

These five fields are the complete set. Any other key inside `input` is rejected
with `invalid_params`, so a typo fails loudly instead of being ignored.

| Field          | Type      | Required | Range                               | Default             |
| -------------- | --------- | -------- | ----------------------------------- | ------------------- |
| `prompt`       | string    | yes      | 1–32000 bytes                       | —                   |
| `n`            | integer   | no       | 1–4                                 | 1                   |
| `aspect_ratio` | string    | no       | see [aspect ratios](#aspect-ratios) | model's own default |
| `image_size`   | string    | no       | `1K` `2K` `4K`                      | `1K`                |
| `images`       | string\[] | no       | up to 14 items                      | none                |

<Warning>
  `image_size` is case-sensitive: `1K` is accepted, `1k` is not. There is no
  `512` tier on the async API, and no free-form `1024x1024` form.
</Warning>

## Resolution tiers

`image_size` scales the whole frame rather than pinning one edge, so the long
edge of a wide image at `4K` is well past 4096 pixels. Measured, and identical
on both available models:

| `image_size` | `1:1`       | `21:9`      | Approximate pixels |
| ------------ | ----------- | ----------- | ------------------ |
| `1K`         | 1024 × 1024 | 1584 × 672  | 1 MP               |
| `2K`         | 2048 × 2048 | —           | 4 MP               |
| `4K`         | 4096 × 4096 | 6336 × 2688 | 17 MP              |

File sizes follow: roughly 0.4–0.7 MB at `1K`, 2.4–3.0 MB at `2K`, and
7.5–8.2 MB at `4K`. Output is always JPEG carrying a C2PA content-credentials
manifest.

## Aspect ratios

Ten values are accepted. Measured pixels at `1K` on `gemini-3-pro-image`:

| Ratio | Pixels      | Ratio  | Pixels     |
| ----- | ----------- | ------ | ---------- |
| `1:1` | 1024 × 1024 | `4:5`  | 928 × 1152 |
| `3:2` | 1264 × 848  | `5:4`  | 1152 × 928 |
| `2:3` | 848 × 1264  | `9:16` | 768 × 1376 |
| `4:3` | 1200 × 896  | `16:9` | 1376 × 768 |
| `3:4` | 896 × 1200  | `21:9` | 1584 × 672 |

Every ratio landed within one percent of nominal. Omit `aspect_ratio` and a text
prompt gives you 1024 × 1024; when you pass `images`, the output follows the
source image's shape instead.

## Editing and composition

Pass reference images in `images` to edit them or compose from them. Each entry
is either an `https` URL or a base64 data URI — a bare base64 string with no
data-URI prefix is rejected, and so is plain `http`.

```json theme={null}
{
  "model": "gemini-3-pro-image",
  "input": {
    "prompt": "place the leaf from the second image leaning against the mug from the first",
    "images": [
      "https://your-bucket.example/mug.jpg",
      "data:image/jpeg;base64,/9j/4AAQSkZJRgABAQ..."
    ]
  }
}
```

Both forms mix freely in one call, and `aspect_ratio`, `image_size` and `n` all
still apply — an edit at `4K` really does come back at 4096 × 4096.

URLs are fetched **server-side after the task is accepted**, so a bad reference
produces a `failed` task rather than a `400`. The two failure codes tell you
which layer gave up:

| What you passed                               | `error.code`        | Time to fail |
| --------------------------------------------- | ------------------- | ------------ |
| Unresolvable host, 404, or a URL needing auth | `input_fetch_error` | under 1 s    |
| Reachable, but not an image (HTML, JSON)      | `upstream_error`    | \~4 s        |

Both fail before any model work, so they are fast and cheap to retry.

## Latency

Async figures come from 30 tasks at concurrency 12; sync figures from single
calls. Treat these as orders of magnitude, not a service-level guarantee.

|                      | Nano Banana Pro | Nano Banana 2 |
| -------------------- | --------------- | ------------- |
| Async submit call    | \~0.9 s         | \~0.9 s       |
| Async end-to-end, 1K | \~29 s mean     | \~20 s mean   |
| Async end-to-end, 4K | \~36–40 s       | \~41 s        |
| Sync round trip, 1K  | \~17 s          | \~13 s        |

Async costs about 0.9 s of extra round trip in exchange for not holding a
connection for the other 20–40 seconds. Queue time was 0–11 seconds under load
and is already folded into the end-to-end figures.

## Synchronous surfaces

Three synchronous shapes work for both available models, and all three return
the image inline rather than as a URL:

| Endpoint                                      | Where the image is                                                                                             |
| --------------------------------------------- | -------------------------------------------------------------------------------------------------------------- |
| `POST /v1/images/generations`                 | `data[0].b64_json`, or `data[0].url` with `response_format` set to `url`. `n` is ignored — one image per call. |
| `POST /v1/chat/completions`                   | a Markdown image with a data URI inside the message content                                                    |
| `POST /v1beta/models/{model}:generateContent` | `candidates[0].content.parts[]`, in an `inlineData` part                                                       |

<Warning>
  On the Gemini-native shape, never index `parts` by position. It is a
  heterogeneous array whose length and order are not guaranteed: a text part can
  come first, and complex edits return several draft images. Filter for entries
  that have `inlineData` and take the **last** one, and read `mimeType` from the
  response instead of assuming a file extension.
</Warning>

## Next steps

<CardGroup cols={2}>
  <Card title="Playground" icon="play" href="/models/nano-banana/playground">
    Send a real request from this page and watch the task run.
  </Card>

  <Card title="Async task API" icon="clock" href="/api/async-tasks">
    The envelope, polling loop, callbacks and error table.
  </Card>
</CardGroup>
