Migrating from OpenAI to Google Gemini: A Practical Guide

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

After — Gemini via the OpenAI SDK
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

OpenAI → Gemini native (google-genai SDK, as of June 2026).
ConceptOpenAIGemini (native)
SDK openaigoogle-genai
Auth OPENAI_API_KEYGEMINI_API_KEY
Call chat.completions.createmodels.generate_content
Messages messages[] role/contentcontents[] role(user/model)/parts
System prompt role: system messageconfig.system_instruction
Max output max_tokensconfig.max_output_tokens
Assistant role assistantmodel
Response text choices[0].message.contentresponse.text
Tools tools + tool_callsconfig.tools (function declarations)
After — Gemini native
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, not assistant. Map your history accordingly.
  • System prompt moves to config.system_instruction (not a message).
  • Multi-turn uses contents as a list of {role, parts} — not OpenAI’s flat messages.
  • Context-tier pricing: Gemini Pro charges more above ~200K-token prompts. Re-budget.
  • Tool schema is Gemini’s function-declaration format, not OpenAI’s tools array.

What to do next

  1. Try the OpenAI-compatible endpoint first — it may be all you need.
  2. If you need native features (large context, Gemini tools), port to google-genai using the mapping above.
  3. Re-price with the cost calculator and re-run evals.
  4. 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.