Most image features start as a demo and then hit a wall: the moment you need to change one thing in a photo without regenerating the whole scene. OpenRouter’s September 9, 2026 tutorial on the Nano Banana API treats that wall as a request-shape problem, and the shape it lands on is small enough to fit on one screen.
One request, two fields that matter
The guide’s claim is that editing takes a single call. You put the source image in input_references and the instruction in prompt, then read the edited image from data[0].b64_json and decode it to disk. The default model is google/gemini-3.1-flash-image, which the tutorial identifies as Nano Banana 2, the default fast model in Google’s Gemini image family.
That is the whole contract. No separate upload step, no job polling, no asset ID to track between calls. For a builder, the interesting part is not the model name but the fact that the request body is the same in Python and TypeScript, and that the response is base64 you can write straight to a file.
Inputs: base64 or a plain URL
input_references accepts either a base64 data URL or an HTTP(S) URL. The tutorial recommends a URL when the image is already hosted publicly, because it keeps the request body small, and base64 for local or private files. Gemini accepts image/png, image/jpeg, image/webp, image/heic, and image/heif inputs, though the guide warns that supported formats vary by model, so check the model page before sending.
That split matters more than it looks. If your pipeline already stores images behind a CDN, you can skip encoding entirely. If it handles user uploads that never leave your infrastructure, base64 keeps them local.
Editing in steps instead of one big prompt
The tutorial’s most practical advice is to edit in small steps. Send each returned image back in as the next source, one instruction per call, so changes stack. The sample chains three calls: add a scarf, make it navy blue, then add soft morning light from the left.
There is a constraint worth internalizing: the model does not remember earlier prompts, so each new prompt has to repeat the parts that should stay the same. That is a real cost in prompt tokens and in review effort, but it also means each step is independently checkable and redoable. If step three comes back wrong, you still have step two on disk.
The guide also separates generation prompts from edit prompts. A generation prompt describes a whole new image; an edit prompt states the change first, then names what must stay the same. Its examples include an object swap, a background change, a style transfer, and a text fix. It notes you can write the prompt as a small JSON block with edit, preserve, and style keys, but the API treats that as plain text, not a special mode.
Swapping models and handling failures
Changing the editing model is a one-field change: replace the model value and keep the source image, prompt, and response handling identical. The tutorial lists four current members of the family, with google/gemini-3.1-flash-lite-image as the cheapest and fastest, google/gemini-3-pro-image as slower and higher quality, and the original google/gemini-2.5-flash-image still working with the same request shape. It also shows openai/gpt-5-image as a cross-provider comparison, with the caveat that this only works for models that accept image input and support the same input_references shape.
If you are already treating model choice as configuration rather than code, this fits the pattern described in Config-as-Code for LLM Calls, where per-environment model settings live outside the request logic.
The failure modes the guide flags are worth planning for. A model may reject an unsupported format or an unreachable URL. Oversized images can time out, so shrink the source first. And a question like “what’s in this photo?” can make the model answer in text instead of producing an image, which the API returns as a 400 error rather than an empty response. Write an instruction, not a question, and check the HTTP status before decoding.
Cost is reported per request in USD when usage data is available, so logging usage.cost gives you spend tracking without a separate meter. For batch jobs, the tutorial suggests retrying 429 and 5xx responses with growing delays, limiting concurrency, and saving each returned image before starting its next edit so one failure does not lose finished work.
What to take from this
The request shape is the useful part: one endpoint, one source image, one instruction, one image back. That makes image editing something you can wrap in a function and test like any other API call, rather than a separate subsystem. The limitation is that quality and format support still vary by model, and the supplied tutorial does not specify how the editing-capable catalog will change over time beyond noting that models are added, deprecated, and repriced. Pin a slug, but keep the model field easy to change.
Sources
AI-assisted summary compiled from the sources above, reviewed by a human before publishing.
