Tool setup

Build a batch image generation pipeline that cannot overrun its budget

There is no batch endpoint to call. On both published image routes, one admitted request returns exactly one candidate image, so a production batch pipeline is your own durable queue in front of Nano Banana 2 (gemini-3.1-flash-image) or GPT Image 2 — with bounded workers, per-asset attempt budgets, terminal-usage reconciliation and a key-level lifetime spending limit as the final monetary boundary.

·

One admitted call returns one candidate

Neither public image route accepts a count, a manifest or a folder of prompts. A Gemini generateContent call on gemini-3.1-flash-image returns one candidate whose image travels as base64 in inlineData; an OpenAI-compatible POST /v1/images/generations on gpt-image-2 returns a single-element data array with b64_json. The model never sees "make 500 variations" — batch size is a property of your queue, not of the request.

// gemini-3.1-flash-image → one candidate, image as base64 inlineData
{
  "candidates": [
    { "content": { "parts": [ { "inlineData": { "mimeType": "image/png", "data": "<base64>" } } ] } }
  ],
  "usageMetadata": { "promptTokenCount": 24, "candidatesTokenCount": 1120, "totalTokenCount": 1144 }
}

// gpt-image-2 → single-element data array, image as b64_json
{
  "created": 1754800000,
  "data": [ { "b64_json": "<base64>" } ],
  "usage": { "input_tokens": 38, "output_tokens": 4096, "total_tokens": 4134 }
}

Plan storage for both shapes at design time: decode the base64 payload once, checksum the bytes and persist them beside the job. A URL-shaped output, when a route returns one, is a fetch task with its own expiry — not a durable asset.

See also: How image generation API pricing actually works

One durable job per asset, not per prompt

  1. 01Create a stable asset ID and an immutable brief — prompt, references, protected traits — before anything is enqueued.
  2. 02Resolve the model, protocol, output size and maximum attempts into the job payload, so a retry replays the same decision rather than making a new one.
  3. 03Give each worker a bounded slice of the queue and reserve one provider request per candidate; never ask the model for an internal batch.
  4. 04Persist the request ID, terminal usage, output checksum and validation verdict atomically with the asset version.
  5. 05Mark the job complete only after storage and downstream publication both confirm the same asset version.
{
  "asset_id": "catalog/sku-1042/hero-v3",
  "idempotency_key": "sku-1042:hero-v3:attempt-1",
  "model": "gemini-3.1-flash-image",
  "size": "1K",
  "max_attempts": 2,
  "spending_key": "image-production"
}

Cost math for a 500-SKU run

Nano Banana 2 publishes fixed image-output legs: 1K is 1,120 image tokens, $0.0672 officially and $0.0336 for a regular B2C account; after the same 50% policy, 2K is $0.0504 and 4K is $0.0756. GPT Image 2 has no honest per-picture constant: its image output bills at $15 per 1M tokens for regular B2C, and the settled total follows terminal usage. Work the example with the fixed leg, because that is the only part you can know before the run.

LineValue
Assets in the campaign500 SKUs
Candidates per asset2
Admitted calls1,000
Image output per 1K candidate (regular B2C)$0.0336
Base image-output spend1,000 × $0.0336 = $33.60
Retry budget: 10% of assets, one extra attempt+$3.36
Worst-case image-output spend$36.96

This is the image-output leg only. Text and image input, optional text or thinking output, and grounding are added from terminal usage. The 50% B2C discount halves official usage; it does not cap the product of assets × candidates × retries × resolution — that product is yours to bound.

The per-leg token rates behind this batch math

Bound every multiplier, not just the price

MultiplierGuardrail
AssetsExplicit queue length and campaign budget
VariantsMaximum candidates per asset
RetriesOnly proven not-started attempts; total deadline
ResolutionDefault 1K; promote by delivery rule
ReferencesOnly files required by the brief
ConcurrencySmall worker ceiling with 429 cooling

A key's lifetime spending limit is the last monetary boundary when every application-level guardrail fails. Set it to the campaign budget plus a measured safety margin — not to the account balance.

Retry, cooling and observability rules

  • Never retry after image bytes or a complete provider response were delivered — that retry is a second paid candidate, not a recovery.
  • Treat an ambiguous timeout as reconciliation work: match the request ID against the dashboard charge before concluding that no billable generation happened.
  • Honor 429 responses with Retry-After, provider cooling and jitter inside a total deadline; immediate fan-out amplifies a capacity event.
  • Track attempts, accepted assets, settled nanoUSD and validation failure reasons; keep prompts and keys out of metrics.
  • Alert on cost per accepted asset and failure share, not only on HTTP success rate — a fully green batch can still be an expensive one.

Settled cost per accepted asset is the batch's real unit economics: it folds token price, resolution, retries and quality rejects into the single number the business actually buys.

Isolate the batch lane with its own key and budget

Run the batch worker on a dedicated key with a lifetime spending limit and an expiration date, so a queue bug can exhaust only the campaign budget, never the account. A new account created with Google or GitHub starts with $5 of platform bonus credit — enough to validate the pipeline end to end before the first top-up; after that, fund any whole-dollar amount by bank card or cryptocurrency such as USDT or BTC. The prepaid balance never expires, and there is no subscription to size.

  • One key per workload: batch generation never shares a key with interactive or editing traffic.
  • Reconcile every settled charge against its request ID before the campaign is closed.
  • Re-check the lifetime spending limit before each new campaign, not once at setup.

Prepaid plans that never expire: fund exactly the campaign budget

Frequently asked questions

Can one API request generate a whole batch of images?

No, on the published routes. One admitted call returns one candidate image; there is no count parameter that multiplies it. Batch size, ordering and concurrency belong to your durable queue — which is also where budgets are enforced before any money moves.

How much would a 1,000-image batch cost?

On Nano Banana 2 at 1K, the fixed image-output leg is 1,120 tokens per candidate — $0.0336 for regular B2C — so 1,000 candidates cost $33.60 of image output, plus input and optional grounding legs from terminal usage. GPT Image 2 bills image output at $15 per 1M tokens for regular B2C with no fixed per-image constant, so its batch total is known only from settled usage.

How do I stop a runaway image batch?

Combine a dedicated key carrying a lifetime spending limit, an explicit queue length, bounded workers, a per-asset maximum attempt count and a total campaign budget. Each layer fails independently, and the key-level limit is the boundary that holds even if all the others misbehave.

Should 429 responses be retried immediately?

No. Respect Retry-After and provider cooling, add jitter and keep a total deadline per job. Immediate fan-out during a capacity event converts a slowdown into an outage you paid to create.

Should the pipeline store the base64 payload or a URL?

Treat the API response as transport, not storage. Decode base64 once, checksum and persist the bytes in your own object storage, then publish optimized WebP/AVIF derivatives; never serve the raw API payload as a storefront asset.

Does the 50% discount apply to every call in a batch?

For regular B2C accounts it applies to the official usage of every admitted call, generation or edit. B2B accounts follow their negotiated policy, and OpenKeys bill 1:1 at official prices. A discount never proves that a model is currently available to a particular key.

Create an account with Google or GitHub and test the gateway with $5 of platform bonus credit.