We rotated our Gemini key this week to unblock our CMS image generator. The first fresh key landed on Convex env and immediately got back HTTP 403 with a message that looked like billing: "Requests to this API generativelanguage.googleapis.com are blocked." An hour later we learned the problem was not billing and the key was not invalid. The key was fine. We were sending it to the wrong endpoint.
If you are integrating Gemini, this is the thing that costs you an hour. It does not cost you an hour twice.
Two keys, two endpoints
Google has two surfaces for Gemini that look interchangeable from the outside. They are not.
AI Studio is the consumer-style developer product. Keys from aistudio.google.com/apikey start with AIzaSy and are 39 characters long. They authenticate at https://generativelanguage.googleapis.com/v1beta. The shape is a single free-tier-friendly API meant for prototypes, side projects, and small apps.
Vertex AI (Express Mode) is Google Cloud's production surface. Keys minted through the Vertex Express flow start with AQ. and are around 53 characters long. They authenticate at https://aiplatform.googleapis.com/v1. Same x-goog-api-key header, different URL, slightly different request body — Vertex requires a role field on each content item that AI Studio lets you omit.
The 403 was Google saying, politely: the key you sent me is cut for a different door.
How to tell which one you have
Look at the prefix and the length.
| Prefix | Length | Surface | Endpoint |
|---|---|---|---|
AIzaSy |
39 chars | AI Studio | generativelanguage.googleapis.com/v1beta |
AQ. |
~53 chars | Vertex Express | aiplatform.googleapis.com/v1 |
That is the whole diagnostic. No dashboard clicks, no gcloud CLI. If your key prefix is AQ. and you are hitting the AI Studio endpoint, you will get API_KEY_SERVICE_BLOCKED every time — not because the key is bad, but because Google explicitly restricts AI Studio-only services from Vertex keys on principle.
What we changed in the client
Our fetch client now supports both surfaces behind a single toggle. The relevant signature:
type GeminiSurface = "ai-studio" | "vertex";
createGeminiFetchClient({
apiKey: process.env.GEMINI_API_KEY,
surface: process.env.GEMINI_API_SURFACE as GeminiSurface | undefined,
});
We default to vertex because it is a strict superset — the Vertex endpoint accepts both key types, reaches newer models sooner, and is the surface any production Google Cloud project is likely to mint from. If you explicitly want AI Studio semantics, set GEMINI_API_SURFACE=ai-studio alongside the key. No other change at the integration layer.
The request body is also a tiny bit different. Vertex requires role: "user" on each content item; AI Studio accepts it but does not require it. We always set it now — safe across both surfaces, and the one-line guardrail means we never have to remember which endpoint we are currently pointed at.
The diagnostic routine
The next time a Gemini key gets rejected, do this in order:
- Check the prefix.
AIzaSy…vsAQ.…. That rules in or out 80% of the confusion immediately. - Check the endpoint URL you are hitting.
generativelanguage.googleapis.comoraiplatform.googleapis.com. If prefix and URL disagree, that is your bug. - If they agree and you still get 403 — now you can go look at billing, API enablement on the GCP project, and key restrictions. In that order. Almost always the answer is "the API was not enabled on the project," which is a two-click fix in the Google Cloud console.
The trap is that all three failure modes (wrong endpoint / billing / API disabled) return roughly the same error string. So the prefix check has to come first. Google could tell you which of the three it is in their error message, and one day they will. Until then, it is your job to read the key.
The short version
AIzaSy…means AI Studio endpoint.AQ.…means Vertex endpoint. They are not interchangeable.- Default your client to Vertex. It accepts both key formats and reaches newer models.
- Always include
role: "user"on content items. Vertex requires it; AI Studio ignores it. - When a 403 lands, read the key before you read the billing dashboard.