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:
| Model | Cheapest host | Priciest host | Cheapest is | Hosts |
|---|---|---|---|---|
| black-forest-labs/flux.2-dev | MachGen $0.0031 / image | Fal $0.012 / image | 74% lower | 2 |
| google/nano-banana-2 | MachGen $0.034 / image | Fal $0.08 / image | 57% lower | 2 |
| google/nano-banana-pro | MachGen $0.0672 / image | Fal $0.15 / image | 55% lower | 2 |
| black-forest-labs/flux.2-pro | DeepInfra $0.015 / image | Black Forest Labs $0.03 / image | 50% lower | 3 |
| black-forest-labs/FLUX.1-dev | DeepInfra $0.009 / image | SiliconFlow $0.014 / image | 36% lower | 2 |
| alibaba/wan-2.6 | Atlas Cloud $0.021 / image | DeepInfra $0.03 / image | 30% lower | 2 |
| black-forest-labs/flux.2-max | Black Forest Labs $0.07 / image | DeepInfra $0.1 / image | 30% lower | 3 |
| seedream-5.0-pro | Atlas Cloud $0.036 / image | WaveSpeedAI $0.045 / image | 20% lower | 3 |
| recraft-4.1 | WaveSpeedAI $0.04 / image | Pika $0.042 / image | 5% lower | 2 |
| bytedance/seedream-4.0 | WaveSpeedAI $0.027 / image | DeepInfra $0.04 / image | 33% lower | 4 |
| bytedance/seedream-5.0-lite | Atlas Cloud $0.0315 / image | WaveSpeedAI $0.035 / image | 10% lower | 4 |
| qwen-image-max | WaveSpeedAI $0.07 / image | DeepInfra $0.075 / image | 7% lower | 2 |
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
- State the change and what must stay: "change the background to a pale green studio sweep; keep the product, its label and its shadow unchanged".
- One change per request keeps results easy to judge. Chain edits by feeding each output into the next call.
- Describe the target state ("the jar is on a wooden table") instead of a process.
- If text must appear in the image, put the exact words in quotation marks and check the spelling in the output.
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
- Assuming one response shape. Handle both
b64_jsonandurl. - Ignoring the size you got. Not every host honours
resolutionandaspect_ratio, and unsupported values are ignored rather than rejected. Open the file and check dimensions. - Sending OpenAI-only parameters.
quality,output_formatand similar are forwarded only for OpenAI models and ignored elsewhere. - Using expired reference URLs. Use a link that is valid when the host fetches it, or send a base64 data URL.
- Expecting streaming.
stream: trueis rejected with a 400 on this endpoint.
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
- Choosing an Image Generation API — Price, Quality and Control
- Text-to-Image vs Image-to-Image API: Modes, Fields, Pitfalls
- GPT Image vs FLUX vs Seedream vs Nano Banana: How to Choose
- Image Generation API Cost Control: Billing, Drafts, Caching
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 →