Setup guide
The API speaks OpenAI's protocol. Use the official OpenAI SDKs; only the base URL and the sign-in change.
1. Your settings
Put these into your project's .env (never into git). The secret comes from
your project page — it is shown once when you create it.
LLM_BASE_URL=https://llm.andreaskra.com/v1
LLM_TOKEN_URL=https://llm.andreaskra.com/oauth/token
LLM_CLIENT_ID=cl_…
LLM_CLIENT_SECRET=cs_…
Ask for models by their alias — usually default, fast and embed. GET /v1/models lists what you can use.
2. How sign-in works
Your client id and secret are exchanged for a short-lived access token (OAuth 2.1 client_credentials,
valid 15 minutes), which goes in the Authorization: Bearer header. The snippets below do this for you and
renew the token automatically.
3. Python
Install the OpenAI SDK and our small sign-in helper (its only dependencies are httpx and pyjwt):
pip install openai httpx "pyjwt[crypto]"
Download llm_client.zip, unzip the llm_client folder into your project, then:
import os
from openai import OpenAI
from llm_client import oauth_http_client
llm = OpenAI(
base_url=os.environ["LLM_BASE_URL"],
api_key="unused", # the helper sets the real Authorization header
http_client=oauth_http_client(
os.environ["LLM_TOKEN_URL"], os.environ["LLM_CLIENT_ID"], os.environ["LLM_CLIENT_SECRET"]
),
)
for chunk in llm.chat.completions.create(
model="default", stream=True,
messages=[{"role": "user", "content": "Hello!"}],
):
if chunk.choices and chunk.choices[0].delta.content:
print(chunk.choices[0].delta.content, end="", flush=True)
4. TypeScript / Node
Download llm-client.ts (one file, no dependencies) into your project, then:
import OpenAI from "openai";
import { oauthFetch } from "./llm-client";
const llm = new OpenAI({
baseURL: process.env.LLM_BASE_URL,
apiKey: "unused",
fetch: oauthFetch({
tokenUrl: process.env.LLM_TOKEN_URL!,
clientId: process.env.LLM_CLIENT_ID!,
clientSecret: process.env.LLM_CLIENT_SECRET!,
}),
});
const answer = await llm.chat.completions.create({
model: "default",
messages: [{ role: "user", content: "Hello!" }],
});
5. curl
TOKEN=$(curl -s -u "$LLM_CLIENT_ID:$LLM_CLIENT_SECRET" -d grant_type=client_credentials \
https://llm.andreaskra.com/oauth/token | python3 -c 'import json,sys; print(json.load(sys.stdin)["access_token"])')
curl -s https://llm.andreaskra.com/v1/chat/completions -H "Authorization: Bearer $TOKEN" \
-H 'Content-Type: application/json' \
-d '{"model": "default", "messages": [{"role": "user", "content": "Hello!"}]}'
6. Things to know
| Situation | What happens |
|---|---|
| The GPU server is offline | A request waits up to 30 s (header X-Queue-Timeout, max 120), then 503 worker_unavailable with Retry-After. The OpenAI SDKs retry this twice by themselves. |
| Token limit reached | 429 token_limit_exceeded; Retry-After says when capacity frees up. Limits are rolling: the last 5 hours and the last 7 days, prompt + completion tokens. |
| Long answers | Set max_tokens to bound an answer. Generation stops after X-Request-Timeout (default 600 s). |
| Work that can wait | POST /v1/jobs with {"endpoint": "/v1/chat/completions", "body": {…}} queues the request even while the GPU is off; poll GET /v1/jobs/{id}. |
| A leaked secret | Generate a new one on your project page — the old one stops working immediately. |