Skip to content

Chat and streaming

POST /v1/chat/completions is the main endpoint. Request and response match OpenAI, so any compatible SDK works.

Field Type Description
model string, required Catalog identifier or alias (gpt-4o, claude-opus)
messages array, required Conversation so far; the last user message is the prompt
stream boolean true streams the answer over SSE
stream_options object {"include_usage": true} appends a final chunk with token usage
temperature number As in OpenAI
max_tokens integer Ceiling on answer length
max_completion_tokens integer Synonym for max_tokens, for newer SDKs
reasoning_effort string Reasoning depth on models that support it
stream = client.chat.completions.create(
model="gpt-5.6-luna",
messages=[{"role": "user", "content": "Write a haiku about deadlines"}],
stream=True,
stream_options={"include_usage": True},
)
for chunk in stream:
if chunk.choices and chunk.choices[0].delta.content:
print(chunk.choices[0].delta.content, end="", flush=True)

The stream is text/event-stream and ends with data: [DONE]. With include_usage, a chunk carrying usage arrives just before it — a convenient place to log spend.

Models with capabilities.vision: true accept an image inside a message:

resp = client.chat.completions.create(
model="gpt-5.6-terra",
messages=[{
"role": "user",
"content": [
{"type": "text", "text": "What's wrong with this chart?"},
{"type": "image_url", "image_url": {"url": "data:image/png;base64,iVBORw0KG..."}},
],
}],
)

Both data: URLs and ordinary HTTPS image links are accepted.

Models with capabilities.file: true read a whole PDF — scans and tables included, no external OCR:

{
"role": "user",
"content": [
{"type": "text", "text": "Summarise the Risks section"},
{"type": "file", "file": {"filename": "report.pdf", "file_data": "data:application/pdf;base64,JVBERi0..."}}
]
}

A model that cannot read files returns 400, so check the flag in the catalog first.

Some models let you dial reasoning depth. The accepted values arrive in capabilities.reasoning_efforts — usually low, medium, high, xhigh, max.

{"model": "claude-opus-4.8", "reasoning_effort": "high", "messages": [...]}

Two things to watch:

  • Reasoning consumes the max_tokens budget. If you expect long JSON from a model that reasons, set the ceiling generously or the answer gets cut mid-structure.
  • Reasoning cannot always be switched off — check capabilities.can_disable_reasoning. Where it reads false, the model always reasons, and the price reflects that.

Models with type: search (the Perplexity Sonar family) reach the internet themselves. There is no separate endpoint or tool — just name one:

curl https://api.mixen.ai/v1/chat/completions \
-H "Authorization: Bearer $MIXEN_API_KEY" \
-H "Content-Type: application/json" \
-d '{"model":"sonar-pro","messages":[{"role":"user","content":"What did Anthropic ship this week?"}]}'

On a scoped key these models need the search scope rather than chat.