API documentation
Using an AI assistant? Give it /llms.txt. It covers sign-up, adding credit and calling the API end to end.
The Lacia API is compatible with the OpenAI Chat Completions API. Existing OpenAI SDK code only needs a new base_url and api_key.
Quickstart
- Create an account and add credit in the dashboard.
- Create a key under Dashboard → API Keys. It is shown only once, so save it.
- Set the
LACIA_API_KEYenvironment variable and run any example below.
Authentication
Every /v1 endpoint requires your API key in the request header:
Authorization: Bearer sk-lacia-xxxxxxxxxxxxxxxx
Never expose your key in front-end code, public repositories or client apps. If it leaks, delete it in the dashboard right away and create a new one.
Base URL & models
https://lacia.app/v1Chat Completions
POST/v1/chat/completions
Request parameters
| Parameter | Type | Description |
|---|---|---|
model | string, required | lacia-creator or lacia-researcher |
messages | array, required | Conversation messages; each has a role (system / user / assistant) and content |
stream | boolean | Stream the response over SSE. Default: false |
max_tokens | integer | Max output tokens. Defaults to 32K; values above the model limit (384K) are capped at the limit |
temperature | number | 0–2; higher is more varied |
top_p | number | Nucleus sampling, 0–1 |
stop | string | array | Stop sequences |
presence_penalty / frequency_penalty | number | -2–2; reduces repetition |
Example request
{
"model": "lacia-creator",
"messages": [
{"role": "system", "content": "You are a narrator with a pitch-black sense of humor."},
{"role": "user", "content": "An opening paragraph, under 200 words."}
],
"temperature": 0.9,
"max_tokens": 800
}
Example response
{
"id": "chatcmpl-...",
"object": "chat.completion",
"created": 1767225600,
"model": "lacia-creator",
"choices": [{
"index": 0,
"message": {"role": "assistant", "content": "..."},
"finish_reason": "stop"
}],
"usage": {"prompt_tokens": 42, "completion_tokens": 186, "total_tokens": 228}
}
Streaming
Set "stream": true and the response is text/event-stream. Each event looks like data: {...}, incremental text is in choices[0].delta.content, and the stream ends with data: [DONE]. The last data event has an empty choices array and carries usage.
Thinking mode
Each mode's thinking behavior is fixed. Fields such as thinking, reasoning_effort and chat_template_kwargs in the request are ignored.
| Model | Thinking | Description |
|---|---|---|
lacia-creator | Off | Answers directly with a faster first token; for writing and conversation |
lacia-researcher | On | Reasons before answering; for complex analysis and coding |
Researcher returns its reasoning in message.reasoning_content (delta.reasoning_content when streaming); the final answer is still in content. Reasoning counts toward completion_tokens, is billed at the output price and uses part of the max_tokens budget. In multi-turn chats, putting content back into messages is enough; if the request includes tools, send each returned reasoning_content back unchanged on its assistant message, or the API returns 400.
Usage
Every successful response includes a usage field:
In the dashboard, Usage aggregates by day and model, and Request logs shows tokens, cost, latency and status for every request. In rare cases the model service returns no usage; we then estimate from character counts and mark the log entry “estimated”.
List models
GET/v1/models
curl https://lacia.app/v1/models -H "Authorization: Bearer $LACIA_API_KEY"
Error codes
Error responses follow the OpenAI format:
{"error": {"message": "Insufficient balance. Please top up in the dashboard.", "type": "insufficient_quota", "code": "insufficient_balance"}}
| HTTP | code | Cause & fix |
|---|---|---|
| 400 | invalid_json / invalid_messages | Malformed request body; check the JSON and messages |
| 400 | context_length_exceeded | Input too long; shorten the context |
| 401 | missing_api_key / invalid_api_key | Missing or invalid API key |
| 402 | insufficient_balance | Insufficient balance; top up and retry |
| 403 | spend_limit_exceeded | You reached your monthly spend cap |
| 404 | model_not_found | Invalid model parameter |
| 429 | rate_limit_exceeded | Too many requests per minute; retry with exponential backoff |
| 502 | upstream_error | Model service error; safe to retry, not billed |
| 503 | upstream_overloaded | Model service busy; retry shortly, not billed |
Rate limits & quotas
- Rate limits apply per API key and per mode, as listed below. Contact us if you need more.
- Set a monthly spend cap in the dashboard. Once reached, requests return 403 until next month.
- Set a low-balance alert and the dashboard will warn you when your balance drops below it.