API reference
LinuxAir implements the OpenAI Chat Completions API. Existing SDKs work unchanged — only the base URL and key differ.
Base URL & authentication
https://ai.linuxair.com/v1Send your LinuxAir key as a bearer token, or in an x-api-key header:
Authorization: Bearer la-xxxxxxxxxxxxxxxxxxxxxxxxKeys issued before the LinuxAir rebrand (prefix rq-) continue to work. Each key has its own requests-per-minute limit.
Create a chat completion
Routes the request and returns a standard chat completion.
Body
| Field | Type | Description |
|---|---|---|
messages | array | Required. OpenAI-format messages. |
model | string | auto (default), la/quality, la/balanced, la/economy, or the id of a model in your workspace to pin it. |
stream | boolean | Stream tokens as server-sent events. |
temperature, top_p, max_tokens, stop, presence_penalty, frequency_penalty, seed, user | — | Passed through to the chosen model. |
response_format, tools, tool_choice | — | Passed through. Answer checks are skipped when tools are used. |
la | object | Optional routing controls (below). Also accepted as linuxair. |
Routing controls
| Field | Type | Description |
|---|---|---|
lambda | number 0–2 | Price weight. 0 = quality first, 2 = savings first. |
tolerance | number 0–0.3 | Max predicted-quality loss accepted, as a fraction (0.02 = 2 pts). Defaults from λ. |
min_quality | number 0–1 | Exclude models predicted below this quality. |
max_cost | number | Estimated USD ceiling for this request. |
models | array | Only consider these models (ids or names). |
exclude | array | Never use these models. |
latency_weight | number 0–1 | Prefer faster models among near-equals. |
cascade | boolean | Enable or disable answer checks for this request. |
cache | boolean | Set false to bypass the semantic cache for this request. |
r = client.chat.completions.create(
model="auto",
messages=[{"role": "user", "content": "Classify this ticket: ..."}],
extra_body={"la": {"tolerance": 0.02, "max_cost": 0.002, "exclude": ["gpt-4o"]}},
)const r = await client.chat.completions.create({
model: "auto",
messages: [{ role: "user", content: "Classify this ticket: ..." }],
// @ts-ignore — extra routing controls
la: { tolerance: 0.02, max_cost: 0.002, exclude: ["gpt-4o"] },
});curl https://ai.linuxair.com/v1/chat/completions \
-H "Authorization: Bearer $LINUXAIR_KEY" -H "Content-Type: application/json" \
-d '{"model":"auto","messages":[{"role":"user","content":"Classify this ticket"}],
"la":{"tolerance":0.02,"max_cost":0.002}}'Response
A standard chat completion, plus a linuxair object and headers X-LinuxAir-Request-Id, X-LinuxAir-Model and X-LinuxAir-Cache (hit or miss).
{
"id": "chatcmpl-rq_8f3a...",
"object": "chat.completion",
"model": "gpt-4.1-mini",
"choices": [{ "index": 0, "message": { "role": "assistant", "content": "..." }, "finish_reason": "stop" }],
"usage": { "prompt_tokens": 212, "completion_tokens": 96, "total_tokens": 308 },
"linuxair": {
"request_id": "rq_8f3a...",
"model_label": "GPT-4.1 Mini",
"cluster": 2,
"lambda": 0.35,
"tolerance": 0.026,
"predicted_quality": 0.93,
"predicted_error": 0.07,
"uncertainty": 0.018,
"reason": "within 1.1 pts of the best model, 6.2x cheaper",
"escalated": false,
"cached": false,
"judge_score": null,
"cost_usd": 0.00024,
"baseline_cost_usd": 0.00149,
"saved_usd": 0.00125,
"candidates": [
{ "model": "gpt-4.1-mini", "predicted_quality": 0.93, "in_tolerance": true, "est_cost_usd": 0.00024, "why": "..." },
{ "model": "gpt-4.1", "predicted_quality": 0.94, "in_tolerance": true, "est_cost_usd": 0.00149, "why": "..." }
]
}
}Streaming
Set stream: true to receive OpenAI-format server-sent events ending with data: [DONE]. The chosen model is in the X-LinuxAir-Model response header. Failover happens before the first token; answer checks are not applied to streamed responses.
stream = client.chat.completions.create(model="la/balanced", stream=True,
messages=[{"role": "user", "content": "Draft a polite payment reminder"}])
for chunk in stream:
print(chunk.choices[0].delta.content or "", end="")Embeddings
Same base URL and key as completions, so one endpoint covers both.
r = client.embeddings.create(model="auto", input=["first text", "second text"])
print(len(r.data[0].embedding))Batch
Send up to 500 requests at once. They run in the background at a reduced platform fee and are routed, logged and metered exactly like live requests.
curl https://ai.linuxair.com/v1/batches \
-H "Authorization: Bearer $LINUXAIR_KEY" -H "Content-Type: application/json" \
-d '{"requests": [
{"custom_id": "row-1", "messages": [{"role":"user","content":"Classify: ..."}]},
{"custom_id": "row-2", "messages": [{"role":"user","content":"Classify: ..."}]}
]}'curl https://ai.linuxair.com/v1/batches/retrieve \
-H "Authorization: Bearer $LINUXAIR_KEY" -H "Content-Type: application/json" \
-d '{"id": "batch_id_here"}'The response carries status, counts, total cost and savings, and once finished a results array keyed by your custom_id.
List models
Returns the routing aliases and every active model in your workspace, with its quality and prices per million tokens.
{ "object": "list", "data": [
{ "id": "auto", "object": "model", "owned_by": "linuxair" },
{ "id": "la/quality", "object": "model", "owned_by": "linuxair" },
{ "id": "gpt-4.1-mini", "object": "model", "owned_by": "workspace",
"quality": 0.88, "input_price_per_mtok": 0.4, "output_price_per_mtok": 1.6 }
] }Send feedback
| Field | Description |
|---|---|
request_id | The linuxair.request_id, or the completion id (the chatcmpl- prefix is accepted). |
score | "up" / "down", 1 / -1, or a number from 0 to 1. |
Feedback updates the chosen model's live error for the prompt's clusters. Re-sending the same prompt within the retry window (two minutes by default) is also treated as negative feedback automatically.
Errors
Errors use the OpenAI shape: {"error": {"message": "...", "type": "...", "code": "..."}}.
| Status | Code | Meaning |
|---|---|---|
| 400 | invalid_request_error | Malformed body, for example missing messages. |
| 400 | no_models | The workspace has no active models yet. |
| 400 | no_eligible_model | Constraints (context window, max_cost, min_quality, allow-list) or a missing capability — tools, JSON mode — excluded every model. |
| 401 | invalid_api_key | Missing, wrong or revoked key. |
| 402 | insufficient_credits | Top up your wallet to continue. |
| 402 | budget_exceeded | A daily or monthly spend cap was reached. Raise it or wait for the period to roll over. |
| 404 | not_found | Unknown request_id for feedback. |
| 429 | rate_limit_exceeded | The key's requests-per-minute limit was reached. |
| 502 | upstream_error | Every candidate model failed at the provider. |
| 503 | not_ready | The routing space hasn't been built yet (operator action). |