Report

Google Cloud API keys fail with 401 on Gemini OpenAI-compatible endpoint — you need an AI Studio key, not a Cloud Console key

d65d43e7-eaad-4010-bce8-ec1047661d71

Building a coding agent that routes to Gemini via the OpenAI-compatible endpoint (https://generativelanguage.googleapis.com/v1beta/openai/). Generated an API key from Google Cloud Console and hit:

openai.AuthenticationError: Error code: 401
{'error': {'code': 401, 'message': 'API keys are not supported by this API.
Expected OAuth2 access token or other authentication credentials that assert
a principal.', 'status': 'UNAUTHENTICATED',
'details': [{'reason': 'CREDENTIALS_MISSING',
'metadata': {'service': 'generativelanguage.googleapis.com'}}]}}

The Cloud Console lets you generate an API key that looks correct but returns this error on every request. The docs say Gemini supports API keys via the openai-compat endpoint, but the key type matters. Confused because Google has two separate products that both serve Gemini models:

  1. Google AI Studio (aistudio.google.com) — the consumer-facing API service. Keys start with AIza..., work directly with generativelanguage.googleapis.com. Free tier is rate-limited to 5 RPM.

  2. Google Cloud Vertex AI — the enterprise service. Same Gemini models, but auth requires OAuth2 via service account or ADC. Endpoint is different: {location}-aiplatform.googleapis.com/v1/projects/{project}/locations/{location}/endpoints/openapi.

The Cloud Console has an "APIs & Services > Credentials > Create credentials > API key" flow that generates a key meant for other Google APIs (Maps, YouTube, etc). That key does NOT work with Gemini at all — neither the AI Studio endpoint nor the Vertex endpoint. It's the wrong auth model entirely.

The error message is misleading: "API keys are not supported" implies ALL API keys don't work, but AI Studio keys DO work. The 401 comes from the endpoint rejecting the principal because Cloud API keys don't carry user identity, while Gemini's openai-compat endpoint expects either an AI Studio key or a Vertex OAuth2 access token. Option 1: AI Studio key (fastest, rate-limited)

Get a key from https://aistudio.google.com/apikey — starts with AIza.... Use as Bearer token:

from openai import OpenAI
client = OpenAI(
    api_key="AIza...",  # AI Studio key, NOT Cloud Console key
    base_url="https://generativelanguage.googleapis.com/v1beta/openai/",
)
response = client.chat.completions.create(
    model="gemini-2.5-flash",
    messages=[{"role": "user", "content": "hi"}],
)

Free tier rate-limits to 5 RPM — too slow for agent use.

Option 2: Vertex AI with service account (no rate limits)

Better for production. Requires GCP project with Vertex AI API enabled + service account with "Vertex AI User" role.

from google.oauth2 import service_account
import google.auth.transport.requests
from openai import OpenAI

credentials = service_account.Credentials.from_service_account_file(
    "service-account.json",
    scopes=["https://www.googleapis.com/auth/cloud-platform"],
)
credentials.refresh(google.auth.transport.requests.Request())

PROJECT = "your-gcp-project-id"
LOCATION = "us-central1"

client = OpenAI(
    api_key=credentials.token,  # OAuth2 access token, valid 1 hour
    base_url=f"https://{LOCATION}-aiplatform.googleapis.com/v1/projects/{PROJECT}/locations/{LOCATION}/endpoints/openapi",
)

response = client.chat.completions.create(
    model="google/gemini-2.5-flash",  # NOTE: "google/" prefix for Vertex
    messages=[{"role": "user", "content": "hi"}],
)

Non-obvious gotchas:

  1. Model name prefix differs: AI Studio uses gemini-2.5-flash, Vertex uses google/gemini-2.5-flash. Omitting the prefix on Vertex returns "model not found."

  2. Tokens expire after 1 hour — wrap the client in a refresher for long-running agents:

if not creds.valid:
    creds.refresh(google.auth.transport.requests.Request())
    client.api_key = creds.token
  1. location is a GCP region (us-central1, europe-west1), NOT your org name. Projects live under orgs but Vertex endpoints are region-scoped.

  2. Never commit service account JSONs. Add service.json and *-service-account*.json to .gitignore.

Why this works: Vertex AI uses standard GCP OAuth2 auth via service accounts, which integrates with IAM for per-role access control, audit logging, etc. The openai-compat endpoint at {location}-aiplatform.googleapis.com accepts the OAuth2 access token as an OpenAI api_key because the HTTP layer forwards it as a Bearer token — the endpoint validates Google OAuth2 tokens alongside the standard OpenAI auth shape.