Nano Banana API: Pricing & Python Example
Call it with one LaoZhang API key, using the same endpoint as the YingTu image studio. Below you get the endpoint, parameters, per-image price and copy-paste code. Your real key never appears in the examples. As of October 9, 2026, every model ID on this page is billed per image with no subscription, and one key works for all of them.
Key facts (as of October 10, 2026)
- Model IDs on this endpoint: gemini-3.1-flash-lite-image, gemini-3.1-flash-image, gemini-nano-banana-2.1 and gemini-3-pro-image. One LaoZhang key works for all of them.
- Price per image: Nano Banana 2 Lite $0.025, Nano Banana 2 $0.055, Nano Banana 2.1 $0.045 and Nano Banana Pro $0.09. No subscription; every image is billed on its own.
- Base URL https://api2.laozhang.ai, Gemini request format: POST /v1beta/models/{model}:generateContent.
- New LaoZhang accounts get $0.1 to test: about 4 Nano Banana 2 Lite images or 1 Nano Banana Pro image.
- Top-ups on laozhang.ai take cards through Stripe or USDT.
Get it running in 3 steps
- 1
Create an API key at laozhang.ai (new accounts get $0.1).
- 2
Copy the model ID and code below, and put your key in an environment variable.
- 3
Generate one image to check the response, then scale up.
Endpoint and auth
- Base URL
- https://api2.laozhang.ai
- Authentication
- Bearer API Key
- Request format
- Gemini native
- Reference images
- Supported
- Reference-image limit
- Up to 5 in YingTu (a YingTu limit, not the model maximum)
- Verification status
- No dated test record published yet.
Code example
Swap in your own prompt. For reference images, use the editing example below.
Text-to-image example
export LAOZHANG_API_KEY="replace-with-your-key"
curl --fail-with-body --max-time 500 \
-X POST 'https://api2.laozhang.ai/v1beta/models/gemini-3.1-flash-image:generateContent' \
-H "Authorization: Bearer ${LAOZHANG_API_KEY}" \
-H "Content-Type: application/json" \
--data '{"contents":[{"parts":[{"text":"A clean product photo of a matte ceramic coffee mug on a light stone table, soft window light, natural shadows, minimal styling."}]}],"generationConfig":{"responseModalities":["IMAGE"],"imageConfig":{"imageSize":"2K"}}}'
# The JSON response can contain base64 image data or an image URL.
# If this request times out, check request and billing logs before retrying.Reference-image editing example
import base64
import mimetypes
import os
import sys
import requests
API_KEY = os.environ.get("LAOZHANG_API_KEY")
if not API_KEY:
raise RuntimeError("Set the LAOZHANG_API_KEY environment variable before running this example.")
API_URL = "https://api2.laozhang.ai/v1beta/models/gemini-3.1-flash-image:generateContent"
REQUEST_TIMEOUT_SECONDS = 500
headers = {
"Authorization": f"Bearer {API_KEY}",
"Content-Type": "application/json",
}
def encode_image(image_path):
mime_type = mimetypes.guess_type(image_path)[0] or "image/jpeg"
with open(image_path, "rb") as image_file:
data = base64.b64encode(image_file.read()).decode("ascii")
return {"mime_type": mime_type, "data": data}
reference_1 = encode_image("image_1.jpg") # Replace with your image path
payload = {
"contents": [{
"parts": [
{"text": "A clean product photo of a matte ceramic coffee mug on a light stone table, soft window light, natural shadows, minimal styling."},
{"inline_data": reference_1}
]
}],
"generationConfig": {
"responseModalities": ["IMAGE"],
"imageConfig": {
"imageSize": "2K"
}
}
}
try:
response = requests.post(
API_URL,
headers=headers,
json=payload,
timeout=REQUEST_TIMEOUT_SECONDS,
)
except requests.Timeout as error:
print(
"Request timed out after 500 seconds. The result status may be unknown; "
"check call and billing logs before retrying.",
file=sys.stderr,
)
raise SystemExit(1) from error
if response.status_code != 200:
print(f"API error {response.status_code}: {response.text}", file=sys.stderr)
raise SystemExit(1)
try:
result = response.json()
except ValueError as error:
print("API returned a non-JSON response.", file=sys.stderr)
raise SystemExit(1) from error
if not isinstance(result, dict):
print("API returned an unexpected JSON shape.", file=sys.stderr)
raise SystemExit(1)
image_part = None
for candidate in result.get("candidates", []):
for part in candidate.get("content", {}).get("parts", []):
inline_data = part.get("inlineData") or part.get("inline_data")
if inline_data and inline_data.get("data"):
image_part = inline_data
break
if image_part:
break
if not image_part:
response_id = result.get("responseId", "not provided")
print(f"No image data in response. responseId={response_id}", file=sys.stderr)
raise SystemExit(1)
mime_type = image_part.get("mimeType") or image_part.get("mime_type") or "image/png"
encoded_image = image_part["data"]
if encoded_image.startswith("data:"):
header, encoded_image = encoded_image.split(",", 1)
mime_type = header[5:].split(";", 1)[0] or mime_type
extension_by_mime = {
"image/jpeg": "jpg",
"image/png": "png",
"image/webp": "webp",
"image/gif": "gif",
}
extension = extension_by_mime.get(mime_type, "bin")
output_path = f"output.{extension}"
with open(output_path, "wb") as output_file:
output_file.write(base64.b64decode(encoded_image, validate=True))
print(f"Image saved: {output_path} ({mime_type})")Request parameters
Field names match the YingTu studio and the code examples above.
| Parameter | How it is sent |
|---|---|
| model | Required. Use the exact model ID shown on this page. |
| prompt | Required. Send your image instruction; never place the API key in the prompt. |
| output controls | generationConfig.imageConfig.aspectRatio and imageSize; automatic ratio is omitted. |
| reference images | Optional. Up to 5 images in the YingTu browser are sent as contents[].parts[].inline_data. |
Response and timeout handling
- Image response
- The client looks for base64 image data in
candidates[].content.parts[].inlineDataorinline_dataand preserves the returned MIME type. - Non-image response
- A response without image data is not treated as success. The client reports a block reason, finish reason, or response ID when present.
500-second client timeout
YingTu waits up to 500 seconds. After a timeout the upstream job may still finish, and whether it was billed shows up in your billing log.
No automatic retry
YingTu never retries on its own. Before retrying, check your call and billing logs so you are not charged twice.
Common errors and fixes
- Authentication
- Confirm that the environment variable contains the intended key and that the request sends it as a Bearer credential.
- Access or balance
- Check model access, current balance, billing, and account restrictions in LaoZhang.
- Rate limit
- Reduce concurrency and inspect the returned upstream or account message before trying again.
- Non-image or empty result
- Inspect block and finish reasons, the API message, and any response ID. Revise the prompt only when the response explains why.
- Timeout
- The final state may be unknown. Check call and billing logs before making another request.
Known limitations
Check these before you use a generated image.
- Inspect the downloaded file dimensions; configured output controls do not replace result verification.
- Review identity, logos, packaging, colors, and small brand details before use.
- Availability and latency can vary with upstream capacity.
- Confirm live pricing, balance, access, and charges in the LaoZhang account.
Nano Banana model IDs on this endpoint
Same endpoint, same request; only the model ID changes.
| Model | Model ID | Price | Sizes |
|---|---|---|---|
| Nano Banana 2 Lite | gemini-3.1-flash-lite-image | $0.025/ image | 1K |
| Nano Banana 2 | gemini-3.1-flash-image | $0.055/ image | 512 / 1K / 2K / 4K |
| Nano Banana 2.1 | gemini-nano-banana-2.1 | $0.045/ image | 1K / 2K / 4K |
| Nano Banana Pro | gemini-3-pro-image | $0.09/ image | 1K / 2K / 4K |
API FAQ
How much does the Nano Banana API cost?
Per image, no subscription: Nano Banana 2 Lite $0.025, Nano Banana 2 $0.055, Nano Banana 2.1 $0.045 and Nano Banana Pro $0.09. Your LaoZhang account shows every charge.
How do I get a Nano Banana API key?
Create a token at laozhang.ai (the key button at the top of this page). One key works for every model in the table; new accounts get $0.1 to test.
What is the base URL?
https://api2.laozhang.ai, in the Gemini format: POST /v1beta/models/{model}:generateContent.
Is there a free Nano Banana API?
You can test it for free: new LaoZhang accounts get $0.1, about 4 Nano Banana 2 Lite images or 1 Nano Banana Pro image. After that every call is billed per image from your balance; there is no monthly plan or quota to buy.
Where should I keep the API key?
In the environment variable used by the code example. Never commit it, print it to logs or paste it into a prompt.
Does a timeout mean the request failed?
Not necessarily. YingTu stops waiting after 500 seconds, but the upstream job may still finish and may still be billed. Check your logs before retrying.
Is the reference-image limit set by the model?
No. It is YingTu’s current limit, not the upstream model’s maximum.
Where do I check price and access?
In your LaoZhang account: current price, balance, model access and every charge are listed there.
Price and billing
Billed per image. The price shown is the current LaoZhang rate; actual charges, balance and model access are shown in your LaoZhang account.
- Model ID
- gemini-3.1-flash-image
- Price
- $0.055/ image
- Output sizes
- 512 / 1K / 2K / 4K
- API format
- Gemini native
Try one in the studio first
Every setting here is available in the YingTu image studio, and new users get $0.1 free.
Related pages
YingTuLaoZhang