Connecting to the API
An endpoint in the OpenAI Chat Completions format, billed from a ruble balance. This page has everything you need to integrate: the URL, authentication, examples, streaming, errors and limitations.
Basics
| Base URL | https://llm.liho.dev/v1 |
|---|---|
| Authentication | Authorization: Bearer lh_… header, with a key from the dashboard |
| Format | JSON, OpenAI Chat Completions |
| Models | An ID from the catalog, e.g. gpt-6-sol. No developer prefix |
| Required fields | model, messages and max_tokens (or max_completion_tokens) |
| Timeout | A response can take up to 15 minutes, so set the client timeout to at least 900 seconds |
| Request ID | The X-Request-ID header matches the response id |
Request
A minimal request. With the OpenAI SDK, setting base_url and the key is enough.
curl https://llm.liho.dev/v1/chat/completions \
-H "Authorization: Bearer $LIHO_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "gpt-6-sol",
"max_tokens": 512,
"messages": [
{"role": "user", "content": "Explain what an API gateway is in two sentences."}
]
}'import os
from openai import OpenAI
client = OpenAI(
base_url="https://llm.liho.dev/v1",
api_key=os.environ["LIHO_API_KEY"],
timeout=900,
)
response = client.chat.completions.create(
model="gpt-6-sol",
max_tokens=512,
messages=[{"role": "user", "content": "Explain what an API gateway is in two sentences."}],
)
print(response.choices[0].message.content)import OpenAI from "openai";
const client = new OpenAI({
baseURL: "https://llm.liho.dev/v1",
apiKey: process.env.LIHO_API_KEY,
timeout: 900_000,
});
const response = await client.chat.completions.create({
model: "gpt-6-sol",
max_tokens: 512,
messages: [{ role: "user", content: "Explain what an API gateway is in two sentences." }],
});
console.log(response.choices[0].message.content);Streaming
With "stream": true, the response arrives as text/event-stream: data: events with chunks and a final data: [DONE]. The last chunk before [DONE] contains usage: tokens and the cost in rubles. If there is no data for 15 seconds, the server sends a : keep-alive comment.
curl -N https://llm.liho.dev/v1/chat/completions \
-H "Authorization: Bearer $LIHO_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "gemini-3.8-flash",
"max_tokens": 512,
"stream": true,
"messages": [
{"role": "user", "content": "Explain what an API gateway is in two sentences."}
]
}'stream = client.chat.completions.create(
model="gemini-3.8-flash",
max_tokens=512,
stream=True,
messages=[{"role": "user", "content": "Explain what an API gateway is in two sentences."}],
)
for chunk in stream:
if chunk.choices and chunk.choices[0].delta.content:
print(chunk.choices[0].delta.content, end="", flush=True)
if chunk.usage:
print("\n", chunk.usage) # the last chunk carries tokens and cost in rublesdata: {"id":"…","object":"chat.completion.chunk","choices":[{"index":0,"delta":{"content":"…"}}]}
: keep-alive
data: {"id":"…","choices":[{"index":0,"delta":{},"finish_reason":"stop"}],"usage":{"prompt_tokens":…,"completion_tokens":…,"cost":…}}
data: [DONE]If the charge is not final yet, the last chunk arrives without the cost field; the final cost will appear in the history and in /v1/generation.
Parameters
The set of parameters depends on the model; the supported_parameters list is on each model’s card in the catalog. Model catalog.
| Parameter | Description |
|---|---|
max_tokens | Required. Caps the response and sets the cost reserve. For reasoning models, leave headroom: reasoning tokens count toward this limit. |
messages | 1 to 2048 messages, up to 256 parts per message. Roles: system, user, assistant, tool. |
tools, tool_choice, parallel_tool_calls | Tool calling: up to 128 tools. When streaming, calls arrive in delta.tool_calls. |
reasoning_effort | Reasoning level for models that support it. reasoning: {effort} is also accepted. |
temperature, top_p, presence_penalty, frequency_penalty, seed, user | Standard sampling parameters. |
stream | Streaming response (SSE). |
HTTP-Referer, X-Title | Optional headers: the app name is shown in the request history. |
Idempotency-Key | Optional header, up to 100 bytes. A repeat with the same key returns 409 and does not start generation again. |
Unknown fields do not cause an error: they are dropped and listed in the X-Liho-Ignored-Fields response header.
Errors and limits
Errors come in a single format that the OpenAI SDK can parse.
{
"error": {
"code": 402,
"message": "…",
"type": "liho_error",
"metadata": { "request_id": "…" }
}
}| Code | Cause |
|---|---|
400 | Invalid request, or a parameter the model does not support |
401 | Key missing, invalid, revoked or expired |
402 | Insufficient funds or the key’s limit is exhausted |
403 | A management key cannot be used for model requests |
404 | Unknown model |
409 | Repeated request with the same Idempotency-Key |
413 | Request body larger than 32 MiB |
429 | Key’s requests-per-minute limit exceeded, see Retry-After |
502 | Error on the model provider’s side |
503 | Temporary capacity shortage, see Retry-After |
- The requests-per-minute limit is set per key: from 1 to 1000, 300 by default.
- Rate-limited responses include the X-RateLimit-Limit, X-RateLimit-Remaining and X-RateLimit-Reset headers.
- Up to 100 active keys per account.
Usage and keys via the API
For agents and tools that need to know the remaining balance or the cost of a specific request.
| Method | Returns |
|---|---|
GET /v1/models | Published models with prices and parameters. Requires a key |
GET /v1/key | Details of the current key: limit and usage |
GET /v1/credits | Account balance |
GET /v1/generation?id=… | Tokens, cost and execution time of a single request |
/v1/keys | Create, update and revoke keys with a management key |
Not supported
- Responses API (/v1/responses), embeddings, legacy completions, image generation, audio, moderation.
- The Anthropic Messages protocol (/v1/messages). Claude Code can connect only through a third-party adapter; see the documentation in the dashboard.
- Message parts with audio and files; the parameters n > 1, logprobs, logit_bias.
- The auto model: for now the model is specified explicitly.
- Structured output (response_format) and stop sequences are currently not enabled for any catalog model.
Coming in the next release: Auto mode that picks the model for the task in 10 ms, the Responses API, embeddings, image and audio generation.
Documentation
Developer portal
Articles on connecting, parameters, streaming, errors and tool setup. Available after you sign in to the dashboard.
Open the portalOpenAPI
Endpoint specification in OpenAPI 3 format.
openapi.yamlllms.txt
The documentation as a single text file, handy to pass to an agent or model.
llms.txt