Documentation

Chat completions

The main endpoint, field by field.

Endpoint

HTTP
1POST https://api.sothe.net/v1/chat/completions

The request and response follow OpenAI's Chat Completions schema, so an OpenAI SDK works unchanged.

Request fields

FieldNotes
modelRequired. An id from the model list, or @preset/<slug>.
messagesRequired, non-empty. See below.
streamtrue switches to server-sent events. See Streaming.
stream_options{ include_usage: true } appends a final chunk carrying token counts and cost.
max_tokens1–1,000,000. max_completion_tokens is accepted as an alias. Defaults to 8,192, and is lowered automatically when your remaining balance cannot cover that many output tokens.
temperature0–2.
top_p0–1.
stopA string, or an array of up to four.
tools, tool_choiceSee Tool calling.
nOnly 1. Any other value is rejected rather than quietly ignored.

Messages

RoleNotes
system, developerInstructions. Both are treated the same and lifted out of the conversation.
userA string, or an array of parts for media.
assistantPrevious replies, including any tool_calls they made.
toolThe result of a call. Must carry the tool_call_id it answers.

Consecutive messages with the same role are merged, because some providers require strictly alternating turns. That is invisible to you, but it means two adjacent user messages arrive at the model as one.

Fields we ignore

These are accepted without error and change nothing. They are listed here so you do not discover it by debugging:

response_format, seed, frequency_penalty, presence_penalty, logprobs, logit_bias, user.

Structured outputs are not enforced yet

Passing response_format does not make the model return JSON. Until it is implemented, ask for JSON in the prompt and validate what comes back, or use a tool call — a forced function gives you a schema the model must fill in.

Response

JSON
1{2  "id": "gen-...",3  "object": "chat.completion",4  "created": 1789862588,5  "model": "anthropic/claude-haiku-4-5-20251001-v1:0",6  "choices": [{7    "index": 0,8    "message": { "role": "assistant", "content": "Hello!" },9    "finish_reason": "stop"10  }],11  "usage": { "prompt_tokens": 9, "completion_tokens": 3, "total_tokens": 12, "cost": 0.000041 }12}

Two additions to the OpenAI shape: usage.cost is the price of the request in USD, and a message carries reasoning when the model produced any. finish_reason is one of stop, length, tool_calls or content_filter.

Whitespace before a slow reply

A non-streaming request that takes a long time receives spaces before its JSON body, to stop proxies closing an idle connection. Every JSON parser ignores them.