> ## Documentation Index
> Fetch the complete documentation index at: https://docs.portkey.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Google Gemini

Portkey provides a robust and secure gateway to facilitate the integration of various Large Language Models (LLMs) into your applications, including [Google Gemini APIs](https://cloud.google.com/vertex-ai/docs/generative-ai/model-reference/gemini).

With Portkey, you can take advantage of features like fast AI gateway access, observability, prompt management, and more, all while ensuring the secure management of your LLM API keys through a [virtual key](/product/ai-gateway/virtual-keys) system.
<Note>Provider Slug. `google`</Note>

## Portkey SDK Integration with Google Gemini Models

Portkey provides a consistent API to interact with models from various providers. To integrate Google Gemini with Portkey:

### 1. Install the Portkey SDK

Add the Portkey SDK to your application to interact with Google Gemini's API through Portkey's gateway.

<Tabs>
  <Tab title="NodeJS">
    ```sh theme={"system"}
    npm install --save portkey-ai
    ```
  </Tab>

  <Tab title="Python">
    ```sh theme={"system"}
    pip install portkey-ai
    ```
  </Tab>
</Tabs>

### 2. Initialize Portkey with the Virtual Key

To use Gemini with Portkey, [get your API key from here](https://aistudio.google.com/app/apikey), then add it to Portkey to create the virtual key.

<Tabs>
  <Tab title="NodeJS SDK">
    ```js theme={"system"}
    import Portkey from 'portkey-ai'

    const portkey = new Portkey({
        apiKey: "PORTKEY_API_KEY", // defaults to process.env["PORTKEY_API_KEY"]
        virtualKey: "VIRTUAL_KEY" // Your Google Virtual Key
    })
    ```
  </Tab>

  <Tab title="Python SDK">
    ```python theme={"system"}
    from portkey_ai import Portkey

    portkey = Portkey(
        api_key="PORTKEY_API_KEY",  # Replace with your Portkey API key
        virtual_key="VIRTUAL_KEY"   # Replace with your virtual key for Google
    )
    ```
  </Tab>
</Tabs>

### **3. Invoke Chat Completions with** Google Gemini

Use the Portkey instance to send requests to Google Gemini. You can also override the virtual key directly in the API call if needed.

<Tabs>
  <Tab title="NodeJS SDK">
    ```js theme={"system"}
    const chatCompletion = await portkey.chat.completions.create({
        messages: [
            { role: 'system', content: 'You are not a helpful assistant' },
            { role: 'user', content: 'Say this is a test' }
        ],
        model: 'gemini-1.5-pro',
    });

    console.log(chatCompletion.choices);
    ```
  </Tab>

  <Tab title="Python SDK">
    ```python theme={"system"}
    completion = portkey.chat.completions.create(
        messages= [
            { "role": 'system', "content": 'You are not a helpful assistant' },
            { "role": 'user', "content": 'Say this is a test' }
        ],
        model= 'gemini-1.5-pro'
    )

    print(completion)
    ```
  </Tab>
</Tabs>

<Note>
  Portkey supports the `system_instructions` parameter for Google Gemini 1.5 - allowing you to control the behavior and output of your Gemini-powered applications with ease.

  Simply include your Gemini system prompt as part of the `{"role":"system"}` message within the `messages` array of your request body. Portkey Gateway will automatically transform your message to ensure seamless compatibility with the Google Gemini API.
</Note>

## Function Calling

Portkey supports function calling mode on Google's Gemini Models. Explore this <Icon icon="square-down" /> Cookbook for a deep dive and examples:

[Function Calling](/guides/getting-started/function-calling)

## Document, Video, Audio Processing with Gemini

Gemini supports attaching `mp4`, `pdf`, `jpg`, `mp3`, `wav`, etc. file types to your messages.

<Info>
  Gemini Docs:

  * [Document Processing](https://ai.google.dev/gemini-api/docs/document-processing?lang=python)
  * [Video & Image Processing](https://ai.google.dev/gemini-api/docs/vision?lang=python)
  * [Audio Processing](https://ai.google.dev/gemini-api/docs/audio?lang=python)
</Info>

Using Portkey, here's how you can send these media files:

<CodeGroup>
  ```javascript JavaScript theme={"system"}
  const chatCompletion = await portkey.chat.completions.create({
      messages: [
          { role: 'system', content: 'You are a helpful assistant' },
          { role: 'user', content: [
              {
                  type: 'image_url',
                  image_url: {
                      url: 'gs://cloud-samples-data/generative-ai/image/scones.jpg'
                  }
              },
              {
                  type: 'text',
                  text: 'Describe the image'
              }
          ]}
      ],
      model: 'gemini-1.5-pro',
      max_tokens: 200
  });
  ```

  ```python Python theme={"system"}
  completion = portkey.chat.completions.create(
      messages=[
          {
              "role": "system",
              "content": "You are a helpful assistant"
          },
          {
              "role": "user",
              "content": [
                  {
                      "type": "image_url",
                      "image_url": {
                          "url": "gs://cloud-samples-data/generative-ai/image/scones.jpg"
                      }
                  },
                  {
                      "type": "text",
                      "text": "Describe the image"
                  }
              ]
          }
      ],
      model='gemini-1.5-pro',
      max_tokens=200
  )
  print(completion)
  ```

  ```sh cURL theme={"system"}
  curl --location 'https://api.portkey.ai/v1/chat/completions' \
  --header 'x-portkey-provider: vertex-ai' \
  --header 'x-portkey-vertex-region: us-central1' \
  --header 'Content-Type: application/json' \
  --header 'x-portkey-api-key: PORTKEY_API_KEY' \
  --header 'Authorization: GEMINI_API_KEY' \
  --data '{
      "model": "gemini-1.5-pro",
      "max_tokens": 200,
      "stream": false,
      "messages": [
          {
              "role": "system",
              "content": "You are a helpful assistant"
          },
          {
              "role": "user",
              "content": [
                  {
                      "type": "image_url",
                      "image_url": {
                          "url": "gs://cloud-samples-data/generative-ai/image/scones.jpg"
                      }
                  },
                  {
                      "type": "text",
                      "text": "describe this image"
                  }
              ]
          }
      ]
  }'
  ```
</CodeGroup>

This same message format also works for all other media types — just send your media file in the `url` field, like `"url": "gs://cloud-samples-data/video/animals.mp4"`.

<Note>
  Your URL should have the file extension, this is used for inferring `MIME_TYPE` which is a required parameter for prompting Gemini models with files.
</Note>

### Sending base64 Image

Here, you can send the `base64` image data along with the `url` field too:

```json theme={"system"}
"url": "data:image/png;base64,UklGRkacAABXRUJQVlA4IDqcAAC....."
```

## Grounding with Google Search

Vertex AI supports grounding with Google Search. This is a feature that allows you to ground your LLM responses with real-time search results.
Grounding is invoked by passing the `google_search` tool (for newer models like gemini-2.0-flash-001), and `google_search_retrieval` (for older models like gemini-1.5-flash) in the `tools` array.

```json theme={"system"}
"tools": [
    {
        "type": "function",
        "function": {
            "name": "google_search" // or google_search_retrieval for older models
        }
    }]
```

<Warning>
  If you mix regular tools with grounding tools, vertex might throw an error saying only one tool can be used at a time.
</Warning>

## Extended Thinking (Reasoning Models) (Beta)

<Note>
  The assistants thinking response is returned in the `response_chunk.choices[0].delta.content_blocks` array, not the `response.choices[0].message.content` string.
</Note>

Models like `gemini-2.5-flash-preview-04-17` `gemini-2.5-flash-preview-04-17` support [extended thinking](https://cloud.google.com/vertex-ai/generative-ai/docs/partner-models/use-claude#claude-3-7-sonnet).
This is similar to openai thinking, but you get the model's reasoning as it processes the request as well.

Note that you will have to set [`strict_open_ai_compliance=False`](/product/ai-gateway/strict-open-ai-compliance) in the headers to use this feature.

### Single turn conversation

<CodeGroup>
  ```py Python theme={"system"}
  from portkey_ai import Portkey

  # Initialize the Portkey client
  portkey = Portkey(
      api_key="PORTKEY_API_KEY",  # Replace with your Portkey API key
      virtual_key="VIRTUAL_KEY",   # Add your provider's virtual key
      strict_open_ai_compliance=False
  )

  # Create the request
  response = portkey.chat.completions.create(
    model="gemini-2.5-flash-preview-04-17",
    max_tokens=3000,
    thinking={
        "type": "enabled",
        "budget_tokens": 2030
    },
    stream=True,
    messages=[
        {
            "role": "user",
            "content": [
                {
                    "type": "text",
                    "text": "when does the flight from new york to bengaluru land tomorrow, what time, what is its flight number, and what is its baggage belt?"
                }
            ]
        }
    ]
  )
  print(response)
  # in case of streaming responses you'd have to parse the response_chunk.choices[0].delta.content_blocks array
  # response = portkey.chat.completions.create(
  #   ...same config as above but with stream: true
  # )
  # for chunk in response:
  #     if chunk.choices[0].delta:
  #         content_blocks = chunk.choices[0].delta.get("content_blocks")
  #         if content_blocks is not None:
  #             for content_block in content_blocks:
  #                 print(content_block)
  ```

  ```ts NodeJS theme={"system"}
  import Portkey from 'portkey-ai';

  // Initialize the Portkey client
  const portkey = new Portkey({
    apiKey: "PORTKEY_API_KEY", // Replace with your Portkey API key
    virtualKey: "VIRTUAL_KEY", // your vertex-ai virtual key
    strictOpenAiCompliance: false
  });

  // Generate a chat completion
  async function getChatCompletionFunctions() {
      const response = await portkey.chat.completions.create({
        model: "gemini-2.5-flash-preview-04-17",
        max_tokens: 3000,
        thinking: {
            type: "enabled",
            budget_tokens: 2030
        },
        stream: true,
        messages: [
            {
                role: "user",
                content: [
                    {
                        type: "text",
                        text: "when does the flight from new york to bengaluru land tomorrow, what time, what is its flight number, and what is its baggage belt?"
                    }
                ]
            }
        ]
      });
      console.log(response);
    // in case of streaming responses you'd have to parse the response_chunk.choices[0].delta.content_blocks array
    // const response = await portkey.chat.completions.create({
    //   ...same config as above but with stream: true
    // });
    // for await (const chunk of response) {
    //   if (chunk.choices[0].delta?.content_blocks) {
    //     for (const contentBlock of chunk.choices[0].delta.content_blocks) {
    //       console.log(contentBlock);
    //     }
    //   }
    // }
    }
  // Call the function
  getChatCompletionFunctions();
  ```

  ```js OpenAI NodeJS theme={"system"}
  import OpenAI from 'openai'; // We're using the v4 SDK
  import { PORTKEY_GATEWAY_URL, createHeaders } from 'portkey-ai'

  const openai = new OpenAI({
    apiKey: 'VERTEX_API_KEY', // defaults to process.env["OPENAI_API_KEY"],
    baseURL: PORTKEY_GATEWAY_URL,
    defaultHeaders: createHeaders({
      provider: "vertex-ai",
      apiKey: "PORTKEY_API_KEY", // defaults to process.env["PORTKEY_API_KEY"]
      strictOpenAiCompliance: false
    })
  });

  // Generate a chat completion with streaming
  async function getChatCompletionFunctions(){
    const response = await openai.chat.completions.create({
      model: "gemini-2.5-flash-preview-04-17",
      max_tokens: 3000,
      thinking: {
          type: "enabled",
          budget_tokens: 2030
      },
      stream: true,
      messages: [
          {
              role: "user",
              content: [
                  {
                      type: "text",
                      text: "when does the flight from new york to bengaluru land tomorrow, what time, what is its flight number, and what is its baggage belt?"
                  }
              ]
          }
      ],
    });

    console.log(response)
    // in case of streaming responses you'd have to parse the response_chunk.choices[0].delta.content_blocks array
    // const response = await openai.chat.completions.create({
    //   ...same config as above but with stream: true
    // });
    // for await (const chunk of response) {
    //   if (chunk.choices[0].delta?.content_blocks) {
    //     for (const contentBlock of chunk.choices[0].delta.content_blocks) {
    //       console.log(contentBlock);
    //     }
    //   }
    // }
  }
  await getChatCompletionFunctions();
  ```

  ```py OpenAI Python theme={"system"}
  from openai import OpenAI
  from portkey_ai import PORTKEY_GATEWAY_URL, createHeaders

  openai = OpenAI(
      api_key='VERTEX_API_KEY',
      base_url=PORTKEY_GATEWAY_URL,
      default_headers=createHeaders(
          provider="vertex-ai",
          api_key="PORTKEY_API_KEY",
          strict_open_ai_compliance=False
      )
  )


  response = openai.chat.completions.create(
      model="gemini-2.5-flash-preview-04-17",
      max_tokens=3000,
      thinking={
          "type": "enabled",
          "budget_tokens": 2030
      },
      stream=True,
      messages=[
          {
              "role": "user",
              "content": [
                  {
                      "type": "text",
                      "text": "when does the flight from new york to bengaluru land tomorrow, what time, what is its flight number, and what is its baggage belt?"
                  }
              ]
          }
      ]
  )

  print(response)
  ```

  ```sh cURL theme={"system"}
  curl "https://api.portkey.ai/v1/chat/completions" \
    -H "Content-Type: application/json" \
    -H "x-portkey-api-key: $PORTKEY_API_KEY" \
    -H "x-portkey-provider: vertex-ai" \
    -H "x-api-key: $VERTEX_API_KEY" \
    -H "x-portkey-strict-open-ai-compliance: false" \
    -d '{
      "model": "gemini-2.5-flash-preview-04-17",
      "max_tokens": 3000,
      "thinking": {
        "type": "enabled",
        "budget_tokens": 2030
      },
      "stream": true,
      "messages": [
        {
          "role": "user",
          "content": [
            {
              "type": "text",
              "text": "when does the flight from new york to bengaluru land tomorrow, what time, what is its flight number, and what is its baggage belt?"
            }
          ]
        }
      ]
    }'
  ```
</CodeGroup>

<Note>
  To disable thinking for gemini models like `gemini-2.5-flash-preview-04-17`, you are required to explicitly set `budget_tokens` to `0`.

  ```json theme={"system"}
  "thinking": {
      "type": "enabled",
      "budget_tokens": 0
  }
  ```
</Note>

<Info>
  Gemini grounding mode may not work via Portkey SDK. [Contact support](mailto:support@portkey.ai) for assistance.
</Info>

## Next Steps

The complete list of features supported in the SDK are available on the link below.

<Card title="SDK" href="/api-reference/portkey-sdk-client" />

You'll find more information in the relevant sections:

1. [Add metadata to your requests](/product/observability/metadata)
2. [Add gateway configs to your Gemini requests](/product/ai-gateway/configs)
3. [Tracing Google Gemini requests](/product/observability/traces)
4. [Setup a fallback from OpenAI to Gemini APIs](/product/ai-gateway/fallbacks)
