RouterOne

Generate Content

Last updated August 31, 2026

The inference endpoint for the Google Gemini generateContent protocol — compatible with the official SDKs, usable with any model that supports it.

This endpoint is compatible with Google Gemini's generateContent API and works with the official SDKs after pointing their base URL here.

Authentication follows Gemini's native pattern: x-goog-api-key: <your RouterOne key>, or ?key= on the URL.

The table below covers the main request parameters — accepted ranges, how each is handled on cross-protocol calls, and any preconditions. Gemini-native fields are preserved where possible on the compatible path, but billing-affecting fields and cross-protocol incompatibilities may still be blocked, normalized, or dropped.

POSThttps://gateway.routerone.ai/v1beta/models/{model}:generateContent

Authorization

header
AuthorizationstringRequired

The RouterOne key created in the console. This is the header the Gemini SDKs send natively; Authorization: Bearer and ?key= on the URL are also accepted.

Content-TypestringRequiredDefault "application/json"

Always application/json.

Request

application/json
modelstringRequired

Canonical ID, given in the path (Gemini puts the model name and the action in the URL). Do not escape the slash in vendor/model. The colon suffixes work here too — :provider to pin one, :@strategy to choose an ordering — placed before the action (models/vendor/model:@price:generateContent).

contentsarray<object>Required

The conversation contents. The assistant side is called model, not assistant.

›contentsarray<object>
role"user" | "model"

Role. The assistant side is called model, not assistant.

partsarray<object>Required

Content parts. Text is { text: "…" }; multimodal uses inlineData.

›partsarray<object>
textstring

A text part.

systemInstructionobject

System instruction, shaped like one contents entry. Not an entry in contents.

generationConfigobject

Sampling and output configuration. Gemini nests here what the others put at the top level — temperature, maxOutputTokens, stopSequences (at most 5), thinkingConfig and so on, each described below.

›generationConfigobject
temperaturenumber

Sampling temperature, 0-2. Clamped to 1 when converting to Anthropic.

topPnumber

Nucleus sampling. Pick this or temperature, not both.

topKinteger

Top-k sampling. The OpenAI protocols have no equivalent, so it is dropped when converting out. Watch the Anthropic link: models after Opus 4.6 reject top_k and the whole request fails with a 400.

candidateCountinteger

How many candidates to generate — Chat's n. Not carried across protocols by default. Billing follows the total tokens actually returned.

maxOutputTokensinteger

Maximum tokens for this generation. Chat calls it max_tokens.

stopSequencesarray<string>

Stop sequences, at most 5. Truncated to 4 with a note when converting to Chat.

presencePenaltynumber

Presence penalty. Anthropic has no equivalent, so it is dropped there.

frequencyPenaltynumber

Frequency penalty. Same as above.

seedinteger

Sampling seed. Chat has an equivalent; Anthropic and Responses do not.

responseMimeTypestring

Output MIME type, application/json or text/plain. This is what a JSON constraint from the other protocols converts into.

responseSchemaobject

Schema the output must satisfy, in Gemini's own subset.

responseJsonSchemaobject

Standard JSON Schema the output must satisfy. Chat's response_format.json_schema lands here.

responseLogprobsboolean

Whether to return token probabilities. Not carried across protocols by default.

logprobsinteger

How many candidate probabilities per position; requires responseLogprobs. Not carried across protocols by default.

thinkingConfigobject

Thinking configuration. The two spellings (token budget / level) are mutually exclusive; see each field.

›thinkingConfigobject
includeThoughtsboolean

Whether thinking comes back with the response. A switch with no detail level — which is why Responses' reasoning.summary can only carry its "whether" half onto this link.

thinkingBudgetinteger

Token budget for thinking. 0 turns thinking off, and it is Gemini's only way to do so — there is no boolean switch.

thinkingLevelstring

Level-based thinking effort, recommended from Gemini 3 on. Mutually exclusive with thinkingBudget — sending both makes the upstream return a 400.

responseModalitiesarray<"TEXT" | "IMAGE" | "AUDIO">

Which modalities the model should return. A non-TEXT value changes the billing dimension (the upstream charges per image or per second) while this endpoint's price book only has per-token tiers — see the generationConfig description.

mediaResolution"LOW" | "MEDIUM" | "HIGH"

Resolution for input media, deciding how many tokens an image is worth. Usage comes back truthfully and is billed as it happened.

speechConfigobject

Speech output configuration. Passed through, not carried across protocols by default.

imageConfigobject

Image output configuration. Passed through, not carried across protocols by default.

labelsobject

Custom key/value labels Google uses to break down its own bill. Passed through; no effect on billing here.

toolsarray<object>

Callable tools, shaped { functionDeclarations: [{ name, description, parameters }] }. Note the extra wrapping layer.

toolConfigobject

Tool choice. functionCallingConfig.mode takes AUTO / ANY / NONE, matching tool_choice on the others.

›toolConfigobject
functionCallingConfigobject

mode takes AUTO / ANY / NONE, matching the others' tool_choice; allowedFunctionNames narrows the callable set.

safetySettingsarray<object>

Safety threshold settings. Gemini-only; passed through unchanged.

cachedContentstring

Handle for explicitly cached content. Gemini-only, passed through — this is upstream-side state, so it is only reliable when you pin a provider. Cache hits come back in usage at their own lower rate, so billing what actually happened is correct and we do not strip it.

serviceTier"standard" | "flex" | "priority"

Service tier. Not supported — we forward it to no upstream, on either path, and serviceTier and service_tier are treated alike. Sending it is not an error. What was stripped is reported back: amux.droppedParams in the body, or the x-amux-dropped-params header when streaming.

storeboolean

Whether the upstream should log this request. Passed through unchanged; we do not retain request bodies ourselves.

Response

200response

Inference succeeded.

402response

Insufficient balance. These are not retried and do not affect any provider's health.

Path and version segment

Gemini places the model name and action in the URL, which differs from the fixed-path layout used by the other compatible protocols:

POST /v1beta/models/anthropic/claude-opus-5:generateContent
  • Both v1beta and v1 are accepted. Google's current official documentation mainly shows v1beta.
  • Streaming is a separate action: replace the trailing :generateContent with :streamGenerateContent. Official SDKs commonly add alt=sse; omitting alt returns a growing JSON array instead of SSE.
  • Do not escape the slash in the model name.

Three differences from the other compatible protocols

  • The system prompt is the top-level systemInstruction, not an entry in the contents array.
  • The assistant role is called model, not assistant.
  • candidatesTokenCount excludes thinking tokens, while the output tokens on your bill include them.

Errors

Errors come back in Gemini's error shape. For status values and retry semantics, see Errors and retries.

cURL
curl https://gateway.routerone.ai/v1beta/models/google/gemini-3-pro:generateContent \
  -H "x-goog-api-key: $ROUTERONE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "contents": [
      {
        "role": "user",
        "parts": [
          {
            "text": "Hello!"
          }
        ]
      }
    ]
  }'
{
  "candidates": [
    {
      "content": {
        "role": "user",
        "parts": [
          {
            "text": "Hello!"
          }
        ]
      },
      "finishReason": "STOP"
    }
  ],
  "usageMetadata": {
    "promptTokenCount": 0,
    "candidatesTokenCount": 0,
    "totalTokenCount": 0
  }
}