Choose Auto, TokenLab Verified, or Official for each request, with prices shown up front.See what's new

Nano Banana API Guide: Image Generation and Editing on TokenLab

·September 19, 2026·12 min read·Updated October 2, 2026·1585 views
#image#ai-api#tokenlab
Nano Banana API Guide: Image Generation and Editing on TokenLab

What you’ll learn

  • Which Nano Banana model ID should I send for image-to-image requests?
  • Why did my image request return a task_id instead of an image?
  • Can I get base64 output from a Nano Banana model?
  • Is a failed image task charged?

The Nano Banana API has three priced model IDs on TokenLab, and the cheapest costs about half as much per image as the middle one. The expensive mistake is rarely the model choice. It is sending an edit request to the wrong endpoint or retrying a create call that already made a task. This guide covers the exact IDs, a working text-to-image call, a reference-image call, async polling, expected errors, and how the charge is set. Prices and field lists were read on 2026-10-03, so confirm them again before you ship.

Key Takeaways

  • Send the exact ID: nano-banana-2, nano-banana-2-lite, or nano-banana-pro. Display names are not request aliases.
  • Reference-image work for Nano Banana goes to POST /v1/images/generations with operation: "image-to-image" and image_urls. It does not go to /v1/images/edits or /v1/chat/completions.
  • The base prices we read on 2026-10-03 are $0.0168, $0.0335, and $0.067 per image for the lite, standard, and pro IDs. Each model has a price range, so confirm the exact tier in Usage.
  • A create response with task_id, status: "pending", or poll_url means you must poll GET /v1/tasks/{id} until completed or failed.
  • A status read returns HTTP 200 even when the task failed. Branch on the task's status field, not the HTTP code.
  • Final charges live in Usage and in billing_transaction_id, not in a copied price table.

Nano Banana API models, price units, and what each is for

When we compared this guide's earlier draft against the current docs, we found three problems. It listed models without prices. It sent a Nano Banana edit through chat completions. It queried the catalog with a filter the image guide does not use. The table below fixes the first. The later sections fix the other two.

Model ID Best for Pricing unit TokenLab price (USD) Source, observed
nano-banana-2 Text-to-image and image-to-image with aspect_ratio and resolution (1k, 2k, 4k). Released 2026-02-26. per_image $0.0335 per request. Range $0.0225 to $0.0755. Live model API, 2026-10-03
nano-banana-2-lite Cheapest text-to-image and image-to-image. The price entry we saw covers the 1k tier. per_image $0.0168 per request. Min and max both $0.0168. Live model API, 2026-10-03
nano-banana-pro Text-to-image, image-to-image, and image edit with aspect_ratio and resolution. per_image $0.067 per request. Range $0.067 to $0.12. Live model API, 2026-10-03
nano-banana Text-to-image with aspect_ratio only. No public resolution selection. Not in our evidence Check the model page or pricing endpoint Catalog, 2026-10-02; Create Image docs, 2026-10-03

All prices above carry is_lock_price: true and were updated 2026-10-02T16:53:30.068Z. Three details matter before you pick one:

  • Resolution tiers move the price. The live API shows a range for nano-banana-2 and nano-banana-pro, but our evidence does not map each tier to a resolution. Do not assume 1k is the base price. Read the pricing entries for your model.
  • Text output has its own token price. Both nano-banana-2 and nano-banana-pro carry a native-gemini-text-output entry. It applies when outputModality is text. For nano-banana-2 it lists 0.25 input and 1.5 output. For nano-banana-pro it lists 1 input and 6 output. The unit is per_token. Confirm the scale in GET /v1/models/:model/pricing before you budget around it.
  • Lite lists no accepted request format. The live record for nano-banana-2-lite says "not listed". Read its details before building against it.

For a rough budget, we multiply the base price by volume. These are estimates at the base price, not quotes:

  • 100 images on nano-banana-2-lite: 100 × $0.0168 = $1.68.
  • 100 images on nano-banana-2: 100 × $0.0335 = $3.35.
  • 100 images on nano-banana-pro: 100 × $0.067 = $6.70.

Higher resolution tiers will raise these numbers.

To list current image models yourself, call the endpoint the image generation guide uses. The earlier draft used category=image, which the guide does not document.

curl "https://api.tokenlab.sh/v1/models?recommended_for=image" \
  -H "Authorization: Bearer sk-your-api-key"

For one model's operations, prices, and lifecycle, use Get a Model. You can also browse the TokenLab Models directory.

Send a text-to-image request with the Nano Banana API

Create an API key in the TokenLab dashboard and export it:

export TOKENLAB_API_KEY="your-tokenlab-api-key"

Always send model. The Create Image reference says image APIs do not pick a default. A missing model returns a 400 with param: "model".

This request uses only fields the docs list for Google image families. We kept resolution at 1k because nano-banana-2 documents 1k, 2k, and 4k.

curl -X POST "https://api.tokenlab.sh/v1/images/generations" \
  --max-time 120 \
  -H "Authorization: Bearer $TOKENLAB_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "nano-banana-2",
    "prompt": "A minimalist ceramic vase on a natural wooden table, studio lighting",
    "aspect_ratio": "1:1",
    "resolution": "1k",
    "response_format": "url"
  }'

The --max-time 120 flag matches the docs. They say high-resolution requests can take close to a minute or longer, so set your client timeout to at least 120 seconds. The docs say size is a compatibility alias for Google image families, but they recommend aspect_ratio directly.

A synchronous success returns the finished image inline. The placeholder values below show the documented shape only:

{
  "created": 1700000000,
  "data": [
    { "url": "https://example.com/generated-image.png" }
  ]
}

Read it in this order:

  1. If the body has task_id, status: "pending", or poll_url, you have a task, not an image. Go to the polling section.
  2. Otherwise read data[0].url. With response_format: "b64_json", read data[0].b64_json instead.
  3. created is a Unix timestamp. revised_prompt appears only when the model returns one, so do not require it.
  4. Store the image URL, your own job ID, the model, and the request_id from the response headers.

Generated image URLs may be kept as media copies for 30 days. Check media_retention.items for each item's status and expires_at. Pending or failed copies are not guaranteed, so copy the file to your own storage if you need it longer. The data retention guide has the details.

Edit an image with a reference URL

Imagine a catalog team that wants the same product shot on a clean studio background. The tempting move is /v1/images/edits. The docs rule that out. Nano Banana reference-image requests are exposed on /v1/images/generations with operation: "image-to-image". /v1/images/edits is not the right path for them.

This request comes from the image generation guide, with nano-banana-2 as the model:

curl https://api.tokenlab.sh/v1/images/generations \
  -H "Authorization: Bearer $TOKENLAB_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "nano-banana-2",
    "operation": "image-to-image",
    "prompt": "Keep the product shape, change the background to a bright studio setup",
    "image_urls": ["https://example.com/input/product.png"],
    "aspect_ratio": "1:1"
  }'

Rules we follow with this shape:

  • Send exactly the documented reference fields. Use image_url, image_urls, or reference_image_urls in JSON. Do not send top-level images[] or file_id. Those belong to the edit flow and are rejected on this endpoint.
  • Use public URLs. They must be http or https, with no embedded credentials, no fragments, and no private network hosts. Avoid signed URLs that may expire before processing starts.
  • Use multipart for private sources. The docs offer a multipart image file for sources that are private or header-protected.
  • Match resolution to the model. The docs say nano-banana-pro may include it and nano-banana-edit should omit it. The docs also name nano-banana-edit as a reference-image model, but that ID is not in the catalog we fetched on 2026-10-02. Verify any ID against /v1/models before using it.

The source article's chat-completions edit example is gone. The live record lists gemini_generate_content as the accepted format for nano-banana-2 and nano-banana-pro. Our evidence does not document a chat-completions image-edit path.

Mask-based inpainting and parameters such as strength are not documented for Nano Banana in our evidence. Inspect GET /v1/models/{model} before you send them.

When an image request becomes a task, and how to poll it

An image create call is either synchronous or asynchronous, and the response tells you which. The async jobs guide lists the trigger fields: task_id, status: "pending", or poll_url. If any appears, the data[] array is empty and the work is still running.

Our evidence documents the async: true request flag only for gpt-image-2 and official FLUX/BFL image models. It does not document it for the Nano Banana IDs. Do not add it to a Nano Banana request. Handle a task response if one comes back, and check the model details if you need async behavior.

Imagine a browser refresh that re-sends the create call after a slow response. You now pay for two generations. The docs say most duplicate generations come from this retry. Follow this order:

  1. Save IDs immediately. Store id or task_id, poll_url, the model, the endpoint, and your own job ID. id and task_id are the same value.
  2. Poll the URL. Use poll_url when present. Otherwise call the fixed route:
curl "https://api.tokenlab.sh/v1/tasks/$TASK_ID" \
  -H "Authorization: Bearer $TOKENLAB_API_KEY"
  1. Poll every 5–10 seconds. The guide says that is usually enough for long media jobs.
  2. Know the statuses. They are pending, processing, completed, and failed. A cancelled task shows failed with cancelled: true.
  3. Stop at a terminal status. On completed, read data[].url. Async image results are URLs only, never b64_json. On failed, read error and error_details.
  4. Handle timeouts safely. If a create call times out before you see a response, check the request_id and look for a task before retrying. If you stored a task ID, resume polling it. If a status poll fails, retry that poll with backoff and do not re-create.

A status read returns HTTP 200 even for a failed task. Failed tasks may include error_details with status, type, code, message, param, and retryable. For example, error_details.status: 400 with param: "size" means the request needs correction. It does not mean the poll itself failed. Retrying a failed generation creates a new task and may create a new charge.

Errors to expect and what to do

Handle errors by HTTP status and code, never by message. The error handling guide says the message can change without notice. Chat Completions and Responses use an OpenAI-style error object, while Gemini and Anthropic formats keep their own shapes. Do not share one parser across all TokenLab APIs.

Status / code Likely cause What to do
400, param: "model" No explicit model Send model. List IDs with /v1/models?recommended_for=image.
400 unsupported field, or unsupported_parameter A field the model does not document, such as resolution on a model without it Remove the field or switch model. Do not repeat unchanged.
400 on a reference image Wrong endpoint, or a private or expired URL Use /v1/images/generations with image_urls. Use a public, stable URL.
401 invalid_api_key or expired_api_key Missing, revoked, or expired key Replace the key.
402 insufficient_balance or quota_exceeded Balance too low, or the key hit its own limit Add funds, raise the key limit, or choose a lower-priced model.
403 model_not_allowed The key cannot use that model Update the key's model list.
404 model_not_found Unknown or unavailable ID Read /v1/models and use a current ID.
413 payload_too_large Request or file too large Reduce the input.
429 rate_limit_exceeded Too many requests in the window Wait for Retry-After, then retry.
500–504, all_channels_failed Service or supply problem Retry only when retryable is true. Respect retry_after and cap attempts.

A 503 all_channels_failed does not always mean an outage. If retryable is false and retry_after is missing, the operation has no supply in the selected Delivery tier. Repeating the request will not help, so check GET /v1/models first.

Task polling has its own failures:

  • 404 async_task_not_found: the task expired or is gone. Check the saved task_id and poll_url.
  • 403 task_not_owned: the task belongs to another workspace. Check which workspace the API key belongs to.
  • A completed task with no media URL: treat it as failed. Keep the IDs and contact support.

When you contact support, send request_id, task_id, billing_transaction_id when present, endpoint, model, time, and field names. Never send keys, private media, or signed URLs.

How the charge for an image request is determined

All three priced Nano Banana IDs use the per_image unit, so the headline charge is the model's per_request price. The billing guide adds the rules around it:

  • One result, one charge. Each completed request is charged once, for the delivery option that produced it. TokenLab Verified uses TokenLab public prices. Official uses the Official price layer. Auto tries Verified first, then Official.
  • Tiers set the final number. The live price ranges ($0.0225 to $0.0755 for nano-banana-2, $0.067 to $0.12 for nano-banana-pro) show that one flat price does not cover every request. Resolution tiers are the likely driver, but confirm that in the model's pricing entries.
  • Tasks reserve first. An async task may reserve its estimated cost when accepted. A completed task is charged once, and a failed task releases or refunds the pending amount. The billing guide says a failed task is not charged.
  • A dash is not free. On the Models page, a dash in the TokenLab price column means no Verified offer is available right now.

To confirm a charge, use these places:

  1. GET /v1/models/:model/pricing or the Pricing API for the current price.
  2. Console, which shows the maximum estimate before you confirm paid generation.
  3. Usage for the final charge by model.
  4. billing_transaction_id in the response or task, and the X-Billing-Transaction-ID header. Streaming and some native formats may expose it only in the header.

If Usage does not show the final charge or the released amount after a task finishes, send the Request ID and task ID to support@tokenlab.sh. Do not copy the prices in this article into your code. The billing guide says to read the current price when your application needs to display or compare costs.

FAQ

Which Nano Banana model ID should I send for image-to-image requests?

The live records list image-to-image for nano-banana-2, nano-banana-2-lite, and nano-banana-pro. The docs also name nano-banana-edit, but it is not in the catalog we fetched on 2026-10-02. Send the ID with operation: "image-to-image" and image_urls to /v1/images/generations. Run a small test on your own images, because our evidence has no quality comparison.

Why did my image request return a task_id instead of an image?

The create call ran as an async task. Look for task_id, status: "pending", or poll_url in the response. Save those fields, then poll poll_url or GET /v1/tasks/{id} every 5–10 seconds until the status is completed or failed. Do not send a second create request while you wait.

Can I get base64 output from a Nano Banana model?

The response_format field accepts url or b64_json, and a synchronous request can return data[].b64_json. Async image results are URLs only, whatever format you asked for. Check the selected model's details to confirm it accepts b64_json, because fields differ by model.

Is a failed image task charged?

The billing guide says a failed task is not charged, and any pending reservation is released or refunded. Retrying a failed generation creates a new task and may create a new charge. Confirm the outcome in Usage using the billing_transaction_id and task_id.

Create a key in the TokenLab dashboard, send the text-to-image request above with nano-banana-2-lite, and check the charge in Usage.

Sources

Prices checked 2026-10-03

Related models

Recent model releases

Try the models from this article

Chat, create images, or make video with the same TokenLab balance.