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.
https://gateway.routerone.ai/v1beta/models/{model}:generateContentAuthorization
headerAuthorizationstringRequiredThe 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/jsonmodelstringRequiredCanonical 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>RequiredThe 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>RequiredContent parts. Text is { text: "…" }; multimodal uses inlineData.
›partsarray<object>
textstringA text part.
systemInstructionobjectSystem instruction, shaped like one contents entry. Not an entry in contents.
generationConfigobjectSampling 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
temperaturenumberSampling temperature, 0-2. Clamped to 1 when converting to Anthropic.
topPnumberNucleus sampling. Pick this or temperature, not both.
topKintegerTop-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.
candidateCountintegerHow many candidates to generate — Chat's n. Not carried across protocols by default. Billing follows the total tokens actually returned.
maxOutputTokensintegerMaximum 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.
presencePenaltynumberPresence penalty. Anthropic has no equivalent, so it is dropped there.
frequencyPenaltynumberFrequency penalty. Same as above.
seedintegerSampling seed. Chat has an equivalent; Anthropic and Responses do not.
responseMimeTypestringOutput MIME type, application/json or text/plain. This is what a JSON constraint from the other protocols converts into.
responseSchemaobjectSchema the output must satisfy, in Gemini's own subset.
responseJsonSchemaobjectStandard JSON Schema the output must satisfy. Chat's response_format.json_schema lands here.
responseLogprobsbooleanWhether to return token probabilities. Not carried across protocols by default.
logprobsintegerHow many candidate probabilities per position; requires responseLogprobs. Not carried across protocols by default.
thinkingConfigobjectThinking configuration. The two spellings (token budget / level) are mutually exclusive; see each field.
›thinkingConfigobject
includeThoughtsbooleanWhether 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.
thinkingBudgetintegerToken budget for thinking. 0 turns thinking off, and it is Gemini's only way to do so — there is no boolean switch.
thinkingLevelstringLevel-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.
speechConfigobjectSpeech output configuration. Passed through, not carried across protocols by default.
imageConfigobjectImage output configuration. Passed through, not carried across protocols by default.
labelsobjectCustom 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.
toolConfigobjectTool choice. functionCallingConfig.mode takes AUTO / ANY / NONE, matching tool_choice on the others.
›toolConfigobject
functionCallingConfigobjectmode takes AUTO / ANY / NONE, matching the others' tool_choice; allowedFunctionNames narrows the callable set.
safetySettingsarray<object>Safety threshold settings. Gemini-only; passed through unchanged.
cachedContentstringHandle 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.
storebooleanWhether the upstream should log this request. Passed through unchanged; we do not retain request bodies ourselves.
Response
200responseInference succeeded.
402responseInsufficient 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
v1betaandv1are accepted. Google's current official documentation mainly showsv1beta. - Streaming is a separate action: replace the trailing
:generateContentwith:streamGenerateContent. Official SDKs commonly addalt=sse; omittingaltreturns 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, notassistant. candidatesTokenCountexcludes 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 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
}
}