Skip to main content
Version: Latest (1.9.x dev)

Gemini generateContent API

From 1.9.0 the DVARA LLM Gateway serves Gemini's generateContent API under /v1/gemini, for clients built for it such as Gemini CLI and the Google GenAI SDKs. Each call runs the same governance as /v1/chat/completions: policy, PII rules, guardrails, budgets, rate limits, cost records and audit. It works on any provider routing picks.

To set up Gemini CLI, see Govern Gemini CLI.

Which endpoints are served?​

A client's base URL is the Gateway address followed by /v1/gemini, for example https://gateway.acme.example.com/v1/gemini. The client then calls:

EndpointWhat it does
POST /v1/gemini/v1beta/models/{model}:generateContentOne answer
POST /v1/gemini/v1beta/models/{model}:streamGenerateContent?alt=sseA streamed answer, as server-sent events
POST /v1/gemini/v1beta/models/{model}:countTokensCounts tokens. No model is called and nothing is billed

The model in the path is routed like any model name: to Gemini, or by a route to another provider.

How is the key sent?​

DVARA reads a DVARA workspace key from x-goog-api-key (what Gemini CLI and the Google SDKs send), Authorization: Bearer or x-api-key. A key in the URL (?key=) is never read, because URLs end up in logs. A key with scopes needs completions:write.

curl -s "https://gateway.acme.example.com/v1/gemini/v1beta/models/<gemini-model-id>:generateContent" \
-H "x-goog-api-key: $DVARA_API_KEY" \
-H "content-type: application/json" \
-d '{"contents": [{"role": "user", "parts": [{"text": "Reply with one word: ready."}]}]}'

The answer is Gemini's response shape, with candidates and usageMetadata. The call shows in the audit log and on the usage and cost pages like any chat call.

What happens on each route?​

On a route to Gemini, the request goes on as the client sent it: every field and part, call ids, thought signatures, thinking settings and safety settings included. The answer, plain or streamed, comes back as Gemini sent it, changed only where governance changes it, such as redacted text. Usage and cost come from Gemini's own figures, including thinking and cached tokens.

On a route to another provider, the request is translated:

  • systemInstruction becomes a system message.
  • Function declarations become tools; functionCall and functionResponse parts become tool calls and their results.
  • The answer is written back in Gemini's shape. A streamed function call arrives whole.
  • What only tunes Gemini (thinking settings, topK, safety settings, thought parts) is left out. Anthropic, which takes only one of temperature and topP, is sent temperature.

When a PII rule or guardrail changes or holds an answer, parts DVARA does not read, such as executableCode, codeExecutionResult and inlineData, are still delivered.

What is refused?​

RequestWhy
Tools Google runs itself (googleSearch, urlContext, codeExecution, googleSearchRetrieval and the like), on every routeWhat they fetch or run is never checked
cachedContentThe content lives at Google, outside the Gateway
More than one candidate—
streamGenerateContent without alt=sse—

Every refusal comes back as an HTTP error status with JSON in Google's error shape, also on a streamed call and also when the provider refuses before its stream starts:

{
"error": {
"code": 400,
"message": "...",
"status": "INVALID_ARGUMENT"
}
}

The status and the reason are the ones any other endpoint would give; see Error handling.

What else should you know?​

  • Response cap. A client that sends no output limit, such as Gemini CLI, gets the Gateway's default response cap as its maxOutputTokens. Gemini counts thinking inside that limit, so an operator may need to raise the cap for long agent turns.
  • Response cache. These calls neither read nor fill the response cache.
  • Google sign-in. A client signed in with a Google account does not use a custom base URL, so it cannot be pointed at DVARA.