Reference

The whole API is four endpoints.

Base URL https://lazarus-th.duckdns.org/v1. Authenticate with Authorization: Bearer sk-.... Anything that speaks OpenAI speaks this.

MethodPathReturns
POST/v1/chat/completionsCompletion, or an SSE stream when stream:true
GET/v1/modelsEvery model the key can reach
GET/api/statusPublic instance status, no auth
GET/api/user/selfBalance and quota for the calling key

Chat completions

Request body is the OpenAI shape. model is the only field that selects a route.

curl https://lazarus-th.duckdns.org/v1/chat/completions \
  -H "Authorization: Bearer sk-..." \
  -H "Content-Type: application/json" \
  -d '{
    "model": "deepseek-ai/DeepSeek-V4-Flash-0731",
    "messages": [{"role": "user", "content": "hello"}],
    "max_tokens": 256,
    "stream": false
  }'

Response carries a usage block on every call: prompt_tokens, completion_tokens, total_tokens, and reasoning_tokens where the model reports it.

Streaming

Set stream:true and the response becomes text/event-stream. Each frame is a data: line holding a delta; the last one is data: [DONE].

Errors

Errors are JSON with a stable shape, so a client can branch on message without parsing prose.

{"error": {"message": "Invalid token", "type": "new_api_error"}}

Python

from openai import OpenAI

client = OpenAI(
    base_url="https://lazarus-th.duckdns.org/v1",
    api_key="sk-...",
)

r = client.chat.completions.create(
    model="zai-org/GLM-5.3-Flash",
    messages=[{"role": "user", "content": "hello"}],
)
print(r.choices[0].message.content)

Node

import OpenAI from "openai";

const client = new OpenAI({
  baseURL: "https://lazarus-th.duckdns.org/v1",
  apiKey: "sk-...",
});

const r = await client.chat.completions.create({
  model: "MiniMaxAI/MiniMax-M2.7",
  messages: [{ role: "user", content: "hello" }],
});

Keys

Keys are created in the console under Tokens. A key carries a quota, an optional model allow-list, and an optional IP allow-list. Revoking a key takes effect on the next request, no cache to wait out.