Documentation

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

  1. Create an account and add credit in the dashboard.
  2. Create a key under Dashboard → API Keys. It is shown only once, so save it.
  3. Set the LACIA_API_KEY environment 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

Base URL
https://lacia.app/v1
Protocol
HTTPS, JSON, UTF-8
Compatibility
OpenAI Chat Completions (including streaming)

Chat Completions

POST/v1/chat/completions

Request parameters

ParameterTypeDescription
modelstring, requiredlacia-creator or lacia-researcher
messagesarray, requiredConversation messages; each has a role (system / user / assistant) and content
streambooleanStream the response over SSE. Default: false
max_tokensintegerMax output tokens. Defaults to 32K; values above the model limit (384K) are capped at the limit
temperaturenumber0–2; higher is more varied
top_pnumberNucleus sampling, 0–1
stopstring | arrayStop sequences
presence_penalty / frequency_penaltynumber-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.

ModelThinkingDescription
lacia-creatorOffAnswers directly with a faster first token; for writing and conversation
lacia-researcherOnReasons 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:

prompt_tokens
Input tokens, billed at the input price
completion_tokens
Output tokens, billed at the output price
total_tokens
Sum of both

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"}}
HTTPcodeCause & fix
400invalid_json / invalid_messagesMalformed request body; check the JSON and messages
400context_length_exceededInput too long; shorten the context
401missing_api_key / invalid_api_keyMissing or invalid API key
402insufficient_balanceInsufficient balance; top up and retry
403spend_limit_exceededYou reached your monthly spend cap
404model_not_foundInvalid model parameter
429rate_limit_exceededToo many requests per minute; retry with exponential backoff
502upstream_errorModel service error; safe to retry, not billed
503upstream_overloadedModel service busy; retry shortly, not billed

Rate limits & quotas