Format
Standard server-sent events — the same chunked data: format and termination OpenAI's streaming responses use. The model field in each chunk shows the model name you requested.
Docs
If your code already speaks to an OpenAI-compatible API, this is a two-line change: the base URL and the key.
Quick start
Start right away — no system migration. Change just a few lines.
In the member portal, under API keys. The key is shown once — we store only a hash of it, so we cannot show it to you again or recover it for you.
Set the base URL to our endpoint and use your key as the API key. Model names come from GET /v1/models.
Server-sent events work exactly as you expect — tokens arrive as they are produced, not batched at the end.
Example
Same shape as the OpenAI Chat Completions API — model, messages, and the usual sampling parameters, though some models ignore some of them. stream: true switches the response to server-sent events on the same endpoint.
# pip install openai
import os
from openai import OpenAI
client = OpenAI(
base_url="https://api.ic-lueur.ai/v1",
api_key=os.environ["LLMR_API_KEY"],
)
resp = client.chat.completions.create(
model="gpt-5-mini",
messages=[{"role": "user", "content": "Sawasdee!"}],
) Connect your tools
Use a Base URL and API key to connect any tool that supports the OpenAI API — set up in just a few steps and start right away.
https://api.ic-lueur.ai/v1 Create or manage API keys in Member Portal → API Keys
Connect your AI coding tools with one Base URL and API Key
Roo Code sidebar showing the API Provider dropdown set to OpenAI Compatible
Cline extension sidebar showing the API Provider dropdown set to OpenAI Compatible
// ~/.continue/config.json (add inside "models": [...])
{
"title": "IC Lueur Ai",
"provider": "openai",
"model": "claude-sonnet-4-6",
"apiBase": "https://api.ic-lueur.ai/v1",
"apiKey": "YOUR_API_KEY"
} // settings.json
{
"github.copilot.advanced": {},
"languageModels": {
"openAI": {
"baseURL": "https://api.ic-lueur.ai/v1",
"apiKey": "YOUR_API_KEY"
}
}
} Connect AI chat clients that support the OpenAI API
Cherry Studio Settings showing the Add Provider form with API URL and Key fields
NextChat Settings panel showing the Custom Endpoint URL and API Key fields
# .env
OPENAI_REVERSE_PROXY=https://api.ic-lueur.ai/v1
OPENAI_API_KEY=YOUR_API_KEY LobeChat Language Model settings showing the OpenAI Compatible custom endpoint fields
Configure CLI tools and SDKs to use models through IC Lueur Ai
export ANTHROPIC_BASE_URL="https://api.ic-lueur.ai/v1"
export ANTHROPIC_API_KEY="YOUR_API_KEY"
claude curl https://api.ic-lueur.ai/v1/chat/completions \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "claude-sonnet-4-6",
"messages": [{"role": "user", "content": "Hello"}]
}' from openai import OpenAI
client = OpenAI(
base_url="https://api.ic-lueur.ai/v1", # ← change this
api_key="YOUR_API_KEY", # ← and this
)
response = client.chat.completions.create(
model="claude-sonnet-4-6",
messages=[{"role": "user", "content": "Hello"}],
)
print(response.choices[0].message.content) import OpenAI from "openai";
const client = new OpenAI({
baseURL: "https://api.ic-lueur.ai/v1", // ← change this
apiKey: "YOUR_API_KEY", // ← and this
});
const res = await client.chat.completions.create({
model: "claude-sonnet-4-6",
messages: [{ role: "user", content: "Hello" }],
});
console.log(res.choices[0].message.content); Connect IC Lueur Ai to your workflows and no-code tools
{
"model": "app/your-assistant-name",
"messages": [{ "role": "user", "content": "{{escapeJSON(1.text)}}" }]
} {
"model": "app/your-assistant-name",
"messages": [{ "role": "user", "content": {{ JSON.stringify($json.text) }} }]
} Base URL: https://api.ic-lueur.ai/v1
Assistant: app/your-assistant-name
API key: YOUR_API_KEY (a key made just for this sheet) Set stream: true and read the response as server-sent events, same shape as OpenAI's Chat Completions streaming.
stream: true [DONE] Standard server-sent events — the same chunked data: format and termination OpenAI's streaming responses use. The model field in each chunk shows the model name you requested.
Tokens already generated before you close the connection are still billed. An interrupted request is metered the same as a completed one.
Errors use the same shape as OpenAI's, {"error": {"message": "<message>"}}, with the HTTP status. The type and code values do not always match OpenAI's, so branch on the HTTP status and the message text instead.
The requested model has no configured deployment (check the model name against GET /v1/models), or the request sets a field this gateway does not accept: extra_body, kwargs, litellm_params or custom_llm_provider. Send model options as top-level fields — the OpenAI SDKs already do this with their own extra_body.
The key is missing, unknown, or has been revoked.
Your account balance is too low to cover this request. The message states the balance in THB.
The organization has been suspended, the key is an operator/master key (which cannot be billed for inference), or the key’s creator has reached a daily or monthly spend limit set by the organization’s owner or admin.
The prompt is too large to qualify for a free-model promotion window (see Free-model promotions below).
This key has exceeded its requests-per-minute limit. Wait for the Retry-After header, when present, and read the message before retrying.
429 covers several conditions. If your retry logic needs to tell them apart, match on how the message starts, not on the status code alone, and match case-sensitively: the key's own rate limit starts with rate limit exceeded: in lower case; a region that is temporarily unavailable starts with no region available; the three free-model-promotion limits below start with QUOTA_EXCEEDED, REQUEST_LIMIT_EXCEEDED or RATE_LIMIT_EXCEEDED in capitals.
Our internal key store is unreachable, or the model has no price configured yet. We fail closed rather than let an unverifiable key or an unpriced request through.
Any model can carry a temporary free window — same request, no charge, while it lasts.
15 requests / min per key
Separate from your key's own rate limit, and usually tighter
1,000,000 tokens or 1,000 requests
Per organisation, whichever is hit first
Every Monday
00:00, Asia/Bangkok time
32,000 tokens
Over this, the request is refused outright — never billed instead
16,000 tokens
Capped automatically; a smaller max_tokens you set is still honoured
Blocked until Monday
Unless you turn on auto-fallback in the member portal (Top-up settings)
See what's free right now in the pricing catalogue — filter by "Free" there.
Your organisation has one routing policy, which our team sets for you on request. A new key takes it when it is created and it is enforced on every call; changing the policy later does not change keys created before. Read the note below first — it says where requests are actually served from today.
Most requests are served from Singapore (ap-southeast-1) and Tokyo (ap-northeast-1). Some models are only offered in a provider’s global region, which can be outside Asia, for example the United States, and organisations on the available policy can also reach providers in mainland China. Your account data, balance, billing ledger and tax invoices are stored on AWS in Thailand regardless of which region served the request.
Every request is paid from your organisation’s prepaid THB credit. Top up in the member portal under Credit Wallet; the credit is added once the payment is confirmed.
00000 for head office, otherwise the branch name as well.An assistant is a task you set up once — categorize an expense, summarize an email, sort a review, pull fields out of a message. You pick the task, a name and a model, and we keep the instructions. Your system then calls it by name, app/your-name, in any program that takes an OpenAI-style model field.
a–z, 0–9 and -, 3–40 characters. The call name becomes app/<name> and cannot be changed later, because your systems refer to it. Use the same base URL and API key as any other request, and put the assistant’s name where the model goes. Send only the text for it to work on — the stored instructions are added in front for you.
resp = client.chat.completions.create(
model="app/accounting-helper",
messages=[{"role": "user", "content": "Taxi to see a client, 250 baht"}],
)
print(resp.choices[0].message.content) max_tokens you send. When the assistant sets a temperature or an output format, the assistant wins, not the request.GET /v1/models includes your organization’s assistants, as app/<name>, next to the models. Fetching a single one with GET /v1/models/app/<name> is not supported. The portal’s Usage page shows which assistant each request went through.The name is wrong, the assistant is switched off or deleted, or it belongs to another organization. The answer is the same for all of these on purpose. After you create or switch one on, allow up to about 30 seconds. Nothing is charged.
An assistant only works with chat completions: the request must carry a messages list. Nothing is charged.
The assistant exists but its stored definition could not be applied. We never run the request without its instructions, so nothing is charged; try again shortly.
Errors come back as {"error": {"message": …}} with the HTTP status. Balance (402) and rate-limit (429) errors are exactly as above.
Latest updates
Create a key, then check per-model rates before you commit spend.