Chat and streaming
POST /v1/chat/completions is the main endpoint. Request and response match OpenAI, so any compatible SDK works.
Parameters
Section titled “Parameters”| 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 |
Streaming
Section titled “Streaming”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)const stream = await 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 await (const chunk of stream) { process.stdout.write(chunk.choices[0]?.delta?.content ?? '')}curl -N https://api.mixen.ai/v1/chat/completions \ -H "Authorization: Bearer $MIXEN_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "gpt-5.6-luna", "messages": [{"role": "user", "content": "Write a haiku about deadlines"}], "stream": true, "stream_options": {"include_usage": 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.
Image input
Section titled “Image input”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.
File input
Section titled “File input”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.
Reasoning effort
Section titled “Reasoning effort”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_tokensbudget. 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 readsfalse, the model always reasons, and the price reflects that.
Web search
Section titled “Web search”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.