Use Gemini through a custom endpoint
The simplest reliable route to Gemini on a third-party endpoint is the OpenAI-compatible one: point any OpenAI SDK at the base URL, pass a Gemini model ID, and both chat and streaming work without a second SDK.
https://aicomp.ai/v1).
Create one free →
curl https://aicomp.ai/v1/models \
-H "Authorization: Bearer sk-your-gateway-key"
A JSON list of model IDs means the key is good. Invalid token means it was copied wrong.
Get the exact model ID first
This matters more for Gemini than for any other family. Model strings carry version and preview suffixes, and they differ between providers — copying an ID from generic documentation for a different platform is the most common source of a 404. Read yours off the models endpoint and use it verbatim:
curl "$GATEWAY_BASE/chat/completions" \
-H "Authorization: Bearer $GATEWAY_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "gemini-3.1-flash-lite",
"messages": [{"role": "user", "content": "Say OK"}],
"max_tokens": 64
}'
# First confirm the exact model ID your gateway exposes:
curl "$GATEWAY_BASE/models" -H "Authorization: Bearer $GATEWAY_KEY"
Through the OpenAI SDK
One client across OpenAI, Anthropic-shaped and Gemini models. This is the reason most teams prefer the compatible route — there is nothing new to learn and nothing vendor-specific to maintain:
import OpenAI from "openai";
// Gemini is reachable through an OpenAI-compatible route on many gateways.
const client = new OpenAI({
apiKey: process.env.GATEWAY_KEY,
baseURL: process.env.GATEWAY_BASE,
});
const res = await client.chat.completions.create({
model: "gemini-3.5-flash",
messages: [
{ role: "system", content: "Answer in one sentence." },
{ role: "user", content: "Why is Neptune blue?" },
],
max_tokens: 200,
});
console.log(res.choices[0].message.content);
Streaming
const stream = await client.chat.completions.create({
model: "gemini-3-flash-preview",
messages: [{ role: "user", content: "Summarise rate limiting in three bullets." }],
max_tokens: 300,
stream: true,
});
for await (const chunk of stream) {
process.stdout.write(chunk.choices[0]?.delta?.content ?? "");
}
If the chunks arrive together rather than incrementally, the endpoint is buffering. The response is still correct, you just lose the perceived-speed benefit, worth knowing before you build a typing UI on it.
Two routes to the same models
There are two ways to reach Gemini through a non-Google endpoint, and they are not interchangeable in maintenance cost even though they return the same completions.
The OpenAI-compatible route is the one this page uses: any OpenAI SDK, one base URL, Gemini model IDs in the model field. You keep one client, one request shape and one error-handling path across every vendor you call. The cost of that simplicity is that you only get what the compatible surface exposes — Gemini-specific parameters that the native client accepts as named options may not have a compatible equivalent.
The native SDK route keeps those options, at the price of a second client whose option names have changed between SDK generations. It is the right choice when you depend on a Gemini-specific feature that the compatible route does not carry. It is the wrong choice when you are simply consolidating billing: you would be maintaining two clients to save yourself changing one string.
Rates
| Model | Gateway rate in / out per 1M tokens | Official list in / out per 1M tokens |
|---|---|---|
| gemini-3.5-flash | $0.75 / $4.5 | — / — |
| gemini-3-flash-preview | $0.25 / $1.5 | — / — |
| gemini-3.1-flash-lite | $0.125 / $0.75 | — / — |
Rates checked 2026-11-01. Gateway rates move with upstream promotions (verify the current number in your dashboard before committing to a budget).
These are gateway rates and none of them carry a verified official list price in our data, unlike the OpenAI and Anthropic rows elsewhere on this site, the gateway column here cannot be cross-checked against published figures. Treat them as what the gateway charges, not as a discount claim.
What long context actually costs
Long context is the reason to look at Gemini at all, and it is also where the bill stops behaving like a chat bill. Once the prompt is measured in hundreds of thousands of tokens, the answer is a rounding error: the entire cost is input. That makes the comparison simple (the input rate is the only number that matters) and it makes the absolute numbers worth checking before you design around a large window.
| Workload | gemini-3.5-flash | gemini-3-flash-preview | gemini-3.1-flash-lite |
|---|---|---|---|
| One question over 100k tokens | $0.08 | $0.03 | $0.01 |
| One question over 500k tokens | $0.38 | $0.13 | $0.06 |
| One question over 1M tokens | $0.77 | $0.26 | $0.13 |
| 20 questions a day over 100k, for a month | $33.60 | $11.20 | $5.60 |
The monthly row assumes 20 working days. Output is held at a few thousand tokens throughout, because at these context sizes it is a rounding error either way.
Two things follow from the table. First, a single large-context question is cheap in absolute terms; it is repetition that turns it into a line item, which is why the last row is twenty times the first and not twenty times a tiny number. Second, if your workload is mostly long context, a model that looks expensive per output token can still be the cheapest option, because you are barely buying any output. Judge these models on their input rate or you will rank them backwards.
Troubleshooting
| Symptom | Cause and fix |
|---|---|
| 404 model not found | Wrong ID string. Copy it from /models, suffixes included. |
| 401 invalid key | Key truncated on copy, or env var not loaded in this runtime. |
| Unexpected response shape | You hit a Gemini-native path with an OpenAI-shaped client. Use the compatible route. |
| Streaming returns nothing | Some builds require SSE-compatible headers; test with curl before debugging the SDK. |
| 429 immediately | Per-model quota, not a global one. Back off exponentially and retry. |
FAQ
Can I use the official Google SDK with a custom endpoint?
Usually yes, but the parameter name has changed between SDK generations (earlier releases used different option names for the endpoint than recent ones). Check the docs for the exact version you have installed. The OpenAI-compatible route avoids the question entirely and works with the SDK most projects already depend on.
Which Gemini model IDs work?
Whatever your provider exposes, and they do differ, some carry -preview or date suffixes. Always read them off GET /models rather than guessing from documentation for a different platform.
Does streaming work?
Usually on the OpenAI-compatible route, but verify it. If chunks arrive as one block the endpoint is buffering, which is functionally fine but removes the time-to-first-token benefit.
Do Gemini rate limits work differently?
The quota dimensions are vendor-specific and enforced per model rather than per account. Treat a 429 as a signal to back off exponentially rather than to change model.
Why does the same Gemini model cost different amounts at different providers?
Providers resell the same models at different markups, and some expose versioned variants at the same rate as the stable one. Compare the exact string (the table above lists the IDs we track).
What is the Gemini API base URL?
It is the root path your client sends every request to, and it is the only value you change, request shapes stay identical to OpenAI's. On a gateway it is one host plus /v1, and the model you want is chosen by ID rather than by a different URL. If you are coming from the official Google client, this single value replaces the endpoint the SDK hardcodes.
What is the Gemini API endpoint URL for chat completions?
Chat completions sit at /v1/chat/completions under the base URL. The same path OpenAI uses, which is exactly why an existing OpenAI client works unchanged. You do not need a Gemini-specific endpoint or a second SDK; put a Gemini model ID in the model field instead.
Is there an OpenAI-compatible Gemini endpoint?
Yes, and it is the route this page recommends. Any OpenAI SDK pointed at an OpenAI-compatible base URL can call Gemini models by ID, streaming included. The alternative, a Gemini-native client with an overridden endpoint, also works, but ties you to option names that have changed between SDK generations.
Related
- Custom base URL in Node.js
- What 'OpenAI-compatible' covers
- Every tool that accepts a custom endpoint (LiteLLM, Vercel AI SDK, Cline and the rest), on one key
- LiteLLM against a custom endpoint — per-call override or shared proxy
- Vercel AI SDK with a custom endpoint —
createOpenAIinstead of the provider helper - Open WebUI with a custom endpoint, a shared, self-hosted chat front end
- LobeChat with a custom endpoint (the chat-UI shape), where
OPENAI_PROXY_URLand a model list decide what you can pick - All Gemini models compared
- Rate limits explained
- 404 Not Found: v1beta, double slashes and OAuth mode