Use Lumi from any app
Lumi speaks the OpenAI chat-completions protocol. Point Cursor, Raycast, Chatbox, Open WebUI or the official OpenAI SDK at the base URL below, paste a key, and you get Lumi — same persona, same tools, same voice as the app.
1. Base URL
Paste this into the field your client calls Base URL, API Host or Override OpenAI Base URL.
https://api-lumi.kynguyen.cc/v1Four ways to get this wrong
All four return 404 Not Found, which reads like the service is down when it isn't. If you see a 404, check this list first.
https://api-lumi.kynguyen.cc/v1/v1/modelsbase URL already ends in /v1 and the client added anotherhttps://lumi.kynguyen.cc/v1/modelsthat is the web app — the API lives on api-lumihttps://api-lumi.kynguyen.cc/api/v1/models/api/v1 is the app's own API, not this onehttps://api-lumi.kynguyen.cc/modelsthe /v1 prefix is missing
A correct URL with a bad key answers 401, not 404 — so a 401 actually means your base URL is right.
2. Get an API key
Keys are issued by the admin, not self-service — every request spends the same shared model budget, so access is granted per person. Contact the admin to request one.
Once it has been issued, your key is always readable in the app: open Lumi → Settings → API key → Show. You don't need to save it anywhere else, and losing it costs nothing.
It looks like sk-lumi-… and goes in the field labelled API Key or OpenAI API Key. Treat it like a password: anyone holding it can spend your quota. Ask the admin to delete it if it leaks.
3. First request
The fastest check that everything is wired up — it needs no model call.
curl https://api-lumi.kynguyen.cc/v1/models \
-H "Authorization: Bearer $LUMI_API_KEY"Then an actual reply:
curl -X POST https://api-lumi.kynguyen.cc/v1/chat/completions \
-H "Authorization: Bearer $LUMI_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"messages": [{"role": "user", "content": "Xin chào Lumi"}]
}' Streaming — -N matters, without it curl buffers and everything appears at once:
curl -N -X POST https://api-lumi.kynguyen.cc/v1/chat/completions \
-H "Authorization: Bearer $LUMI_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"stream": true,
"messages": [{"role": "user", "content": "Explain SSE in five sentences."}]
}'Or with the official Python SDK:
from openai import OpenAI
client = OpenAI(api_key="sk-lumi-…", base_url="https://api-lumi.kynguyen.cc/v1")
stream = client.chat.completions.create(
model="gemini-3.7-flash",
messages=[{"role": "user", "content": "Xin chào Lumi"}],
stream=True,
)
for chunk in stream:
print(chunk.choices[0].delta.content or "", end="")4. Models
Put one of these slugs in the model field. A name we don't recognise — gpt-4o, or a typo — is not an error: it quietly falls back to gemini-3.7-flash. So if a reply feels like the wrong model, check the model field of the response, which always reports what actually answered.
| Slug | Model | Maker | Notes |
|---|---|---|---|
gemini-3.7-flash | Gemini 3.7 Flash | default · newest; picks its own thinking depth | |
gemini-3.1-pro-low | Gemini 3.1 Pro (Low) | ||
gemini-3.1-pro-high | Gemini 3.1 Pro (High) | ||
claude-sonnet-4.6-thinking | Claude Sonnet 4.6 (Thinking) | Anthropic | thinks before answering |
claude-opus-4.6-thinking | Claude Opus 4.6 (Thinking) | Anthropic | thinks before answering |
gpt-oss-120b-medium | GPT-OSS 120B (Medium) | OpenAI |
5. What works, what doesn't
Supported
- Streaming and non-streaming completions
- Multi-turn conversations of any length
- Your own
systemmessage - Images, as
data:base64 URLs - Web search, memory and Lumi's other tools — run server-side
Not supported
- Function calling. A
toolsarray is accepted and ignored — Lumi's toolset is server-owned. Anything that needs the model to call your tools (agent modes that edit files or run commands) will not work. /v1/embeddings— no such endpoint- Remote image URLs (only
data:is read) temperatureand friends are accepted, then ignored
Prefer stream: true. A non-streamed request sends no bytes until the whole reply is finished, and our edge gives up on a silent connection at around 100 seconds — so long answers have a 90-second ceiling without streaming, and none with it.
6. When something goes wrong
| 401 | Missing, mistyped or deleted key. The base URL is fine — a wrong URL gives 404. |
| 404 | Wrong base URL. See the list in step 1. |
| 429 | Hourly reply limit reached. Wait, or ask the admin to raise your quota. |
| 502 | Every model attempt failed. Usually momentary — retry. |
| 504 | A non-streamed reply ran past the deadline. Retry with "stream": true. |