GEMINI LABJP
NANOLITE — Nano Banana 2 Lite is here: Google's fastest and most cost-efficient Gemini Image model, made for running lightweight image generation cheaplyOMNIFLASH — Gemini Omni Flash is in public preview, a natively multimodal model that lets enterprises and developers build custom, dynamic video workflowsAGENTS — Managed Agents expand with background: true for async server-side runs and polling, remote MCP server integration, and refreshing credentials across interactionsMEMORY — The Memory Bank IngestEvents API is generally available, decoupling event ingestion from memory generation so you can stream content continuouslyTHROUGHPUT — Provisioned Throughput now lets you submit up to seven pending orders for the same model and regionDEPRECATE — Image generation models shut down on August 17, and the Grok 4.1 family on the Gemini Enterprise Agent Platform on August 20NANOLITE — Nano Banana 2 Lite is here: Google's fastest and most cost-efficient Gemini Image model, made for running lightweight image generation cheaplyOMNIFLASH — Gemini Omni Flash is in public preview, a natively multimodal model that lets enterprises and developers build custom, dynamic video workflowsAGENTS — Managed Agents expand with background: true for async server-side runs and polling, remote MCP server integration, and refreshing credentials across interactionsMEMORY — The Memory Bank IngestEvents API is generally available, decoupling event ingestion from memory generation so you can stream content continuouslyTHROUGHPUT — Provisioned Throughput now lets you submit up to seven pending orders for the same model and regionDEPRECATE — Image generation models shut down on August 17, and the Grok 4.1 family on the Gemini Enterprise Agent Platform on August 20
Articles/API / SDK
API / SDK/2026-04-28Beginner

Gemini API: GEMINI_API_KEY vs GOOGLE_API_KEY — Which One Should You Actually Use?

A practical, SDK-by-SDK guide to the GEMINI_API_KEY vs GOOGLE_API_KEY confusion. Covers precedence rules, the Vertex AI auto-switch, and four real-world traps with diagnostic snippets you can paste into a running app.

gemini-api277troubleshooting82api-key3environment-variablesgoogle-genai4vertex-ai8

"Nothing in my code changed, but the day after I bumped the SDK my app started crashing with API key not valid." This is one of the quieter, more frustrating traps you hit in your first month with the Gemini API. The cause is usually not the key itself — it is which environment variable the SDK is reading. GEMINI_API_KEY and GOOGLE_API_KEY look interchangeable, but every library has its own opinion about which one wins.

I personally lost two hours to this when I ported one of my side-project tools from Python to Node.js. This article maps out the precedence rules across the SDKs you are most likely to mix, the conditions that flip your client into Vertex AI mode, and the four traps that catch real developers — with a five-minute diagnostic snippet you can paste into any app to find out exactly which path is active.

Why two variable names exist in the first place

The Gemini SDK has gone through generations, and each generation set a different convention.

The legacy google-generativeai library, dominant through early 2024, did not read environment variables automatically. You configured it explicitly with genai.configure(api_key=...), and most developers fell into the habit of naming the variable GOOGLE_API_KEY because that matched the rest of Google Cloud.

The current google-genai library, the official replacement from late 2024 onward, formally adopted GEMINI_API_KEY as its primary name. For backward compatibility it still reads GOOGLE_API_KEY, but GEMINI_API_KEY wins when both are set. On top of that, setting GOOGLE_GENAI_USE_VERTEXAI=true quietly disables the API-key path entirely and switches the client to Application Default Credentials (ADC).

Add LangChain and the Vercel AI SDK — each with their own preferred variable names — and you end up with three coexisting worlds. That is the whole story behind the confusion.

Precedence cheat sheet by SDK

Here is how the most common libraries actually resolve the key.

  • google-genai (Python and Node.js): explicit api_key argument > GEMINI_API_KEY > GOOGLE_API_KEY. If both env vars are set, the first one wins.
  • google-genai in Vertex mode: when GOOGLE_GENAI_USE_VERTEXAI=true is set, API keys are ignored entirely. Authentication switches to ADC, and you must also have GOOGLE_CLOUD_PROJECT and GOOGLE_CLOUD_LOCATION set.
  • google-generativeai (legacy Python SDK): no automatic env reading. You must pass it yourself: genai.configure(api_key=os.getenv("GOOGLE_API_KEY")).
  • LangChain langchain-google-genai: expects GOOGLE_API_KEY. Setting only GEMINI_API_KEY produces a confusing "Invalid API key" error because LangChain never reads it.
  • Vercel AI SDK @ai-sdk/google: looks for GOOGLE_GENERATIVE_AI_API_KEY. A third name, distinct from both of the above.

The takeaway is that the same valid key may need to live under different names depending on which library is consuming it.

A five-minute diagnostic snippet

When authentication breaks, the first thing to confirm is which variables your process can actually see. Drop these four lines at the top of your Python entrypoint and the cause becomes obvious.

import os
 
# Print which key-related env vars are visible to this process at startup.
print("GEMINI_API_KEY:", "set" if os.getenv("GEMINI_API_KEY") else "missing")
print("GOOGLE_API_KEY:", "set" if os.getenv("GOOGLE_API_KEY") else "missing")
print("GOOGLE_GENAI_USE_VERTEXAI:", os.getenv("GOOGLE_GENAI_USE_VERTEXAI"))
print("GOOGLE_APPLICATION_CREDENTIALS:", os.getenv("GOOGLE_APPLICATION_CREDENTIALS"))

A healthy output for the API-key path looks like this:

GEMINI_API_KEY: set
GOOGLE_API_KEY: missing
GOOGLE_GENAI_USE_VERTEXAI: None
GOOGLE_APPLICATION_CREDENTIALS: None

If you see GOOGLE_GENAI_USE_VERTEXAI: true, your client is in Vertex mode. API keys are ignored and the SDK is trying ADC. If you have not run gcloud auth application-default login locally, you will get a 403 every time, no matter how correct your key is.

To confirm which path the new SDK actually took, peek at the client's internal state right after construction:

from google import genai
 
client = genai.Client()
print("vertexai mode:", client._api_client.vertexai)
print("api_key present:", bool(client._api_client.api_key))

vertexai mode: False plus api_key present: True means the API-key path is active. vertexai mode: True means you are on ADC. You can stop guessing. If your project is Node.js or TypeScript, the equivalent diagnostic is just as short. Place it before any SDK import to make sure the values you see match what the library will read.

// Node.js / TypeScript: print env state before any SDK initialization.
console.log("GEMINI_API_KEY:", process.env.GEMINI_API_KEY ? "set" : "missing");
console.log("GOOGLE_API_KEY:", process.env.GOOGLE_API_KEY ? "set" : "missing");
console.log("GOOGLE_GENAI_USE_VERTEXAI:", process.env.GOOGLE_GENAI_USE_VERTEXAI ?? "unset");
console.log("GOOGLE_APPLICATION_CREDENTIALS:", process.env.GOOGLE_APPLICATION_CREDENTIALS ?? "unset");

In serverless platforms — Vercel, Netlify, Cloudflare — these process.env reads return undefined for variables you forgot to register on the dashboard, even when they exist in your local .env.local. Seeing missing in the logs of a deployed function points you straight at the platform's environment variable settings rather than at the SDK.

Four traps that catch real developers

Once you know which variable is being read, the actual fixes fall out quickly. Here are the four patterns I see most often.

1. You set GOOGLE_API_KEY in .env.local, but the new SDK still returns 403. Check whether GOOGLE_GENAI_USE_VERTEXAI=true is leaking in from somewhere else — a Docker base image, a CI shell profile, or an old direnv block. unset GOOGLE_GENAI_USE_VERTEXAI clears it. If you never want Vertex mode in this project, write GOOGLE_GENAI_USE_VERTEXAI=false explicitly so a stray true upstream cannot reactivate it silently.

2. python-dotenv is not overriding what is in your shell. By default it does not overwrite values that already exist in the process environment. If your shell still has an old GOOGLE_API_KEY from last week, your fresh .env is being shadowed. Pass load_dotenv(override=True) or open a clean shell session.

3. LangChain throws "Invalid API key" while everything else works. LangChain reads GOOGLE_API_KEY, not GEMINI_API_KEY. Either set both, or inject the value explicitly: ChatGoogleGenerativeAI(google_api_key=os.getenv("GEMINI_API_KEY")). The latter is more explicit and survives future name changes.

4. Cloudflare Workers or Pages: it works locally but 401 in production. Workers do not read .env files. Register the key as a secret with wrangler secret put GEMINI_API_KEY, or — only for non-sensitive values — add it under [vars] in wrangler.toml. Anything in vars ships in plain text, so production keys belong on the secret side.

Where each platform expects you to put the key

Even with the SDK precedence sorted out, every deployment platform has its own loading model. Skipping these details is the second-largest cause of "works locally, breaks in production" auth bugs after the variable-name mismatch above.

  • Vercel: dashboard → Project Settings → Environment Variables. Vercel scopes variables to Production, Preview, and Development separately, so a key set only for Production silently disappears in vercel dev. If you use the Vercel AI SDK on top of google-genai, set GOOGLE_GENERATIVE_AI_API_KEY for the AI SDK and GEMINI_API_KEY for the underlying client both — the AI SDK reads the former, anything you call directly reads the latter.
  • Netlify: dashboard → Site Configuration → Environment Variables. Netlify Build and Netlify Functions share the same scope, but local netlify dev only injects values when you opt in with netlify env:get. A common surprise is that Edge Functions run in a different runtime where process.env is replaced by Netlify.env.get("GEMINI_API_KEY").
  • Cloudflare Workers / Pages: wrangler secret put GEMINI_API_KEY for sensitive values, [vars] in wrangler.toml for non-sensitive defaults. Workers expose values on the env parameter (env.GEMINI_API_KEY), not on process.env. Code copied from a Vercel project will silently read undefined on Workers because process.env is essentially empty in a Workers runtime.
  • AWS Lambda: configure as Lambda environment variables, or use AWS Secrets Manager for production. If you mount Secrets Manager values via the Parameters and Secrets Lambda Extension, they appear as files at /tmp/..., not as env vars — a subtle gotcha for anyone expecting process.env.GEMINI_API_KEY to be populated automatically.
  • Google Cloud Run: when you deploy from source, gcloud run deploy --set-env-vars=GEMINI_API_KEY=... is the most reliable path. For Vertex mode, you typically want --set-env-vars=GOOGLE_GENAI_USE_VERTEXAI=true,GOOGLE_CLOUD_LOCATION=us-central1 instead, with the API key omitted entirely.

The pattern in all five is the same: the platform owns environment injection, and the SDK only sees what was actually injected. Always print the diagnostic snippet from the previous section in your real deployment logs at least once after a deploy, before you start chasing imaginary SDK bugs.

Three operating rules for a calmer life

When you run multiple environments — local, CI, staging, production, plus side projects — these three rules dramatically cut auth incidents.

Rule 1: Log the auth path on startup. Drop the four os.getenv lines into your main.py so every process announces which variables are visible. Never log the key value itself; set versus missing is enough to triage.

Rule 2: Standardize on GEMINI_API_KEY for new projects. It is the official name, and it visually distinguishes Gemini keys from generic Google Cloud API keys. Keep GOOGLE_API_KEY only in legacy systems where renaming would touch too many call sites. Avoid mixing both within a single service.

Rule 3: Use the same variable name in CI and production. Environment-name drift is the single biggest cause of "works on my machine" auth bugs. Pin one name per service and write it down in an ENV.md at the repo root — your future self, three months from now, will thank you.

For the broader setup story, the Google AI Studio API key setup and management guide and the Gemini API authentication error solutions article cover provisioning and the failure modes around it. If you are migrating between SDK generations, the google-genai Python SDK migration guide is the natural next stop.

Open the .env of whichever project you are touching today, say out loud which variable name is in use, and you will already be in better shape than most teams the next time you bump the SDK.

Share

Thank You for Reading

Gemini Lab is ad-free, supported entirely by members like you. We publish practical guides daily with implementation code, benchmarks, and production-ready patterns. If you've found it useful, we'd love to have you on board.

  • Copy-paste ready implementation code
  • New advanced guides published daily
  • $5/mo or $10 for lifetime access
View Membership →

If you found this article helpful, a small tip ($1.50) would mean a lot to us. Your support helps keep this site ad-free and covers server and hosting costs.

Related Articles

API / SDK2026-05-29
Why HTTP Referrer Restrictions on Your Gemini API Key Cause 403 Errors in Production
Walks through why a Gemini API key with HTTP referrer restrictions can suddenly return 403 PERMISSION_DENIED in production. Covers the exact referrer string format, SDK behavior differences, how to safely route around the limitation with a tiny edge proxy, and how it differs from the CORS error you hit when calling straight from the browser.
API / SDK2026-05-28
Why per-turn generationConfig is ignored in Gemini API chat sessions
If you pass a different generationConfig (temperature, max_output_tokens, response_schema) to each send_message in a google-genai chat session and the behavior never changes, this walkthrough shows what is actually happening, why the SDK is designed that way, and three workarounds we use in production for review-summary and reply-draft pipelines.
API / SDK2026-05-10
What I Tried, In Order, When Gemini API Returned User location is not supported in Production
Hitting the Gemini API from Cloudflare Workers or Vercel and getting hit with a sudden 'User location is not supported' error? Here is the exact order I worked through, drawn from a live production incident on my own indie apps.
📚RECOMMENDED BOOKS
Build a Large Language Model (From Scratch)
Sebastian Raschka
LLM Dev
Prompt Engineering for LLMs
Berryman & Ziegler
Prompting
AI Engineering
Chip Huyen
AI Eng
* Contains affiliate links
See all →