---
title: "Google GenAI SDK"
description: "The official Google GenAI SDKs for Python and TypeScript call pirouter with the base URL set to https://api.pirouter.ai and an extra Authorization: Bearer header, because the gateway does not read the SDK's default x-goog-api-key. This page covers installing, configuring and verifying the SDK, and what to do about common errors."
canonical: "https://pirouter.ai/docs/integrations/google-genai-sdk"
last-updated: "2026-10-17"
lang: "en"
source: "content/docs/en/integrations/google-genai-sdk.mdx"
---

# Google GenAI SDK

The official Google GenAI SDKs for Python and TypeScript call pirouter with the base URL set to https://api.pirouter.ai and an extra Authorization: Bearer header, because the gateway does not read the SDK's default x-goog-api-key. This page covers installing, configuring and verifying the SDK, and what to do about common errors.

The official Google GenAI SDKs need no plugin to call pirouter: when you create the client, change the base URL and add one header. The rest of your code stays as it is.

## Prerequisites

- A pirouter API key. If you do not have one, create it with the [quickstart](https://pirouter.ai/docs/quickstart.md) and store it in an environment variable:

```bash
export PIROUTER_API_KEY="sk-pi-..."
```

- Python 3.10 or later, or Node.js 20 or later.
- The SDK:

Python:

```bash
pip install google-genai
```

TypeScript:

```bash
pnpm add @google/genai
```

The TypeScript samples use top-level `await`: save the file as `.mjs`, or set `"type": "module"` in `package.json`.

## Configure

Set three things when you create the client:

- The base URL is `https://api.pirouter.ai`, without `/v1beta`, because the SDK adds it. In Python it is `base_url` in `http_options`; in TypeScript, `baseUrl` in `httpOptions`. Do not set `api_version` (`apiVersion` in TypeScript); keep the SDK's default, `v1beta`.
- In the same place, add an `Authorization: Bearer` header under `headers`, with your pirouter key as the value.
- Pass the same pirouter key as `api_key` (`apiKey` in TypeScript) too; the SDK requires it.

The gateway serves two actions: `/v1beta/models/{model}:generateContent` and `:streamGenerateContent`.

The extra `Authorization` header is needed because the SDK sends the key in the `x-goog-api-key` header by default, and the gateway does not read that header: it reads `Authorization` and `x-api-key` only. The SDK still sends `x-goog-api-key`; the gateway removes it on the way in and never forwards it upstream.

Python:

```python
import os
from google import genai
from google.genai import types

client = genai.Client(
    api_key=os.environ["PIROUTER_API_KEY"],
    http_options=types.HttpOptions(
        base_url="https://api.pirouter.ai",
        headers={"Authorization": f"Bearer {os.environ['PIROUTER_API_KEY']}"},
    ),
)

response = client.models.generate_content(
    model="google/gemini-3.5-flash",
    contents="Hello!",
)
print(response.text)
```

TypeScript:

```ts
import { GoogleGenAI } from '@google/genai'

const ai = new GoogleGenAI({
  apiKey: process.env.PIROUTER_API_KEY,
  httpOptions: {
    baseUrl: 'https://api.pirouter.ai',
    headers: { Authorization: `Bearer ${process.env.PIROUTER_API_KEY}` },
  },
})

const response = await ai.models.generateContent({
  model: 'google/gemini-3.5-flash',
  contents: 'Hello!',
})
console.log(response.text)
```

Write the full model ID, such as `google/gemini-3.5-flash`. The SDK puts it in the path, and the gateway takes everything after `models/` and before the last colon as the model ID, slash included.

For the models you can use, see the Gemini column of the protocol table in [Models and protocols](https://pirouter.ai/docs/models.md#which-protocols-each-model-accepts).

A header cannot be added through an environment variable, so this SDK is configured in code only.

### Stream the response

Use `generate_content_stream` in Python and `generateContentStream` in TypeScript; the SDK sends the request to `:streamGenerateContent`:

Python:

```python
import os
from google import genai
from google.genai import types

client = genai.Client(
    api_key=os.environ["PIROUTER_API_KEY"],
    http_options=types.HttpOptions(
        base_url="https://api.pirouter.ai",
        headers={"Authorization": f"Bearer {os.environ['PIROUTER_API_KEY']}"},
    ),
)

for chunk in client.models.generate_content_stream(
    model="google/gemini-3.5-flash",
    contents="Hello!",
):
    print(chunk.text or "", end="", flush=True)
print()
```

TypeScript:

```ts
import { GoogleGenAI } from '@google/genai'

const ai = new GoogleGenAI({
  apiKey: process.env.PIROUTER_API_KEY,
  httpOptions: {
    baseUrl: 'https://api.pirouter.ai',
    headers: { Authorization: `Bearer ${process.env.PIROUTER_API_KEY}` },
  },
})

const stream = await ai.models.generateContentStream({
  model: 'google/gemini-3.5-flash',
  contents: 'Hello!',
})
for await (const chunk of stream) {
  process.stdout.write(chunk.text ?? '')
}
console.log()
```

You should see the reply printed piece by piece.

## Verify

Save the sample above as `main.py` or `main.mjs`, then run it:

Python:

```bash
python main.py
```

TypeScript:

```bash
node main.mjs
```

You should see a one-line reply from the model.

Open **Logs** in the console. A few seconds after the request, it appears in the list; **Endpoint** shows the path of the call, ending in `:generateContent`. The **Trace ID** in the log details is the same value as the response's `X-Pi-Trace-Id` header.

## Troubleshooting

### 401 invalid\_api\_key

A `401` with the error code `invalid_api_key` and the `message` "You didn't provide an API key. Provide it in an Authorization header using Bearer auth (Authorization: Bearer YOUR\_KEY)." most often means the `Authorization` header is missing and the request relies on the SDK's default `x-goog-api-key`. Add the header under `headers` as configured above. A header value that is not a pirouter key starting with `sk-pi-` gets the same answer.

### 400 model is required

A `400` with the error code `invalid_request` and the `message` `model is required` usually means the base URL is `https://api.pirouter.ai/v1beta`, or `api_version` is set. The request path is then not an endpoint the gateway serves, and the gateway cannot find a model in it. Use `https://api.pirouter.ai` as the base URL and remove `api_version`.

### 422 validation\_failed

A `422` with the error code `validation_failed` and a `message` starting "This model is not served on the endpoint you called." means the model does not accept the Gemini protocol, for example `anthropic/claude-sonnet-5.5`. The rest of the `message` lists the endpoints it is served on. Pick a model marked Yes in the Gemini column of the protocol table, or use the [OpenAI SDK](https://pirouter.ai/docs/integrations/openai-sdk.md).

## Not verified yet

- The gateway serves `generateContent` and `streamGenerateContent` only. `countTokens` is not available today and returns `400` with `model is required`.
- `embedContent`, `batchGenerateContent`, Files uploads and the Live API are not available today.
