Getting started
Authentication
Every request is authenticated with an API key sent as a Bearer token. Keys are secrets: keep them on the server, scope them narrowly and rotate them.
Send your key in the Authorization header of every request. The OpenAI SDKs do this for you when you pass api_key / apiKey.
POST /v1/chat/completions HTTP/1.1
Host: api.lirux.ai
Authorization: Bearer sk-...
Content-Type: application/jsoncurl https://api.lirux.ai/v1/models \
-H "Authorization: Bearer $LIRUX_API_KEY"A missing, malformed or revoked key returns 401:
{
"error": {
"message": "Invalid API key provided.",
"type": "authentication_error",
"code": "invalid_api_key",
"param": null
}
}Keys are created, rotated and revoked in the console. During the pilot phase, while the console is rolling out, the same operations are handled by our support team — write to [email protected] from an address registered on your account.
| Operation | What happens |
|---|---|
| Create | A new key is generated and shown once. Store it in your secret manager immediately; it cannot be displayed again. |
| Rotate | Create a second key, deploy it, confirm traffic has moved, then revoke the old key. Both keys work in the meantime, so rotation needs no downtime. |
| Revoke | The key stops working for new requests. Revocation is permanent; create a new key if you need access again. |
If a key is exposed
Use one key per application and environment, and give each key only what it needs:
- Per environment — separate keys for development, staging and production, so a leaked development key never reaches production data.
- Per model or endpoint — a key can be restricted to specific models or endpoints, for example an indexing job that may only call
/v1/embeddings. Requests outside the scope return403 permission_error. - Per deployment — keys for a dedicated node are valid only for that node's endpoint.
Anything shipped to a browser, mobile app or desktop client can be extracted. Do not put API keys in frontend code, public environment variables (such as NEXT_PUBLIC_* or VITE_*) or app bundles. Instead, call the API from your backend and expose a narrow endpoint of your own that authenticates your users, validates input and applies your own limits.
// app/api/assistant/route.ts — runs on your server, never in the browser
import OpenAI from "openai";
const client = new OpenAI({
baseURL: process.env.LIRUX_BASE_URL,
apiKey: process.env.LIRUX_API_KEY, // server-side secret
});
export async function POST(request: Request) {
await requireUser(request); // your own authentication
const { question } = await request.json();
const completion = await client.chat.completions.create({
model: "qwen3-30b-a3b",
messages: [{ role: "user", content: String(question).slice(0, 4000) }],
});
return Response.json({ answer: completion.choices[0].message.content });
}- TLS only. The API is served exclusively over HTTPS. Plain HTTP is not accepted.
- IP allowlisting is available on dedicated plans. Requests from addresses outside your allowlist are rejected with
403 ip_not_allowed, even with a valid key. - VPN connectivity to dedicated endpoints is available on eligible plans, so traffic does not traverse the public internet between your network and the endpoint.
Network options are set up during onboarding. For details on data handling, see Data processing and Security.