ASAI inference
An OpenAI-compatible endpoint. Point any OpenAI SDK at it, change the base URL and the model name, and it works — streaming and tool calls included.
Base URL https://asai.aperturesyndicate.com/api/v1| Method | Endpoint | |
|---|---|---|
POST | /chat/completions | Chat completion, streamed or whole |
GET | /models | The three model names |
Keys
Every request carries Authorization: Bearer asai_…. There are two kinds of asai_ key, and they differ only in who pays:
| Key | Where | Who pays |
|---|---|---|
| Dev Studio key | Dev Studio → ASAI keys | The wallet folder the key is attached to, at twice the model's price. No ASAI plan needed |
| Personal key | ASAI → Settings → API | Your ASAI energy, the same pool as the chat. Needs ASAI Pro or Etherane |
A key is shown once, when it is created — we keep only its hash. Revoke a leaked key and issue a new one. Keys from the old developer portal list, the ones that do not start with asai_, do not open this API.
Models
| Model | For |
|---|---|
asai-mini | Fast everyday answers |
asai-arc | Harder reasoning, longer answers |
asai-code | Code — the default when the name matches nothing |
The name is matched loosely: anything containing arc goes to asai-arc, anything containing mini or chat to asai-mini, everything else to asai-code. The model field of the response always carries one of the three public names.
Request
from openai import OpenAI
client = OpenAI(
api_key="asai_…",
base_url="https://asai.aperturesyndicate.com/api/v1",
)
stream = client.chat.completions.create(
model="asai-code",
messages=[{"role": "user", "content": "Explain this stack trace"}],
stream=True,
)
for chunk in stream:
print(chunk.choices[0].delta.content or "", end="")| Field | |
|---|---|
model | One of the names above |
messages | Non-empty; roles system, user, assistant, tool. content is a string or a list of text and image_url parts |
stream | true for server-sent events in the OpenAI chunk format |
temperature | Optional |
max_tokens / max_completion_tokens | Optional, capped at 32 768. Without it each model uses its own default |
tools | Function tools; parameters must be a JSON schema with type: "object" |
tool_choice | auto, none, required, or a named function |
Other OpenAI fields are ignored. Responses follow the OpenAI format, including usage.
How a request is paid for
A request costs what its tokens cost on the model that answered: fresh input, cached input and output are priced separately.
- Dev Studio key — twice that price is charged to the key's wallet folder after the answer, including a stream you cut off midway. When the folder reaches zero, requests get
402until you add funds in Wallet. - Personal key — the price is taken from your ASAI energy, with the same weekly budget and daily brake as the chat.
asai-arcis open on plans that include it.
Errors
Errors come in the OpenAI shape, so SDKs raise their usual exceptions:
{ "error": { "message": "Invalid API key.", "type": "invalid_request_error", "code": "invalid_api_key" } }| Status | code | Means |
|---|---|---|
400 | invalid_request | Body is not JSON, or messages is empty or malformed |
401 | invalid_api_key | Missing, wrong or revoked key |
402 | budget_exhausted | The wallet folder behind a Dev Studio key is empty |
403 | model_not_available | Personal key: the plan has no API access, or no asai-arc |
429 | invalid_request | 60 requests per minute per key exceeded, or a personal key ran out of daily or weekly energy — the message says which |
503 | billing_unavailable | We could not check the wallet folder — retry |
5xx | The model service is unavailable — retry with backoff |
Rules
- Do not resell access to the API.
- Keep keys on your server. A key in a browser bundle or an app binary will be found.
- Content rules are the same as in the chat: ASAI Acceptable Use.
- Full terms: Developer & API Terms.