This message is Google's catch-all: the key you sent could not be used for this call. That is not the same as the key being wrong, and four of the five causes leave the key itself perfectly valid — which is why re-copying it is usually wasted effort.
The error
{
"error": {
"code": 400,
"message": "API key not valid. Please pass a valid API key.",
"status": "INVALID_ARGUMENT",
"details": [{ "reason": "API_KEY_INVALID" }]
}
}Causes and fixes at a glance
| Cause | Fix |
|---|---|
| The Generative Language API is not enabled on the key's project | Enable it for that project, then wait a minute — freshly enabled APIs reject for a short window. |
| A Vertex AI credential sent to the AI Studio endpoint | Vertex uses OAuth against a regional host; generativelanguage.googleapis.com wants an AI Studio API key. They are not interchangeable. |
| The key carries HTTP-referrer or IP restrictions | Server-side calls send no referrer. Restrict by IP, or issue an unrestricted key for backend use. |
| Key sent in the wrong place | Gemini reads `x-goog-api-key` or `?key=`. An `Authorization: Bearer` header is ignored, so the request arrives keyless. |
| Key deleted, or from a different Google account than you think | The only cause where re-issuing helps. Check which account AI Studio is logged into. |
Prove the key in isolation first
Before touching your application, take the key to a bare request. If this works and your app does not, the key is fine and the bug is in how your app transmits it — which eliminates the three most common causes at once.
curl -s -H "x-goog-api-key: $GEMINI_API_KEY" \
"https://generativelanguage.googleapis.com/v1beta/models" \
| head -20
# 200 + a model list -> the key is valid; look at your client
# 400 API_KEY_INVALID -> the key really cannot call this APIRead which header your client actually sends
Most OpenAI-shaped SDKs put credentials in `Authorization: Bearer`. Gemini's native API does not read that header, so pointing an OpenAI client straight at generativelanguage.googleapis.com produces this exact error with a perfectly good key. Either use Google's SDK, or call an OpenAI-compatible endpoint that expects the bearer form.
from openai import OpenAI
# Bearer auth, OpenAI request shape, Gemini model names.
client = OpenAI(
api_key=KUNAVO_API_KEY,
base_url="https://api.kunavo.com/v1",
)
print(client.chat.completions.create(
model="gemini-2-5-flash",
messages=[{"role": "user", "content": "ping"}],
).choices[0].message.content)Separate 400 from 403
If the reason changes to PERMISSION_DENIED once the key is transmitted correctly, the key is now being read and rejected on scope — a different problem with a different fix (project permissions, not key format). Getting from 400 to 403 is progress, not a regression.
If you’re calling through Kunavo
On Kunavo the Gemini shelf sits behind the same OpenAI-shaped endpoint and the same `sk-kn-` key as everything else, sent as a normal bearer token — so the header-mismatch and Vertex-vs-AI-Studio causes above simply do not have a form to take. There is no Google project to enable and no per-key referrer policy to trip over. What stays your responsibility is the key being live and the wallet funded; a rejected request is not billed. Per-token Gemini rates are in our Gemini pricing guide.
FAQ
I just created the key and it still says invalid.
Newly enabled APIs and brand-new keys can reject for up to a minute or two. If it persists past that, the project almost certainly lacks the Generative Language API rather than the key being bad.
Does this mean I ran out of quota?
No. Quota exhaustion is 429 RESOURCE_EXHAUSTED, and billing problems surface as 403. A 400 API_KEY_INVALID never means you are out of credit.
Why does the same key work in AI Studio but not in my code?
AI Studio calls from Google's own origin. A referrer-restricted key allows that and refuses your server, which sends no referrer at all.
Related guides
- Gemini API key not working — API_KEY_INVALID and its five causes
- Gemini API 429 RESOURCE_EXHAUSTED — quota vs rate limit, fixed properly
- OpenAI-compatible API returning 401/403 — base_url and header pitfalls
More error semantics live in the error reference; getting a key takes a minute via sign up and the authentication docs.