Google Gen AI Python SDK
The Google Gen AI Python SDK (google-genai) takes a base_url through types.HttpOptions, so it can be pointed at a Gemini LLM Registry entry without a wrapper. The same HttpOptions object carries custom headers, which is how the Agent Access Key travels.
All three credential modes below are verified working against a Gemini entry.
Setup
Pick the credential mode your entry runs in. You'll find it on the entry's Provider Credential panel.
- API Key
- Passthrough (Agent Access Key Required)
- Passthrough (No Agent Access Key)
The gateway stores the Gemini credential, so no Gemini key leaves your machine. api_key carries your Agent Access Key instead.
from google import genai
from google.genai import types
client = genai.Client(
api_key="<your-agent-access-key>",
http_options=types.HttpOptions(
base_url="https://<gateway-host>/llm/<url-prefix>"
)
)
response = client.models.generate_content(
model="<model-id>",
contents="Hello"
)
print(response)
The SDK sends api_key as x-goog-api-key, which the gateway accepts as your credential on this mode. It then attaches the stored Gemini credential on the outbound side.
Your Gemini key is set twice, in two different conventions. That is expected, not a mistake, and the call fails without both. See why the Gemini key appears twice below.
from google import genai
from google.genai import types
client = genai.Client(
api_key="<your-gemini-api-key>",
http_options=types.HttpOptions(
headers={
"X-Agent-Key": "<your-agent-access-key>",
"Authorization": "Bearer <your-gemini-api-key>"
},
base_url="https://<gateway-host>/llm/<url-prefix>"
)
)
response = client.models.generate_content(
model="<model-id>",
contents="Hello"
)
print(response)
What each part does:
api_keyis your own Gemini key. The SDK sends it asx-goog-api-key.X-Agent-Keycarries the Agent Access Key, which identifies you to the gateway. On a passthrough entry this header is where the gateway looks for it.Authorization: Bearercarries the same Gemini key again, in the form the gateway's Gemini route needs upstream.base_urlis the entry's endpoint, with no path suffix added.
With Require an agent access key off, only your Gemini key travels and no headers are needed at all.
from google import genai
from google.genai import types
client = genai.Client(
api_key="<your-gemini-api-key>",
http_options=types.HttpOptions(
base_url="https://<gateway-host>/llm/<url-prefix>"
)
)
response = client.models.generate_content(
model="<model-id>",
contents="Hello"
)
print(response)
Note that the Gemini key appears only once here. The second copy is needed only when an Agent Access Key is also in play.
Why the Gemini key appears twice
This surprises people, so it's worth spelling out.
The gateway serves Gemini through Google's OpenAI-compatibility endpoint rather than the native generateContent API. That endpoint authenticates with Authorization: Bearer. The Google Gen AI SDK, meanwhile, follows Google's native convention and sends api_key as x-goog-api-key.
On a passthrough entry the two don't line up on their own, so you supply the key in both forms: api_key for the SDK's own convention, and an explicit Authorization: Bearer header for what the route needs upstream.
The other two modes avoid the problem entirely. Passthrough without an Agent Access Key needs no custom headers, and API Key mode sends no Gemini key at all.
Where to find each value
| Placeholder | Where to find it |
|---|---|
<gateway-host> | Host from the entry's Overview tab, for example gw.aigateway.example.com |
<url-prefix> | The URL prefix field on the entry's Overview tab |
<model-id> | A model identifier from the entry's Allowed Models list, for example gemini-3.1-flash-lite-preview |
<your-agent-access-key> | Generate from the entry's Agent Access Keys step. Plaintext is shown once. |
<your-gemini-api-key> | Your own Google Gemini API key, needed only in the passthrough modes |
Tips
- Keep credentials out of your source. The snippets inline the values so the shape is clear, but read them from environment variables or a secret store in anything you commit.
base_urltakes no/v1suffix. Gemini differs from the other OpenAI-compatible providers here, because its target base already carries the version segment. Paste the entry's endpoint exactly as the Overview tab shows it.- A 401 on passthrough usually means a missing header, not a bad key. If you've set
api_keybut omitted theAuthorizationorX-Agent-Keyheader, the failure looks like a credential problem even though both credentials are valid. - Working in a different SDK? There are sibling guides for the Anthropic Python SDK and the OpenAI Python SDK.
Cequence AI Gateway