Portkey provides a robust and secure gateway to facilitate the integration of various Large Language Models (LLMs) into your applications, including Google Gemini APIs.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 system.
To use Gemini with Portkey, get your API key from here, then add it to Portkey to create the virtual key.
NodeJS SDK
Python SDK
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})
from portkey_ai import Portkeyportkey = Portkey( api_key="PORTKEY_API_KEY", # Replace with your Portkey API key virtual_key="VIRTUAL_KEY" # Replace with your virtual key for Google)
Use the Portkey instance to send requests to Google Gemini. You can also override the virtual key directly in the API call if needed.
NodeJS SDK
Python SDK
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);
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)
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.
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".
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.
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.
"tools": [ { "type": "function", "function": { "name": "google_search" // or google_search_retrieval for older models } }]
If you mix regular tools with grounding tools, vertex might throw an error saying only one tool can be used at a time.
The assistants thinking response is returned in the response_chunk.choices[0].delta.content_blocks array, not the response.choices[0].message.content string.
Models like gemini-2.5-flash-preview-04-17gemini-2.5-flash-preview-04-17 support extended thinking.
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 in the headers to use this feature.
from portkey_ai import Portkey# Initialize the Portkey clientportkey = 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 requestresponse = 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)
import Portkey from 'portkey-ai';// Initialize the Portkey clientconst 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 completionasync 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 functiongetChatCompletionFunctions();
import OpenAI from 'openai'; // We're using the v4 SDKimport { 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 streamingasync 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();
from openai import OpenAIfrom portkey_ai import PORTKEY_GATEWAY_URL, createHeadersopenai = 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)
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?" } ] } ] }'
To disable thinking for gemini models like gemini-2.5-flash-preview-04-17, you are required to explicitly set budget_tokens to 0.