Gemini-compatible API
generateContent against the Asale gateway, with the official google-genai SDKs. Change the base URL and the key; your request bodies stay as they are.
The Gemini dialect is what google-genai and gemini-cli speak. Unlike the other two it carries both the model and the streaming flag in the path, not the body — which is the one thing to get right when you wire it up by hand.
Read the overview first for keys, models, billing and errors; everything here is the Gemini-specific part.
Connection
| Base URL | https://gw.asale.ai |
| Auth header | x-goog-api-key: sk-asale-... |
| SDK env var | GEMINI_API_KEY, GOOGLE_GEMINI_BASE_URL |
The base URL stops at the host. Google's clients append /v1beta/models/… themselves, so giving them https://gw.asale.ai/v1beta produces a doubled path and a 404. GOOGLE_GEMINI_BASE_URL — what gemini-cli reads — is an origin too.
Authorization: Bearer and x-api-key are accepted as well. A key in the ?key= query string is not — put it in a header.
Endpoints
| Method | Path | Notes |
|---|---|---|
| POST | /v1beta/models/{model}:generateContent | The main one. |
| POST | /v1beta/models/{model}:streamGenerateContent | Streaming — the method name is the flag. |
| GET | /v1beta/models | What the platform will match right now. |
Call it
curl "https://gw.asale.ai/v1beta/models/gemini-2.5-pro:generateContent" \
-H "x-goog-api-key: $ASALE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"contents": [{"role": "user", "parts": [{"text": "Hello"}]}]
}'
# pip install google-genai
import os
from google import genai
from google.genai import types
client = genai.Client(
api_key=os.environ["ASALE_API_KEY"],
http_options=types.HttpOptions(base_url="https://gw.asale.ai"),
)
resp = client.models.generate_content(
model="gemini-2.5-pro",
contents="Hello",
)
print(resp.text)
// npm i @google/genai
import { GoogleGenAI } from "@google/genai";
const ai = new GoogleGenAI({
apiKey: process.env.ASALE_API_KEY,
httpOptions: { baseUrl: "https://gw.asale.ai" },
});
const resp = await ai.models.generateContent({
model: "gemini-2.5-pro",
contents: "Hello",
});
console.log(resp.text);
Streaming
Call :streamGenerateContent instead of :generateContent. The method suffix is what turns streaming on — there is no stream field in a Gemini body — and the response is server-sent events carrying GenerateContentResponse chunks.
for chunk in client.models.generate_content_stream(
model="gemini-2.5-pro",
contents="Count to five",
):
print(chunk.text, end="", flush=True)
Generation config and tools
generationConfig—maxOutputTokens,temperature,topP,stopSequencesand the thinking budget pass through.systemInstructionpasses through as the system prompt.tools/functionCall/functionResponsepass through in their native shape.
Practical notes
- The model in the path wins. If the path names one model and the body another, the path is what you addressed and the path is what is served.
- Set
maxOutputTokens. It is what the balance hold is computed from; the difference returns when the response finishes. - Model names are the platform's, not Google's SKU list.
GET /v1beta/modelsis the list; the market shows which of them have supply. - Request bodies are capped at 16 MiB.