Asale

OpenAI-compatible API

Chat Completions and Responses against the Asale gateway, with the official OpenAI SDKs. Change the base URL and the key; the rest of your code is untouched.

The OpenAI dialect is the broadest one the gateway speaks, and the one most third-party libraries already target. If your code uses the openai package — or anything that imitates it — this is the page you want.

Read the overview first for keys, models, billing and errors; everything here is the OpenAI-specific part.

Connection

Base URLhttps://gw.asale.ai/v1
Auth headerAuthorization: Bearer sk-asale-...
SDK env varOPENAI_API_KEY, OPENAI_BASE_URL

The /v1 belongs to the base URL here: OpenAI's clients append /chat/completions to whatever you give them.

Endpoints

MethodPathNotes
POST/v1/chat/completionsThe main one.
POST/v1/responsesThe Responses API. Codex ≥ 0.146 speaks only this.
POST/v1/completionsLegacy text completions, mapped onto the same path.
GET/v1/modelsWhat the platform will match right now.

Call it

curl https://gw.asale.ai/v1/chat/completions \
  -H "Authorization: Bearer $ASALE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gpt-5",
    "messages": [{"role": "user", "content": "Hello"}],
    "stream": false
  }'
# pip install openai
import os
from openai import OpenAI

client = OpenAI(
    api_key=os.environ["ASALE_API_KEY"],
    base_url="https://gw.asale.ai/v1",
)

resp = client.chat.completions.create(
    model="gpt-5",
    messages=[{"role": "user", "content": "Hello"}],
)
print(resp.choices[0].message.content)
// npm i openai
import OpenAI from "openai";

const client = new OpenAI({
  apiKey: process.env.ASALE_API_KEY,
  baseURL: "https://gw.asale.ai/v1",
});

const resp = await client.chat.completions.create({
  model: "gpt-5",
  messages: [{ role: "user", content: "Hello" }],
});
console.log(resp.choices[0].message.content);

Streaming

stream: true returns text/event-stream with chat.completion.chunk events and a final data: [DONE], exactly as the OpenAI API does. Your existing parser needs no changes.

stream = client.chat.completions.create(
    model="gpt-5",
    messages=[{"role": "user", "content": "Count to five"}],
    stream=True,
)
for chunk in stream:
    delta = chunk.choices[0].delta.content
    if delta:
        print(delta, end="", flush=True)

Tool calling

tools and tool_choice pass through, and the assistant's tool_calls come back in the same shape. Send the result as a role: "tool" message with its tool_call_id, as usual.

The model behind a request may be served by a publisher on any supported vendor, and the gateway translates between wire formats. Provider-specific opaque blobs — a reasoning signature, an encrypted_content — are only handed back when the request and the server speak the same wire; otherwise they are dropped rather than forged.

Practical notes

  • Set max_tokens. It is what the balance hold is computed from. Leaving it out makes the hold conservative, which can read as "insufficient balance" on an account that has plenty for the actual reply.
  • Model names are the platform's. GET /v1/models is the list; the market shows which of them have supply.
  • Images work where the model does. Request bodies are capped at 16 MiB, which is well above a typical inlined image; past that the gateway answers 413.
  • n is ignored — one completion per request.