Asale

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 URLhttps://gw.asale.ai
Auth headerx-goog-api-key: sk-asale-...
SDK env varGEMINI_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

MethodPathNotes
POST/v1beta/models/{model}:generateContentThe main one.
POST/v1beta/models/{model}:streamGenerateContentStreaming — the method name is the flag.
GET/v1beta/modelsWhat 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

  • generationConfigmaxOutputTokens, temperature, topP, stopSequences and the thinking budget pass through.
  • systemInstruction passes through as the system prompt.
  • tools / functionCall / functionResponse pass 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/models is the list; the market shows which of them have supply.
  • Request bodies are capped at 16 MiB.