Call Gemini image models through Router Brain’s Google native /google endpoints.

Example model code: gemini-nano-banana-2.1-all — replace with a model enabled for your account in the model catalog. Authenticate with an API key created in the console. Replace every [BASE64_IMAGE_DATA] placeholder with real image data before calling in production.

1. Entry points

EndpointUse caseRequestResponse
/google/{version}/models/{model}:generateContentNative Google calls, multi-turn edits, video inputGoogle native JSONGoogle native JSON
/google/{version}/models/{model}:streamGenerateContentNative Google streamingGoogle native JSONGoogle native SSE

All of the above use POST. Use https://routerbrain.ai as the gateway base URL and the platform’s public model code in the path. Responses follow Google’s native JSON or SSE format.

2. Google native API

2.1 URL, auth, and headers

Synchronous:

POST https://routerbrain.ai/google/v1beta/models/{model_code}:generateContent

Streaming:

POST https://routerbrain.ai/google/v1beta/models/{model_code}:streamGenerateContent?alt=sse
Parameter / headerRequiredDescription
Path versionYesUse v1, v1beta, or v1alpha in the path; supported versions depend on the model
Path model codeYesPublic model code, e.g. gemini-nano-banana-2.1-all
Path operationYesgenerateContent (sync) or streamGenerateContent (stream)
Content-TypeYesapplication/json
x-goog-api-keyOne of twoConsole API key; may be used instead of query key
Query keyOne of twoConsole API key; Google alias $key is also accepted. URL-encode special characters
Query alt=sseRecommended for streamingStandard SSE form; streaming is selected by :streamGenerateContent in the URL
x-trace-idNoCustom trace id for correlating requests
x-user-idNoEnd-user identifier
x-agent-nameNoCalling app or agent name

If both header and query key are sent, they must match. Duplicate or conflicting keys are rejected. This entry point requires x-goog-api-key or key; Authorization: Bearer ... alone is not sufficient.

See Google’s system parameters for key, $key, and X-Goog-Api-Key.

2.2 Text-to-image (sync)

Set local variables:

GATEWAY_URL='https://routerbrain.ai'
API_KEY='sk-REPLACE-WITH-YOUR-KEY'
MODEL_CODE='gemini-nano-banana-2.1-all'
curl --silent --show-error --fail-with-body --max-time 300 \
  "${GATEWAY_URL}/google/v1beta/models/${MODEL_CODE}:generateContent" \
  -H "x-goog-api-key: ${API_KEY}" \
  -H 'Content-Type: application/json' \
  --data-binary @- <<'JSON'
{
  "contents": [
    {
      "role": "user",
      "parts": [
        { "text": "Generate an image of an orange cat sitting by a window in the sun" }
      ]
    }
  ],
  "generationConfig": {
    "responseModalities": ["TEXT", "IMAGE"],
    "imageConfig": {
      "aspectRatio": "16:9",
      "imageSize": "2K"
    }
  }
}
JSON

--max-time 300 is a client-side curl timeout, not a request body field; adjust as needed.

For query-parameter auth, save the JSON above as request.json:

curl --silent --show-error --fail-with-body --max-time 300 \
  "${GATEWAY_URL}/google/v1beta/models/${MODEL_CODE}:generateContent" \
  --url-query "key=${API_KEY}" \
  -H 'Content-Type: application/json' \
  --data-binary @request.json

--url-query requires a recent curl and handles URL encoding; the header example works on older curl versions.

2.3 Request body (main fields)

The request body matches the Google GenerateContent API. The table below lists common image-generation fields; capabilities vary by model.

FieldTypeRequiredDescription
contentsarray<object>YesCurrent turn or ordered conversation history
contents[].rolestringRecommendeduser for user turns; model for prior model replies
contents[].partsarray<object>YesParts: text, inline media, file references, etc.
parts[].textstringWhen using textPrompt, edit instruction, or history text
parts[].inlineDataobjectInline mediamimeType + data
inlineData.mimeTypestringWith inline mediae.g. image/png, image/jpeg
inlineData.datastringWith inline mediaRaw base64 without a data:image/...;base64, prefix
parts[].fileDataobjectFile referencefileUri, optional mimeType; must be reachable by the model service
fileData.fileUristringWith file referenceURI the model service can read; see Google docs for supported schemes
fileData.mimeTypestringRecommendedMIME of referenced file (image or video/mp4)
parts[].thoughtSignaturestringMulti-turn when returnedSignature from the previous model part; do not invent or modify
systemInstructionobjectNoOften { "parts": [{ "text": "..." }] }
generationConfigobjectRecommended for imagesModalities, image size, sampling options
cachedContentstringNoExisting cached content name; this API does not create cache
safetySettingsarray<object>Noe.g. category, threshold
tools / toolConfigNoTool configuration when supported

Use one content type per Part per Google’s spec. For multi-turn edits, keep the full previous content to preserve images, signatures, and context.

2.4 generationConfig

FieldTypeDescription
responseModalitiesarray<string>For images, prefer ["TEXT", "IMAGE"]; ["IMAGE"] when the model allows
imageConfig.aspectRatiostringe.g. 1:1, 16:9, 9:16, 4:3, 3:2; model-specific
imageConfig.imageSizestring512, 1K, 2K, 4K — mind letter case; support varies by model
temperature, topP, topKSampling; defaults apply when omitted
maxOutputTokensintegerOutput token cap; too low may truncate; not pixel or image count
seedintegerWhen supported; not a strict reproducibility guarantee
candidateCountintegerPrefer 1 for image calls
stopSequencesarray<string>When supported
thinkingConfig.*Thinking level/budget/thoughts when the model supports them

Do not use responseMimeType instead of inlineData.mimeType to force PNG/JPEG. Image calls use imageConfig; see GenerationConfig.

2.5 Image-to-image / edit

Replace placeholders and send as in §2.2:

{
  "contents": [
    {
      "role": "user",
      "parts": [
        { "text": "Keep the cat’s appearance; change the background to a beach sunset" },
        {
          "inlineData": {
            "mimeType": "image/png",
            "data": "[BASE64_IMAGE_DATA]"
          }
        }
      ]
    }
  ],
  "generationConfig": {
    "responseModalities": ["TEXT", "IMAGE"],
    "imageConfig": { "aspectRatio": "16:9", "imageSize": "2K" }
  }
}

File reference part:

{
  "fileData": {
    "mimeType": "image/jpeg",
    "fileUri": "https://example.com/reference.jpg"
  }
}

Place inside contents[].parts. The URL must be directly reachable by the model service; Router Brain does not download remote images for you. HTTPS and Google file URIs depend on the model and Google’s documentation.

For video input, use inlineData or fileData with the appropriate video MIME; support depends on the model.

2.6 Multi-turn image editing

Keep candidates[0].content from the last response as a model turn, then append the new user message:

{
  "contents": [
    {
      "role": "user",
      "parts": [{ "text": "Generate an orange cat by the window" }]
    },
    {
      "role": "model",
      "parts": [
        {
          "inlineData": {
            "mimeType": "image/png",
            "data": "[BASE64_IMAGE_DATA]"
          },
          "thoughtSignature": "[ORIGINAL_THOUGHT_SIGNATURE]"
        }
      ]
    },
    {
      "role": "user",
      "parts": [{ "text": "Same pose; change the view outside to snow" }]
    }
  ],
  "generationConfig": { "responseModalities": ["TEXT", "IMAGE"] }
}

Include thoughtSignature only when the prior response returned one. See Google image generation.

2.7 Native SSE

Save the §2.2 body as request.json:

curl -N --silent --show-error --fail-with-body --max-time 300 \
  "${GATEWAY_URL}/google/v1beta/models/${MODEL_CODE}:streamGenerateContent?alt=sse" \
  -H "x-goog-api-key: ${API_KEY}" \
  -H 'Content-Type: application/json' \
  --data-binary @request.json

Each data: line is typically one Google response object. Parse on SSE event boundaries; do not assume one read equals one JSON object or that [DONE] always appears.

Example event shapes:

data: {"candidates":[{"index":0,"content":{"role":"model","parts":[{"inlineData":{"mimeType":"image/png","data":"[BASE64_IMAGE_DATA]"}}]}}]}

data: {"candidates":[{"index":0,"finishReason":"STOP"}],"usageMetadata":{"promptTokenCount":11,"candidatesTokenCount":1120,"totalTokenCount":1131,"promptTokensDetails":[{"modality":"TEXT","tokenCount":11}],"candidatesTokensDetails":[{"modality":"IMAGE","tokenCount":1120}]}}

Events are separated by blank lines; multiple data: lines may belong to one event.

2.8 Response and reading images

Example response:

{
  "candidates": [
    {
      "index": 0,
      "finishReason": "STOP",
      "content": {
        "role": "model",
        "parts": [
          {
            "inlineData": {
              "mimeType": "image/png",
              "data": "[BASE64_IMAGE_DATA]"
            }
          }
        ]
      }
    }
  ],
  "usageMetadata": {
    "promptTokenCount": 11,
    "candidatesTokenCount": 1120,
    "totalTokenCount": 1131,
    "promptTokensDetails": [{ "modality": "TEXT", "tokenCount": 11 }],
    "candidatesTokensDetails": [{ "modality": "IMAGE", "tokenCount": 1120 }]
  }
}

Walk candidates[].content.parts[]:

FieldMeaning
part.textText output
part.inlineData.dataRaw image base64
part.inlineData.mimeTypeActual image MIME for file extension
part.thoughtWhen true, thought content — not the final image
part.thoughtSignatureKeep for the next multi-turn request
candidate.finishReasonCompletion reason for that candidate
promptFeedbackInput blocking feedback
usageMetadataToken usage in the response; not a request field

You may get text without an image. Check for image parts; HTTP 200 alone does not prove an image was generated.

3. Errors and limits

3.1 Error shape

Authentication error example:

{
  "error": {
    "code": 401,
    "message": "API key not valid. Please pass a valid API key.",
    "status": "UNAUTHENTICATED"
  }
}

Responses may include Google-native error bodies. Check HTTP status, error, promptFeedback, each candidate’s finishReason, and whether image parts are present.

SymptomWhat to check
401 / UNAUTHENTICATEDValid API key via x-goog-api-key or key
400 / INVALID_ARGUMENTValid JSON, non-conflicting keys, supported options
404 / NOT_FOUNDModel code, API version, operation name
403 or permission errorsModel enabled for your account; key valid and account has balance
Text but no imageIMAGE modality, model capability, safety/finish reason
Reference image failsURI reachable by the model service, correct MIME; try inlineData base64
Image size errorsimageSize casing, aspectRatio, model support
SSE errorsTreat as failed stream; keep x-request-id
Long waitIncrease client timeout; curl -N only disables buffering

3.2 Boundaries

  • Only generateContent and streamGenerateContent on this native entry; not Google Interactions API.
  • Model code and streaming operation are in the URL; do not use body stream: true instead of streamGenerateContent.
  • Image size via generationConfig.imageConfig, not OpenAI size / response_format / n.
  • This API does not upload files or create caches; fileData.fileUri and cachedContent must reference existing resources the model service can use.
  • Capabilities and latency are model-specific; a valid body does not guarantee support.
  • For SSE, read until final candidate state and errors; partial success is not enough.
  • Image MIME comes from the response; do not assume PNG.
  • When contacting support: include x-request-id, model code, operation name, and error text — never full API keys or image base64.

Image generation overview · Gateway errors