Home › Guides › Calling Nano Banana

Calling Nano Banana 2 and Nano Banana Pro over one image endpoint

Updated 2026-10-02

Nano Banana is the popular name for Google's Gemini image models, and the catalog lists two entries: nano-banana-2 and nano-banana-pro. This page shows how to call them through VideoRouter's image endpoint, how to send reference images for edits, and what the response looks like. It does not rank them; it covers the mechanics. The general text-to-image versus image-to-image distinction is in the mode guide.

Find the exact ids

The model pages are at videorouter.sh/image/google/nano-banana-2 and videorouter.sh/image/google/nano-banana-pro. They show the id pattern google/nano-banana-2/{host}; a host can be appended as a soft preference, and omitting it routes to the cheapest healthy host. A host suffix can still fall back; a hard pin needs provider.only with allow_fallbacks: false. The models are hosted by more than one provider, and the live table shows how prices compare per image:

ModelCheapest hostPriciest hostCheapest isHosts
black-forest-labs/flux.2-devMachGen
$0.0031 / image
Fal
$0.012 / image
74% lower2
google/nano-banana-2MachGen
$0.034 / image
Fal
$0.08 / image
57% lower2
google/nano-banana-proMachGen
$0.0672 / image
Fal
$0.15 / image
55% lower2
black-forest-labs/flux.2-proDeepInfra
$0.015 / image
Black Forest Labs
$0.03 / image
50% lower3
black-forest-labs/FLUX.1-devDeepInfra
$0.009 / image
SiliconFlow
$0.014 / image
36% lower2
alibaba/wan-2.6Atlas Cloud
$0.021 / image
DeepInfra
$0.03 / image
30% lower2
black-forest-labs/flux.2-maxBlack Forest Labs
$0.07 / image
DeepInfra
$0.1 / image
30% lower3
seedream-5.0-proAtlas Cloud
$0.036 / image
WaveSpeedAI
$0.045 / image
20% lower3
recraft-4.1WaveSpeedAI
$0.04 / image
Pika
$0.042 / image
5% lower2
bytedance/seedream-4.0WaveSpeedAI
$0.027 / image
DeepInfra
$0.04 / image
33% lower4
bytedance/seedream-5.0-liteAtlas Cloud
$0.0315 / image
WaveSpeedAI
$0.035 / image
10% lower4
qwen-image-maxWaveSpeedAI
$0.07 / image
DeepInfra
$0.075 / image
7% lower2

Per image, before VideoRouter's 2% platform fee. For tiered models each row compares the resolution tier with the widest host-to-host gap. Built 2026-10-02 from the live catalog.

Text-to-image with curl

curl https://videorouter.sh/api/v1/images \
  -H "Authorization: Bearer llmr_sk_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "model": "google/nano-banana-2",
    "prompt": "a hand-lettered coffee shop menu board, chalk on slate, warm light",
    "aspect_ratio": "4:3"
  }'

Auth is a bearer key. The endpoint is POST /images under https://videorouter.sh/api/v1, and unlike video it is a single request that returns the image, not a job you poll.

The same call in Python

import base64, os, requests

API = "https://videorouter.sh/api/v1"
H = {"Authorization": f"Bearer {os.environ['VIDEOROUTER_KEY']}"}

def generate(prompt, model="google/nano-banana-2", **params):
    r = requests.post(f"{API}/images", headers=H, timeout=180,
                      json={"model": model, "prompt": prompt, **params})
    if not r.ok:
        err = r.json().get("error", {})
        raise RuntimeError(f"{r.status_code} {err.get('type')}/{err.get('code')}: {err.get('message')}")
    return r.json()

def save(result, path):
    item = result["data"][0]
    if "b64_json" in item:
        open(path, "wb").write(base64.b64decode(item["b64_json"]))
    else:
        open(path, "wb").write(requests.get(item["url"], timeout=60).content)

res = generate("a hand-lettered coffee shop menu board, chalk on slate", aspect_ratio="4:3")
save(res, "menu.png")
print(res.get("usage", {}).get("cost"))

The result's data array holds either b64_json or a url depending on the host, so handle both as above rather than assuming one. The response also carries a usage block with the real cost for that call, which already includes the 2% platform fee. Log it per request.

Editing with input_references

The image documentation shows image-to-image on the same endpoint: pass one or more reference images in input_references, as a public URL or a base64 data URL, with an instruction as the prompt. Its worked example uses a Google image model, and the documentation lists the Gemini image models as working on this endpoint.

res = generate(
    "keep the product exactly as is; change the background to a pale green studio sweep",
    model="google/nano-banana-pro",
    input_references=[
        {"type": "image_url", "image_url": {"url": "https://example.com/product.jpg"}}
    ],
)
save(res, "product-green.png")

One caution. When the model page for nano-banana-2 was checked, it listed "text in, image out" and no image-input row. Whether a given host accepts references can vary, so run one test call with input_references against the exact id and host you plan to use, and read the model page's input list before building an editing workflow. Confirm the result by looking at the output rather than trusting the status code alone.

Prompting edits

Choosing between the two ids

Both are Google image models with their own pricing, and the table above shows the live difference. A sensible approach mirrors any two-tier setup: iterate with the cheaper one, render finals with the other if your own blind tests show it earns the difference. The cost-control guide covers the draft-then-final pattern for images in more detail.

Batching and concurrency

Each call returns one result, so a batch is a loop. Run a small number of requests in parallel, keep it under your key's rate limit, and treat a 429 as a signal to wait for the Retry-After value instead of hammering the endpoint. Save every output as soon as it arrives, along with the usage.cost and the exact model id, so a crash halfway through a batch loses nothing you have already paid for.

Common mistakes

Errors

Errors follow the OpenAI-style envelope {"error": {"message", "type", "code"}}: 400 for a bad request, 401 for a key problem, 402 when the balance or the key's spend cap is exhausted, 403 when the key's scope or allow-list excludes the model, and 429 with Retry-After when you hit your rate limit. Retry only 429 and 5xx, with backoff.

Open the model pages for host details, the pricing page for the live table, and create a key to make your first call.

Frequently asked questions

What model ids do I use for Nano Banana?

The catalog lists nano-banana-2 and nano-banana-pro, shown on their model pages in the form google/nano-banana-2/{host}. Omit the host to route to the cheapest healthy provider.

Do I need to poll for the result?

No. Image generation is a single POST /images request that returns the image, unlike video jobs which are created and polled.

How do I edit an existing image with Nano Banana?

Send the image in input_references with an instruction prompt. Check the model page's input list and test one call first, since support can vary by host.

How do I read the cost of a call?

The response includes a usage block with the cost for that request, which already includes the 2% platform fee. Log it for each call.

Keep reading

Using image generation is one part of the job.

VideoRouter puts it next to dozens of other video and image models behind one API key, so you can compare providers, prices and fail over automatically. Compare providers on VideoRouter →