Generate Images
November 17, 2025 (June 5, 2026)
Table of contents
- Model Capabilities
- Content Moderation
- Response Codes
- Request Headers
- Request Body
- Responses
- Model
- Examples
- Try It
Generate images using AI models Imagen 4, Nano Banana / Gemini 2.5 Flash Image, Nano Banana 2 / Gemini 2.5 Pro Image, and Nano Banana Pro / Gemini 3 Pro Image from text prompts with optional reference images. Use any Google AI subscription or even free account for image generations.
This endpoint features dynamic concurrency management, allowing anywhere from 3 to 20 parallel generations depending on real-time capacity. Image generation typically completes within 10-20 seconds.
Model Capabilities
| Parameter | Imagen 4imagen-4 (default) | Nano Banana 2nano-banana-2 | Nano Banana Pronano-banana-pro |
|---|---|---|---|
| T2I (text-to-image) | ✓ | ✓ | ✓ |
| I2I (reference images) | ✓ (max 3) | ✓ (max 10) | ✓ (max 10) |
| Aspect ratios | 16:9, 4:3, 1:1, 3:4, 9:16 | 16:9, 4:3, 1:1, 3:4, 9:16, auto† | 16:9, 4:3, 1:1, 3:4, 9:16, auto† |
| Default aspect ratio | 16:9 | 16:9 (T2I) / auto (I2I) | 16:9 (T2I) / auto (I2I) |
count | ✓ (1-4) | ✓ (1-4) | ✓ (1-4) |
seed | ✓ | ✓ | ✓ |
| Subscription | all | all | all |
† auto is only valid in image-to-image mode (at least one reference_* provided) — the backend derives the aspect ratio from the first reference image.
Legacy alias nano-banana is still accepted and maps to nano-banana-2.
Content Moderation
If your generation is moderated, retrying with the same prompt often succeeds on subsequent attempts — moderation decisions can vary between requests. Alternatively, switching between imagen-4, nano-banana-2, and nano-banana-pro models may help, as each has different content-moderation behavior.
Response Codes
429 — Rate limit / quota exhausted
Google returns at least four known distinct RESOURCE_EXHAUSTED variants in the response body. Always check the reason field on the returned error to pick the right strategy:
| Reason code | What it means | What to do |
|---|---|---|
PUBLIC_ERROR_UNUSUAL_ACTIVITY_TOO_MUCH_TRAFFIC | This is a captcha-provider issue, not a useapi.net issue. Google’s reCAPTCHA Enterprise scored the captcha token below its risk threshold — usually because the provider is overloaded or being fingerprinted by Google (the provider’s infrastructure is processing too many high-volume requests at once and Google flags them collectively). Our worker has already auto-retried with fresh captcha tokens (up to captchaRetry attempts, default 3) before returning this. | Spread the load across multiple captcha providers — configure several providers via POST /accounts/captcha-providers (e.g. CapSolver + AntiCaptcha + 2Captcha) and use captchaOrder on the request to cycle through them. Adding balance to existing providers can also help, since some prioritize higher-balance accounts. As a short-term measure, wait 30-60s and retry, or bump captchaRetry higher in the request body. |
PUBLIC_ERROR_USER_REQUESTS_THROTTLED | Google-side per-user concurrency limit. The token was fine; this account is sending too many requests at once. | Hold for ~hour, retry after 10-60min. Reduce parallel generations per account. |
PUBLIC_ERROR_PER_MODEL_DAILY_QUOTA_REACHED | This account hit Google’s per-model daily quota. Retrying within the day will not succeed. | Hold for the day (quota resets at UTC midnight), or switch to a different model. |
PUBLIC_ERROR_USER_QUOTA_REACHED | This account hit its overall Google Flow quota cap — separate from per-model limits, blocks all models on this account. | Add more Google Flow accounts via POST /accounts so the load is spread. Hold this specific account until the quota resets, or omit email in your request to let load balancing pick a healthier account. |
Automatic quarantine. When you omit email, the load balancer automatically quarantines an account on any of PUBLIC_ERROR_USER_QUOTA_REACHED, PUBLIC_ERROR_PER_MODEL_DAILY_QUOTA_REACHED, or PUBLIC_ERROR_USER_REQUESTS_THROTTLED and routes subsequent requests to the remaining healthy accounts. See Quarantine pre-filter for the TTLs and exact behavior.
If every account is quarantined for the requested model, the response is 429 with error: "no_eligible_account" plus a Retry-After header — see the example payload in the 429 response tab below.
503 — Service unavailable
Transient Google-side issue. Wait 5-10 seconds and retry. If the response body says "Captcha service failed", the issue is with your captcha provider (check API key and balance) rather than Google — don’t retry until the provider is back.
403 — Request rejected by Google
Captcha token rejected by Google despite our internal retries — a captcha-provider issue. Increase captchaRetry (default 3) in the request body to 5 or higher, and configure additional providers via POST /accounts/captcha-providers so captchaOrder can cycle across them. If issues persist, contact your reCAPTCHA provider(s) support.
https://api.useapi.net/v1/google-flow/images
Request Headers
Authorization: Bearer {API token}
Content-Type: application/json
# Alternatively you can use multipart/form-data
# Content-Type: multipart/form-data
API tokenis required, see Setup useapi.net for details.
Request Body
{
"prompt": "A serene mountain landscape at sunset with vibrant colors",
"model": "imagen-4",
"aspectRatio": "16:9",
"count": 4,
"seed": 123456
}
-
emailis optional. The email address of the Google Flow account to use.When only one account is configured, the API will automatically use that account.
With multiple accounts configured, omitting the email parameter triggers automatic load balancing based on image generation job statistics to select the healthiest account.
If reference images (
reference_1to_10) are provided, theemailparameter can be omitted—the API will automatically use the same account where the images were uploaded. promptis required, text description for image generation.modelis optional, the AI model to use for image generation (default:imagen-4).
Supported values:imagen-4,nano-banana-2,nano-banana-pro. Legacy aliasnano-bananais still accepted and maps tonano-banana-2.aspectRatiois optional, output image aspect ratio. Supported values:16:9,4:3,1:1,3:4,9:16,auto. Legacy aliaseslandscape(→16:9) andportrait(→9:16) are still accepted.autois only valid withnano-banana-2ornano-banana-prowhen at least onereference_*is provided — the backend derives the aspect ratio from the first reference image. Default:- text-to-image (no references):
16:9 imagen-4image-to-image:16:9nano-banana-2/nano-banana-proimage-to-image:auto
- text-to-image (no references):
countis optional, number of image variations to generate (1-4, default:4).seedis optional, random seed for reproducible results (integer ≥ 0).reference_1toreference_10are optional, usemediaGenerationIdfrom POST /assets/emailfor reference images.imagen-4supports max 3 references,nano-banana-2andnano-banana-prosupport up to 10.character_1tocharacter_7are optional, character reference-ids from POST /characters. Characters mix freely withreference_*— they share the same per-model image-ref budget on Google’s side (per-character image counts roll into the total). Imagen models that don’t accept reference images also don’t accept characters.replyUrlis optional, webhook URL for job status callbacks. Receives POST requests with job status updates (created,completed,failed). The JSON payload shape matches GET /jobs/jobIdresponse. Callbacks timeout after 5 seconds.replyRefis optional, custom reference string passed back in webhook callbacks. Useful for tracking jobs on your end.captchaToken,captchaRetry,captchaOrderare optional, mutually exclusive captcha parameters. See Captcha Parameters for details.
Auto-detection: If model is not specified: with references selects nano-banana-2, without references defaults to imagen-4.
Responses
-
Images generated successfully. Returns job ID and media array with generated image data.
{ "jobId": "j1731859345678i-u12345-email:jo***@gmail.com-bot:google-flow", "media": [ { "name": "…redacted…", "workflowId": "…redacted…", "image": { "generatedImage": { "seed": 123456, "mediaGenerationId": "user:12345…redacted…", "mediaVisibility": "PRIVATE", "prompt": "A serene mountain landscape at sunset with vibrant colors", "modelNameType": "IMAGEN_3_5", "workflowId": "…redacted…", "fifeUrl": "https://storage.googleapis.com/…redacted…", "aspectRatio": "IMAGE_ASPECT_RATIO_LANDSCAPE", "requestData": { "promptInputs": [ { "textInput": "A serene mountain landscape at sunset with vibrant colors" } ], "imageGenerationRequestData": { "imageGenerationImageInputs": [] } } } } } ], "captcha": { "service": "AntiCaptcha", "taskId": "abc123...", "durationMs": 3500, "attempts": [ { "service": "AntiCaptcha", "taskId": "abc123...", "durationMs": 3500, "success": true } ] } } -
Invalid request (validation error, reference count exceeded, email mismatch, or content policy violation).
General error:
{ "error": "Invalid request parameters" }Content policy error:
{ "error": { "code": 400, "message": "Request contains an invalid argument.", "status": "INVALID_ARGUMENT", "details": [ { "@type": "type.googleapis.com/google.rpc.ErrorInfo", "reason": "PUBLIC_ERROR_UNSAFE_GENERATION" } ] } } -
Invalid API token.
{ "error": "Unauthorized" } -
Subscription expired or insufficient credits.
{ "error": "Account has no subscription or subscription expired" } -
Request rejected by Google. See Response Codes › 403 above for guidance. Example payload:
{ "code": 403, "created": "2025-12-23T21:54:26.393Z", "error": "API error: 403", "jobid": "j1223215426393445325i-u12345-email:us***@gmail.com-bot:google-flow", "request": { "aspectRatio": "portrait", "count": 4, "email": "us***@gmail.com", "model": "nano-banana-pro", "prompt": "A serene mountain landscape at sunset", "reference_1": { "email": "us***@gmail.com", "id": "CAMaJDMxZGNl...***...YmUwMmM", "referenceId": "user:12345-email:***-image:CAMaJDMxZGNl...***...YmUwMmM", "type": "image", "user": 12345 } }, "response": { "captcha": { "attempts": [ { "service": "AntiCaptcha", "taskId": "14af1dbb-885c-4e25-8121-7a79489dfd0e", "durationMs": 5357, "success": true }, { "service": "AntiCaptcha", "taskId": "fd044078-0a4a-4303-a585-26fd5d2acb00", "durationMs": 5376, "success": true }, { "service": "AntiCaptcha", "taskId": "ab0251dc-6930-4a82-966a-71fe6ab6aa42", "durationMs": 5789, "success": true } ], "durationMs": 18091, "service": "AntiCaptcha", "taskId": "ab0251dc-6930-4a82-966a-71fe6ab6aa42" }, "error": { "code": 403, "details": [ { "@type": "type.googleapis.com/google.rpc.ErrorInfo", "reason": "PUBLIC_ERROR_SOMETHING_WENT_WRONG" } ], "message": "reCAPTCHA evaluation failed", "status": "PERMISSION_DENIED" } }, "status": "failed", "type": "image", "updated": "2025-12-23T21:54:45.319Z" } -
Account not found or not configured.
{ "error": "Google Flow account [email protected] not found" } -
Google returns at least four known distinct
RESOURCE_EXHAUSTEDvariants. See Response Codes › 429 above for the right strategy per reason. Example payloads:Example — reCAPTCHA evaluation failed (
PUBLIC_ERROR_UNUSUAL_ACTIVITY_TOO_MUCH_TRAFFIC):{ "error": { "code": 429, "message": "reCAPTCHA evaluation failed", "status": "RESOURCE_EXHAUSTED", "details": [ { "@type": "type.googleapis.com/google.rpc.ErrorInfo", "reason": "PUBLIC_ERROR_UNUSUAL_ACTIVITY_TOO_MUCH_TRAFFIC" } ] } }Example — per-user throttling:
{ "error": { "code": 429, "message": "Resource has been exhausted (e.g. check quota).", "status": "RESOURCE_EXHAUSTED", "details": [ { "@type": "type.googleapis.com/google.rpc.ErrorInfo", "reason": "PUBLIC_ERROR_USER_REQUESTS_THROTTLED" } ] } }Example — per-model daily quota reached (e.g., using
nano-banana-proon non-Ultra account):{ "error": { "code": 429, "message": "Resource has been exhausted (e.g. check quota).", "status": "RESOURCE_EXHAUSTED", "details": [ { "@type": "type.googleapis.com/google.rpc.ErrorInfo", "reason": "PUBLIC_ERROR_PER_MODEL_DAILY_QUOTA_REACHED", "metadata": { "canUpgradeForQuota": "true" } } ] } }Example — account-wide quota reached (
PUBLIC_ERROR_USER_QUOTA_REACHED):{ "error": { "code": 429, "message": "Resource has been exhausted (e.g. check quota).", "status": "RESOURCE_EXHAUSTED", "details": [ { "@type": "type.googleapis.com/google.rpc.ErrorInfo", "reason": "PUBLIC_ERROR_USER_QUOTA_REACHED" } ] } }Example — every configured account is quarantined for the requested model (
no_eligible_account):When you omit
emailand every one of your accounts is currently quarantined for the requested model (see Quarantine pre-filter), the API short-circuits with this429response — no upstream call to Google is made. Response headers includeRetry-After: <seconds>per RFC 7231.{ "error": "no_eligible_account", "message": "All your Google Flow accounts have hit Google's daily quota for model 'nano-banana-pro'. This quota resets at UTC midnight (2026-05-20T00:00:10.000Z). Try a different model, or wait.", "retryAfter": "2026-05-20T00:00:10.000Z", "skipReasons": [ { "email": "[email protected]", "reason": "PUBLIC_ERROR_PER_MODEL_DAILY_QUOTA_REACHED", "model": "nano-banana-pro" }, { "email": "[email protected]", "reason": "PUBLIC_ERROR_PER_MODEL_DAILY_QUOTA_REACHED", "model": "nano-banana-pro" } ] }skipReasonslists every account considered and the reason it was filtered, so you can decide whether to wait, switch model, or add more accounts. To bypass the load balancer entirely, specifyemailexplicitly — the request will be sent to Google regardless of quarantine state. -
One or more generated images were moderated by Google’s content policy. Try one of the following:
- Switch to
imagen-4model (often successfully processes prompts rejected bynano-banana) - Modify your prompt or remove/change reference images
- Retry the same request (moderation decisions can vary between attempts)
{ "error": { "code": 500, "message": "Internal error encountered.", "status": "INTERNAL" } } - Switch to
-
Service temporarily unavailable or captcha provider error. See Response Codes › 503 above for guidance. Example payloads:
{ "error": { "code": 503, "message": "Service temporarily unavailable.", "status": "UNAVAILABLE", "details": [ { "@type": "type.googleapis.com/google.rpc.ErrorInfo", "reason": "SERVICE_UNAVAILABLE" } ] } }{ "error": "Captcha service failed: ERROR_ZERO_BALANCE", "code": 503 } -
596 Session Error
Google session refresh failed. The account cookies needs to be updated following the instructions in Setup Google Flow.
{ "error": "Failed to refresh session." }
Model
jobId- Unique job identifier (for use with GET /jobs/jobId)media- Array of generated images (1-4 images based oncount)media[].image.generatedImage- Generated image data objectgeneratedImage.fifeUrl- Direct signed URL to access the generated image (valid for limited time)generatedImage.seed- Seed used for this generation (for reproducibility)generatedImage.mediaGenerationId- mediaGenerationId for use in subsequent API callsgeneratedImage.prompt- The prompt used for generationgeneratedImage.modelNameType- Model variant used (IMAGEN_3_5,R2I,GEM_PIX,GEM_PIX_2,NARWHAL)generatedImage.aspectRatio- Generated image aspect ratio (IMAGE_ASPECT_RATIO_LANDSCAPE,IMAGE_ASPECT_RATIO_LANDSCAPE_FOUR_THREE,IMAGE_ASPECT_RATIO_SQUARE,IMAGE_ASPECT_RATIO_PORTRAIT_THREE_FOUR, orIMAGE_ASPECT_RATIO_PORTRAIT)generatedImage.mediaVisibility- Visibility setting (always “PRIVATE”)generatedImage.workflowId- Unique workflow identifiergeneratedImage.requestData- Request data used for this generation including prompt inputs and reference imagesmedia[].name- Internal identifier for the media itemmedia[].workflowId- Unique workflow identifier for this generationcaptcha- Captcha metadata for debugging/researchcaptcha.service- Provider that returned the successful tokencaptcha.taskId- Task ID from the captcha servicecaptcha.durationMs- Total time for all captcha attemptscaptcha.attempts- Array of all captcha attempts (including failures)
{
jobId: string // Job identifier
media: Array<{
name: string // Internal media identifier
workflowId: string // Unique workflow ID
image: {
generatedImage: {
seed: number
mediaGenerationId: string // Format: user:{userid}-email:{hex}-image:{id}
mediaVisibility: string // "PRIVATE"
prompt: string
modelNameType: string // "IMAGEN_3_5" | "R2I" | "GEM_PIX" | "GEM_PIX_2" | "NARWHAL"
workflowId: string
fifeUrl: string // Direct signed URL to generated image
aspectRatio: string // "IMAGE_ASPECT_RATIO_LANDSCAPE" | "IMAGE_ASPECT_RATIO_LANDSCAPE_FOUR_THREE" | "IMAGE_ASPECT_RATIO_SQUARE" | "IMAGE_ASPECT_RATIO_PORTRAIT_THREE_FOUR" | "IMAGE_ASPECT_RATIO_PORTRAIT"
requestData: {
promptInputs: Array<{
textInput: string
}>
imageGenerationRequestData: {
imageGenerationImageInputs: Array<{
mediaGenerationId: string
imageInputType: string // "IMAGE_INPUT_TYPE_REFERENCE"
}>
}
}
}
}
}>
captcha?: { // Captcha metadata
service: string // "CapSolver" | "AntiCaptcha" | "YesCaptcha" | "CapMonster" | "SolveCaptcha" | "2Captcha" | "EzCaptcha" | "UserProvided"
taskId?: string
durationMs: number
attempts: Array<{
service: string
taskId?: string
durationMs: number
success: boolean
error?: string
}>
}
error?: string | { // Error: string (useapi.net) or object (Google API)
code: number
message: string
status: string
details: Array<{
'@type': string
reason: string
metadata?: {
canUpgradeForQuota: boolean
}
}>
}
// The following siblings appear only on the load-balancer empty-set 429,
// i.e. when error === "no_eligible_account" (see 429 response tab).
message?: string // Customer-facing explanation
retryAfter?: string // ISO-8601 timestamp of earliest retry
skipReasons?: Array<{ // Per-account filter rationale
email: string
reason: string // Google 429 reason that triggered the quarantine
model: string // Quarantined model, or "*" for account-wide
}>
}
Examples
-
curl -X POST \ -H "Authorization: Bearer YOUR_API_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "prompt": "A serene mountain landscape at sunset with vibrant colors", "model": "imagen-4", "aspectRatio": "16:9", "count": 4, "seed": 123456 }' \ "https://api.useapi.net/v1/google-flow/images" > response.json # Download images using fifeUrl curl -o image_1.jpg "$(cat response.json | jq -r '.media[0].image.generatedImage.fifeUrl')" curl -o image_2.jpg "$(cat response.json | jq -r '.media[1].image.generatedImage.fifeUrl')" # Continue for remaining images... -
const token = 'YOUR_API_TOKEN'; const apiUrl = 'https://api.useapi.net/v1/google-flow/images'; const response = await fetch(apiUrl, { method: 'POST', headers: { 'Authorization': `Bearer ${token}`, 'Content-Type': 'application/json' }, body: JSON.stringify({ prompt: 'A serene mountain landscape at sunset with vibrant colors', model: 'imagen-4', aspectRatio: '16:9', count: 4, seed: 123456 }) }); const result = await response.json(); console.log('Generated images:', result.media.length); // Download and save images for (const [index, item] of result.media.entries()) { const img = item.image.generatedImage; console.log(`Image ${index + 1} seed:`, img.seed); console.log(`mediaGenerationId:`, img.mediaGenerationId); // Download image from fifeUrl const imageResponse = await fetch(img.fifeUrl); const imageBlob = await imageResponse.blob(); // In Node.js with fs: // const buffer = Buffer.from(await imageBlob.arrayBuffer()); // require('fs').writeFileSync(`generated_image_${index + 1}.jpg`, buffer); // In browser: create download link or display in <img> element // const url = URL.createObjectURL(imageBlob); // document.querySelector('img').src = url; } -
import requests token = 'YOUR_API_TOKEN' api_url = 'https://api.useapi.net/v1/google-flow/images' headers = { 'Authorization': f'Bearer {token}', 'Content-Type': 'application/json' } data = { 'prompt': 'A serene mountain landscape at sunset with vibrant colors', 'model': 'imagen-4', 'aspectRatio': '16:9', 'count': 4, 'seed': 123456 } response = requests.post(api_url, headers=headers, json=data) result = response.json() print(f"Generated {len(result['media'])} images") # Download and save images for index, item in enumerate(result['media']): img = item['image']['generatedImage'] print(f"Image {index + 1} seed:", img['seed']) print(f"mediaGenerationId:", img['mediaGenerationId']) # Download image from fifeUrl image_response = requests.get(img['fifeUrl']) with open(f'generated_image_{index + 1}.jpg', 'wb') as f: f.write(image_response.content)