There are two ways to move from OpenAI to Gemini. The fast path uses Gemini’s OpenAI-compatibility endpoint (config change only). The native path uses the google-genai SDK, which exposes Gemini’s full feature set but has a different request shape. Start with the fast path; reach for native when you need Gemini-specific features.
Fast path — OpenAI-compatibility endpoint
import os
from openai import OpenAI
client = OpenAI(
api_key=os.environ["GEMINI_API_KEY"],
base_url="https://generativelanguage.googleapis.com/v1beta/openai/",
)
resp = client.chat.completions.create(
model="gemini-2.5-flash",
messages=[
{"role": "system", "content": "You are concise."},
{"role": "user", "content": "Explain rate limits in one line."},
],
)
print(resp.choices[0].message.content) That’s the whole migration for standard chat: keep the OpenAI SDK, change base_url, key, and model. Not every Gemini feature is exposed this way, which is when you switch to native.
Native path — concept mapping
| Concept | OpenAI | Gemini (native) |
|---|---|---|
| SDK | openai | google-genai |
| Auth | OPENAI_API_KEY | GEMINI_API_KEY |
| Call | chat.completions.create | models.generate_content |
| Messages | messages[] role/content | contents[] role(user/model)/parts |
| System prompt | role: system message | config.system_instruction |
| Max output | max_tokens | config.max_output_tokens |
| Assistant role | assistant | model |
| Response text | choices[0].message.content | response.text |
| Tools | tools + tool_calls | config.tools (function declarations) |
from google import genai
from google.genai import types
client = genai.Client() # GEMINI_API_KEY
resp = client.models.generate_content(
model="gemini-2.5-flash",
contents="Explain rate limits in one line.",
config=types.GenerateContentConfig(
system_instruction="You are concise.",
max_output_tokens=1024,
),
)
print(resp.text) Watch for these
- Roles differ: the assistant turn is
model, notassistant. Map your history accordingly. - System prompt moves to
config.system_instruction(not a message). - Multi-turn uses
contentsas a list of{role, parts}— not OpenAI’s flatmessages. - Context-tier pricing: Gemini Pro charges more above ~200K-token prompts. Re-budget.
- Tool schema is Gemini’s function-declaration format, not OpenAI’s
toolsarray.
What to do next
- Try the OpenAI-compatible endpoint first — it may be all you need.
- If you need native features (large context, Gemini tools), port to
google-genaiusing the mapping above. - Re-price with the cost calculator and re-run evals.
- Reverse route: Gemini → OpenAI.
Frequently asked questions
Do I have to rewrite everything for Gemini?
No. For standard chat, Gemini's OpenAI-compatibility endpoint lets you keep the OpenAI SDK and just change the base URL, key, and model. Only move to the native google-genai SDK when you need Gemini-specific capabilities.
What's the biggest gotcha in the native API?
Message shape: Gemini uses
contents with roles user/model and parts, the system prompt is a top-level system_instruction, and you read response.text instead of choices[0].message.content.Which Gemini model should I pick?
Gemini 2.5 Flash or 3.5 Flash for cheap, fast workloads; Gemini 2.5 Pro for harder reasoning. Mind the higher pricing tier for very long prompts, and verify current model ids in Google's docs.