Gemini Image

Model (used in the path)PositioningAvailable imageSize
gemini-3-pro-imageQuality tier1K / 2K / 4K
gemini-3.1-flash-imageSpeed / cost balance512px / 1K / 2K / 4K
gemini-3.1-flash-lite-imageLowest cost1K only

The ModelGo gateway accepts image generation requests on the Gemini API generateContent protocol unchanged: contents + generationConfig, returning candidates[].content.parts[].inlineData synchronously. The gateway routes to a supplier and bills the call; which supplier renders the image is invisible to the caller. The model name in the URL path is authoritative — the body does not carry a model.

With the Google GenAI SDK, point http_options.base_url at https://api.modelgo.ai and use your ModelGo API key as api_key. Both x-goog-api-key: $KEY and Authorization: Bearer $KEY are accepted.

>

Google's newer Interactions API is not yet supported; use generateContent.

1. Create an image

POST https://api.modelgo.ai/v1beta/models/{model}:generateContent (also accepted under /v1/models/...)

Text to image

bash
curl "https://api.modelgo.ai/v1beta/models/gemini-3.1-flash-image:generateContent" \
  -H "x-goog-api-key: $MODELGO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "contents": [{"role": "user", "parts": [{"text": "A fluffy orange cat sitting on a sunny windowsill, film grain"}]}],
    "generationConfig": {
      "responseModalities": ["IMAGE"],
      "imageConfig": {"aspectRatio": "16:9", "imageSize": "2K"}
    }
  }'

Image to image

Put reference images into parts as inlineData (base64) or fileData (public URL):

bash
curl "https://api.modelgo.ai/v1beta/models/gemini-3-pro-image:generateContent" \
  -H "x-goog-api-key: $MODELGO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "contents": [{"role": "user", "parts": [
      {"text": "Replace the background with a neon night street, keep the cat's pose"},
      {"inlineData": {"mimeType": "image/png", "data": "<base64>"}}
    ]}],
    "generationConfig": {"responseModalities": ["IMAGE"], "imageConfig": {"aspectRatio": "1:1", "imageSize": "1K"}}
  }&#39;

fileData form: {"fileData": {"fileUri": "https://example-cdn.com/cat.png"}} — must be a direct link the upstream can GET.

Search grounding (enabled per model route)

gemini-3-pro-image and gemini-3.1-flash-image support Google Search Grounding; gemini-3.1-flash-lite-image does not. The feature must be enabled explicitly on the model route and is off by default; while it is off the request returns 400 provider_unsupported without invoking a supplier or reserving any charge.

bash
curl "https://api.modelgo.ai/v1beta/models/gemini-3.1-flash-image:generateContent" \
  -H "x-goog-api-key: $MODELGO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "contents": [{"parts": [{"text": "A stylized match report image for the Champions League game last night"}]}],
    "tools": [{"google_search": {}}],
    "generationConfig": {"responseModalities": ["IMAGE"]}
  }'

When grounding is enabled, the response carries searchEntryPoint, groundingChunks and webSearchQueries under candidates[0].groundingMetadata (image search grounding also reports imageSearchQueries).

Response

json
{
  "candidates": [{
    "content": {
      "role": "model",
      "parts": [{"inlineData": {"mimeType": "image/png", "data": "iVBORw0KGgo..."}}]
    },
    "finishReason": "STOP",
    "index": 0
  }],
  "usageMetadata": {
    "promptTokenCount": 18,
    "candidatesTokenCount": 1680,
    "totalTokenCount": 1698,
    "promptTokensDetails": [{"modality": "TEXT", "tokenCount": 18}],
    "candidatesTokensDetails": [{"modality": "IMAGE", "tokenCount": 1680}]
  },
  "modelVersion": "gemini-3.1-flash-image"
}
  • The image is in parts[].inlineData.data (base64). When responseModalities includes TEXT, parts may also contain a {"text": ...} part.
  • modelVersion echoes the model name from the request path.

Save to a file:

bash
curl -s "https://api.modelgo.ai/v1beta/models/gemini-3.1-flash-image:generateContent" \
  -H "x-goog-api-key: $MODELGO_API_KEY" -H "Content-Type: application/json" \
  -d '{"contents":[{"parts":[{"text":"a red ball on a wooden table"}]}],"generationConfig":{"responseModalities":["IMAGE"]}}' \
  | python3 -c '
import sys, json, base64
for p in json.load(sys.stdin)["candidates"][0]["content"]["parts"]:
    if "inlineData" in p:
        open("out.png", "wb").write(base64.b64decode(p["inlineData"]["data"])); break'

2. Parameters

FieldTypeDescription
contents[].rolestringuser
contents[].parts[].textstringThe prompt. Describes the image; for image-to-image, describes the change
contents[].parts[].inlineDataobjectReference image, {"mimeType": "image/png", "data": "<base64>"}
contents[].parts[].fileDataobjectReference image URL, {"fileUri": "https://..."}
systemInstructionobjectOptional system instruction, same as Gemini text calls
generationConfig.responseModalitiesstring[]["IMAGE"] for image only; ["TEXT","IMAGE"] for interleaved text and image
generationConfig.imageConfig.aspectRatiostringCommon values such as 1:1 / 16:9 / 9:16; see the official documentation for the full list
generationConfig.imageConfig.imageSizestringResolution tier; per-model values in the first table, default 1K
toolsobject[]Only [{"google_search": {}}] (Search Grounding). Supported by gemini-3-pro-image and gemini-3.1-flash-image, not by gemini-3.1-flash-lite-image; must be enabled on the model route (off by default)
toolConfigobjectGrounding retrieval configuration, forwarded with tools
cachedContentstringNot supported: Google's image models do not offer context caching; sending it returns 400
  • candidateCount > 1 → 400: Google's image models do not support multiple candidates (Google answers Multiple candidates is not enabled for this model); one image per request.
  • tools / toolConfig: Search Grounding only, and model-specific — supported by gemini-3-pro-image and gemini-3.1-flash-image, not by gemini-3.1-flash-lite-image. Availability also depends on the model route; while grounding is off the request returns 400 provider_unsupported without invoking a supplier or reserving any charge.
  • cachedContent → 400: Google's image models do not support context caching.
  • responseSchema / responseMimeType → 400: image models do not support structured output.
  • :streamGenerateContent → 400: image generation does not stream.
  • An imageSize the model does not offer (e.g. 2K on gemini-3.1-flash-lite-image) is decided by the supplier; an unsupported value returns 400.
  • Routing follows deliverable tiers. The gateway prefers suppliers that can deliver the declared tier; if none claims it, it still routes to an available supplier and lets it decide (a 400 if unsupported).

Resolution tiers

TierPixel budgetOutput (example)
512px~0.25 MP—
1K (default)~1 MPdefault → 1408×768
2K~4 MP16:9 → 2752×1536
4K~16 MP9:16 → 3072×5504

The tier sets the total pixel budget; exact width and height are determined by aspectRatio. Without an aspectRatio the default is the supplier's roughly 16:9 output.

3. Full example (Python, Google GenAI SDK)

python
import os
from google import genai
from google.genai import types

client = genai.Client(api_key=os.environ["MODELGO_API_KEY"],
                      http_options={"base_url": "https://api.modelgo.ai"})

resp = client.models.generate_content(
    model="gemini-3.1-flash-image",
    contents="A fluffy orange cat sitting on a sunny windowsill, film grain",
    config=types.GenerateContentConfig(
        response_modalities=["IMAGE"],
        image_config=types.ImageConfig(aspect_ratio="16:9", image_size="2K"),
    ),
)
for part in resp.candidates[0].content.parts:
    if part.inline_data:
        open("cat.png", "wb").write(part.inline_data.data)
print(resp.usage_metadata.candidates_token_count)

For image-to-image, pass a list as contents: ["Replace the background with a neon night street", types.Part.from_bytes(data=open("cat.png","rb").read(), mime_type="image/png")].

4. Billing

  • Token-based: text in promptTokensDetails at input, images at image_input; in candidatesTokensDetails, IMAGE at image_output and TEXT at output.
  • Output image tokens grow with the tier; take the exact values from usageMetadata in the response.
  • A reservation is frozen at request time and settled from the actual usageMetadata values.
  • Grounding add-on: a Search Grounding call is billed per executed query, counted from groundingMetadata.webSearchQueries / imageSearchQueries in the response, under the web_search add-on. A response without groundingMetadata adds nothing. The add-on price is whatever the console configures.
  • Rejected requests (400) and failed generations are never billed; the reservation is released automatically.
  • Prices are those shown in the console's model list.

Common errors

SymptomCauseFix
400imageSize not offered by the model; aspectRatio outside the table; candidateCount > 1 (Google's image models do not support multiple candidates); tools / toolConfig on an unsupported model or a route with grounding off; cachedContent (image models do not support caching); responseSchema / responseMimeType; :streamGenerateContent called; no supplier can currently produce the requested tierFix per the parameter table; use generateContent
No inlineData in partsresponseModalities did not include IMAGE, or the prompt was blocked by safety policy (finishReason other than STOP)Pass ["IMAGE"] explicitly; check finishReason
Reference image ignoredfileData.fileUri is not a public direct link (auth / redirect / 403)Use inlineData or a direct link on your own CDN
401Invalid API key or missing x-goog-api-key / Authorization headerCheck the key