gemini-3-pro-image (Nano Banana Pro) via APIYI. It explains the output structure of the response JSON and what each usageMetadata field actually means, and clarifies several counting behaviors that look like anomalies but are inherent to the model. All conclusions come from testing against the production gateway (48 text-to-image + 18 image-edit requests), cross-checked against Google’s official docs (ai.google.dev/gemini-api/docs/image-generation), not speculation.
Overall Response Structure
APIYI’s nano banana series uses the Google native format. The response always has four top-level fields:On successful generation
When blocked by safety policies
The HTTP status code is still 200; the difference is inside the candidate:- Three
finishReasonvalues were observed in testing:IMAGE_SAFETY(the output image violates policy),PROHIBITED_CONTENT(a prohibited-use policy was triggered, with an explanatoryfinishMessage), andNO_IMAGE(no image generated, usually returned within seconds). - The refusal explanation lives in the
finishMessagefield — it does not appear as a text part insideparts. - Your parsing code must handle
partsbeingnull, otherwise blocked responses will crash it.
usageMetadata Field Meanings
Successful generations always carry 6 fields:| Field | Meaning | Reliability |
|---|---|---|
promptTokenCount | Input-side total | ✅ Always equals the sum of promptTokensDetails |
candidatesTokenCount | Output-side total | ✅ The billing figure; but greater than the sum of details — see Behavior 1 below |
thoughtsTokenCount | Thinking tokens, typically 50–350 in testing | ✅ |
totalTokenCount | Grand total | ✅ Always equals the sum of the previous three on successful generation; refusals are the exception — see Behavior 2 below |
promptTokensDetails | Input breakdown by modality | ✅ Complete breakdown |
candidatesTokensDetails | Output breakdown by modality | ⚠️ Covers only the image portion — not a complete breakdown |
ai.google.dev/gemini-api/docs/image-generation), fully consistent with our measurements of gemini-3-pro-image:
| Aspect ratio | 1K size | 1K tokens | 2K size | 2K tokens | 4K size | 4K tokens |
|---|---|---|---|---|---|---|
| 1:1 | 1024x1024 | 1120 | 2048x2048 | 1120 | 4096x4096 | 2000 |
| 2:3 | 848x1264 | 1120 | 1696x2528 | 1120 | 3392x5056 | 2000 |
| 3:2 | 1264x848 | 1120 | 2528x1696 | 1120 | 5056x3392 | 2000 |
| 3:4 | 896x1200 | 1120 | 1792x2400 | 1120 | 3584x4800 | 2000 |
| 4:3 | 1200x896 | 1120 | 2400x1792 | 1120 | 4800x3584 | 2000 |
| 4:5 | 928x1152 | 1120 | 1856x2304 | 1120 | 3712x4608 | 2000 |
| 5:4 | 1152x928 | 1120 | 2304x1856 | 1120 | 4608x3712 | 2000 |
| 9:16 | 768x1376 | 1120 | 1536x2752 | 1120 | 3072x5504 | 2000 |
| 16:9 | 1376x768 | 1120 | 2752x1536 | 1120 | 5504x3072 | 2000 |
| 21:9 | 1584x672 | 1120 | 3168x1344 | 1120 | 6336x2688 | 2000 |
In Google’s official table, the column header
1K tokens means “the token count for the 1K resolution tier” — the actual per-image token count is the cell value: 1120 per image at 1K/2K, 2000 at 4K. (The Chinese localization of that page renders the header as “1,000 tokens”, which is easy to misread as the per-image count.) Also note the 512px tier (747 tokens per image) exists only for the Flash image models — gemini-3-pro-image supports 1K/2K/4K only.Three Behaviors That Look Like Anomalies
Behavior 1: candidatesTokenCount ≠ sum of candidatesTokensDetails — normal and inevitable
In testing, 100% of samples (49/49 successful generations) showedcandidatesTokenCount exceeding the sum of details by 88–630 tokens (the more complex the prompt and the more images returned, the bigger the gap).
Reason: candidatesTokensDetails counts only the image payload itself (fixed 1120/2000 per image), while candidatesTokenCount also includes internal tokens generated alongside the image-generation process, which have no corresponding modality entry. This is Gemini’s native counting convention; APIYI passes it through unchanged.
Bottom line: do not treat details as a complete breakdown of
candidatesTokenCount for validation. For reconciliation and billing, always use candidatesTokenCount / totalTokenCount; details are only useful for estimating the image share.Behavior 2: totalTokenCount ≠ prompt + candidates + thoughts — only on responses with no image output
- On successful generation, the equation holds strictly (49/49):
total = promptTokenCount + candidatesTokenCount + thoughtsTokenCount. - On safety-blocked responses (no image output), the equation never holds (6/6), with a fixed pattern:
candidatesTokenCount mirrors thoughtsTokenCount, so summing the three fields double-counts the thinking tokens. This is also upstream-inherent behavior. totalTokenCount itself is accurate — just use it directly. If about 10% of the responses in your logs “don’t balance”, check whether those responses have empty parts — they are almost certainly safety-blocked samples.
Behavior 3: output tokens occasionally hit 6000+ — caused by multiple image parts from the thinking process
Google’s official docs state that Gemini 3 image models are thinking models: “Thinking” is enabled by default and cannot be disabled in the API. The model generates interim images to test composition and logic, and “the last image within Thinking is also the final rendered image” (source: the Thinking Process section ofai.google.dev/gemini-api/docs/image-generation).
In our testing, these interim thinking drafts come back in the native generateContent response as ordinary image parts: every part carries a thoughtSignature field but no thought: true flag, and each one is counted at 1120 tokens in candidatesTokensDetails. Google’s docs say Thinking generates at most two interim images, but with complex task-style prompts we observed up to 10 image parts in a single response. Usage grows strictly linearly with the image count:
| Images returned | candidatesTokensDetails | candidatesTokenCount | totalTokenCount |
|---|---|---|---|
| 1 (text-to-image, 1K) | 1120 | ~1210–1275 | ~1350–1450 |
| 2 | 2240 | ~2500 | ~3300 |
| 3 | 3360 | ~3800 | ~4600 |
| 4 | 4480 | ~5000 | ~5900 |
| 5 | 5600 | ~6200 | ~7000 |
| 10 | 11200 | ~12700 | ~13500 |
thoughtsTokenCount field only counts text thinking and never exceeded 400 in testing — the source of high output tokens is the number of image parts, not this field. When you see 6000+ or even five-digit output tokens, check the number of parts in that response — it is almost certainly a multi-image response and normal billing (still reconcile with totalTokenCount).
Thinking Levels & the Two API Paradigms
How thinkingLevel affects tokens
Thinking-level control is only supported by Gemini 3.1 Flash Image / Flash Lite Image (generationConfig.thinkingConfig.thinkingLevel, default minimal, or high); on gemini-3-pro-image thinking is always on and cannot be adjusted. Measured (same prompt, 1K text-to-image, via the APIYI gateway):
| Model / setting | thoughtsTokenCount | Image tokens | totalTokenCount | Latency |
|---|---|---|---|---|
| gemini-3.1-flash-image · minimal (default) | field absent | 1120 | ~1534–1554 | ~12–13s |
| gemini-3.1-flash-image · high | 700–792 | 1120 | ~2243–2375 | ~18–23s |
| gemini-3-pro-image · high passed in | 181–214 (same as default range) | 1120 | ~1427–1471 | ~23s |
highonly increases thinking tokens and latency — image tokens stay unchanged (still 1120 per image).- Passing
thinkingLeveltogemini-3-pro-imagedoes not error, but has no measurable effect — thinking tokens stay in the default range. includeThoughts: truechanged neither the response structure nor billing in testing; Google states explicitly that thinking tokens are billed by default whether or not you view the thinking process.- Google also notes that “minimal thinking does not mean the model does no thinking at all” — under
minimalthe usage simply stops listing a separatethoughtsTokenCountfield.
How image-model thinking tokens differ from text models
- Text thinking models: the thinking output is text;
thoughtsTokenCountcan reach thousands and is billed at the output-token price. Officially, pricing is based on the full internal thoughts the model generates, even though the API only returns thought summaries (source: the pricing section ofai.google.dev/gemini-api/docs/thinking). - Image thinking models: thinking produces two kinds of output — a small amount of text thinking counted in
thoughtsTokenCount(measured: up to 400 on Pro, ~800 on Flash athigh), and interim draft images, which come back as ordinary image parts billed at 1120/2000 tokens each intocandidatesTokenCount. So for image models the “cost of thinking” mostly shows up in the number of image parts, not in thethoughtsTokenCountfield (see Behavior 3 above).
The two API paradigms
Google’s image-model docs now come in two flavors: the classic generateContent API (stateless) and the newly recommended Interactions API (built for agents and tools). The APIYI gateway uses the Google native generateContent format — everything in this page is based on it. The thinking-related differences:| generateContent (this page) | Interactions API | |
|---|---|---|
| Thinking-level parameter | generationConfig.thinkingConfig.thinkingLevel | generation_config.thinking_level |
| Thought content in response | includeThoughts switch (no visible effect for image models in testing; interim drafts always come back as ordinary image parts) | returned explicitly as steps (type: "thought"), no includeThoughts switch |
| Usage field names | thoughtsTokenCount / candidatesTokenCount / totalTokenCount | total_thought_tokens / total_output_tokens |
Parsing & Reconciliation Best Practices
- Reconcile billing with
totalTokenCount(it is accurate even for refusals); do not validate by summing the three fields yourself or by summing details. - Iterate over parts — never assume a single image; any per-image business logic should go by the actual number of
inlineDataparts. - Handle blocked responses with
parts = null+ HTTP 200, branching onfinishReason. - Simple edits take ~22–25s; complex tasks (multi-image responses) take 35–142s, longer with more images. Set client timeouts to ≥ 5 minutes (including any proxy layer).
Related Docs
Nano Banana Dev Guide
Integration methods, input image requirements, billing basics, timeout settings, and the multi-image explainer
Error Handling Guide
The three key indicators for diagnosing failed generations, content moderation policies, and friendly prompt strategies
Failed Generation Guarantee Plan
For failures not caused by your input, credits are reimbursed per the number of failed requests
Nano Banana Pricing
Per-image pricing across resolutions and model tiers