Nano Banana 2.1 is Google’s high-efficiency image model for generation and editing, with output up to 4K and support for up to 10 reference images. The Nano Banana 2.1 API enables developers to integrate these capabilities into Python applications. This tutorial walks through a working Python integration: authenticating, creating a task, checking its status, and downloading the result.
What You Will Learn About the Nano Banana 2.1 API?
- How the asynchronous task pattern works for image-generation APIs?
- How to send text-to-image and image-editing requests?
- Which parameters control resolution, aspect ratio, and file format?
- How do you poll for results safely, and when should you switch to callbacks?
- What should you change when moving an existing project off Nano Banana 2?
Prerequisites for Using the Nano Banana 2.1 API
You need Python 3.8 or later, the requests library (pip install requests), and an API key from a provider that hosts the model. Basic familiarity with JSON and HTTP requests is enough to follow along. Every request in this tutorial sends the key in an Authorization: Bearer header, so store it in an environment variable rather than in the script.
Step 1: Understand the Model and Why it Matters Now
Google positions Nano Banana 2.1 as the recommended replacement for Nano Banana 2, with improvements in visual quality, prompt adherence, character consistency, text rendering, and multi-reference work. It also sits alongside Nano Banana Pro as the more efficient option: Pro targets premium image quality, while 2.1 aims to balance quality, speed, and cost for high-volume work.
There is a practical deadline, too. Nano Banana 2 is scheduled to shut down on October 29, 2026. If an application still calls it, now is the time to migrate. As you will see below, the Nano Banana 2.1 API request structure is straightforward, so many migrations may involve changing the model name and retesting prompts.
Step 2: Learn the Asynchronous Task Pattern
Image generation takes longer than a typical API call, so the Nano Banana 2.1 API does not return the image in the initial response. Instead, the process works in two stages:
- You send a POST request to create a task. The response contains a taskId.
- You check the task with that ID until its state is success or fail. On success, the result contains a list of image URLs.
A task moves through the states waiting, queuing, and generating before it finishes. One detail catches many beginners: errors come back with an HTTP status of 200, so your code must read the code field in the JSON body. A value of 200 means success; values such as 401 (invalid key), 402 (insufficient credits), and 429 (rate limited) mean the request failed.
Step 3: Send Your First text-to-image Request
This tutorial uses the Nano Banana 2.1 API on Kie.ai, where the model name is nano-banana-2-1, and tasks go to a shared task endpoint. The page also has a browser playground, which is useful for trying prompts before you write any code.
import os, time, json, requests
API_KEY = os.environ["KIE_API_KEY"]
BASE = "https://api.kie.ai/api/v1/jobs"
HEADERS = {"Authorization": f"Bearer {API_KEY}", "Content-Type": "application/json"}
def create_task(prompt, image_urls=None, aspect_ratio="auto", resolution="1K", output_format="png"):
payload = {
"model": "nano-banana-2-1",
"input": {
"prompt": prompt,
"image_input": image_urls or [],
"aspect_ratio": aspect_ratio,
"resolution": resolution,
"output_format": output_format,
},
}
r = requests.post(f"{BASE}/createTask", headers=HEADERS, json=payload, timeout=30)
body = r.json()
if body.get("code") != 200:
raise RuntimeError(f"createTask failed: {body.get('code')} {body.get('msg')}")
return body["data"]["taskId"]
Notice that the function checks code rather than relying on r.status_code. That one line prevents silent failures later.
Step 4: Poll for the Result
Next, write a function that queries the task until it finishes. The documentation recommends starting with 2 to 3-second intervals and increasing them gradually, which the loop below does.
def wait_for_result(task_id, max_wait=300):
delay, waited = 2, 0
while waited < max_wait:
r = requests.get(f"{BASE}/recordInfo", headers=HEADERS,
params={"taskId": task_id}, timeout=30)
body = r.json()
if body.get("code") != 200:
raise RuntimeError(f"recordInfo failed: {body.get('msg')}")
data = body["data"]
if data["state"] == "success":
return json.loads(data["resultJson"])["resultUrls"]
if data["state"] == "fail":
raise RuntimeError(f"task failed: {data.get('failMsg')}")
time.sleep(delay)
waited += delay
delay = min(delay * 1.5, 15)
raise TimeoutError("task did not finish in time")
task = create_task("A clean infographic poster titled 'Water Cycle' with four labeled stages, "
"flat illustration style, white background", aspect_ratio="3:4", resolution="2K")
print(wait_for_result(task))
The resultJson field arrives as a string, so it has to be parsed before you can read resultUrls. Download the files promptly: generated results are kept for 14 days.
Step 5: Edit an Existing Image With References
Editing uses the same function. Pass one or more image URLs in image_input and describe the change in the prompt. The model accepts up to 10 reference images, each JPEG, PNG, or WebP, up to 30 MB. The images must be URLs, not file contents; if your files are local, upload them first with the provider’s file upload API.
task = create_task(
"Keep the person from the first image and the jacket from the second image. "
"Place them on a rainy city street at night, same face and hairstyle.",
image_urls=["https://example.com/person.png", "https://example.com/jacket.png"],
aspect_ratio="4:5", resolution="2K")
print(wait_for_result(task))
Replace the example URLs with publicly accessible image URLs or URLs supported by your provider.
Multi-reference prompts work best when you specify which image supplies each element. For example, “the person from the first image” is much less ambiguous than “this person.” Clear instructions help the Nano Banana 2.1 API interpret references more accurately.
Step 6: Choose the Right Parameters
- prompt (required): up to 20,000 characters. Long, specific prompts are fine.
- resolution: 1K, 2K, or 4K. The default is 1K, and higher resolutions take longer to generate.
- aspect_ratio: 14 fixed ratios plus auto (the default). Beyond the usual 1:1, 16:9, and 9:16, it includes tall and wide options such as 1:4, 4:1, 1:8, and 8:1 for banners and vertical strips.
- output_format: jpg (default) or png. Use PNG when you plan further editing.
- image_input: optional list of up to 10 reference image URLs.
Step 7: Move to Callbacks for Production
Polling is fine for a script or a notebook. In a web application, the documentation recommends passing a callBackUrl when you create the task. The system then POSTs the result to your endpoint when generation completes, so your server does not waste time asking. If you enable webhook signing, each callback carries a timestamp header and an HMAC-SHA256 signature that you can verify before trusting the payload.
Common Nano Banana 2.1 API Mistakes to Avoid
- Reading only the HTTP status and missing an error in the code
- Forgetting to parse resultJson from a string.
- Sending local file paths in image_input instead of hosted URLs.
- Polling every 200 milliseconds and running into rate limits.
- Leaving results on the provider’s storage past the 14-day window.
Practice Exercises: Test Your Nano Banana 2.1 API Integration
Try these three exercises to reinforce your understanding of image generation and editing.
- Compare image resolutions: Generate the same prompt at 1K and 4K, then compare detail, generation time, and output file size.
- Create a consistent four-panel comic: Generate the first panel, then reuse it as a reference for subsequent panels to maintain character consistency.
- Replace polling with callbacks: Rewrite wait_for_result() as part of a small Flask application that receives callbacks instead of repeatedly checking task status.
These exercises show how the Nano Banana 2.1 API supports different image workflows, from basic generation to reference-based editing and production automation.
Final Thoughts
The Nano Banana 2.1 API provides a straightforward way to integrate image generation and editing into Python applications through an asynchronous task workflow. By learning how to create tasks, monitor their status, process image URLs, and select the right parameters, developers can build more flexible image-processing workflows.
Once the basic integration works, you can use the same approach to explore other models. Kie.ai hosts several image and video models behind a shared task endpoint and API key, so comparing models may involve changing the model value and its input fields rather than rewriting the entire client. Always verify each model’s current API requirements before switching.
Recommended Articles
We hope this guide helps you use the Nano Banana 2.1 API for image generation and editing with Python. Explore our recommended articles for more insights on AI image tools, Python APIs, and generative AI.
