Chat completions (OpenAI)
POST /v1/chat/completions — drop-in OpenAI-compatible endpoint, used by opencode and any OpenAI SDK.
The Chat Completions endpoint speaks the OpenAI Chat Completions wire format. Any client that targets https://api.openai.com/v1/chat/completions can be redirected to Cocobox by changing the base URL and key.
https://api.cocobox.io/v1/chat/completions Authenticated with Authorization: Bearer sk-coco-… Request
| Field | Type | Description |
|---|---|---|
model required | string | Model alias or full id. See Models. |
messages required | Message[] | Conversation history. Roles: system, user, assistant, tool. |
stream optional | boolean | If true, stream Server-Sent Events. Default: false |
temperature optional | number | Sampling temperature, 0–2. Default: 1 |
top_p optional | number | Nucleus sampling. Default: 1 |
max_tokens optional | integer | Maximum output tokens. Capped per model. |
stop optional | string | string[] | Up to 4 stop sequences. |
tools optional | Tool[] | OpenAI-format tool definitions. Passthrough: Cocobox does not auto-execute tools on this surface — the client orchestrates the loop. |
tool_choice optional | string | object | "auto", "none", or { "type": "function", "function": { "name": "..." } }. |
response_format optional | object | { "type": "json_object" } for JSON mode. |
user optional | string | Opaque end-user identifier you log in your own systems. Forwarded to the provider for abuse monitoring. |
Response (non-streaming)
{
"id": "chatcmpl-01HF2X7Y9KQR…",
"object": "chat.completion",
"created": 1735689600,
"model": "sonnet",
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": "SELECT id, total FROM orders ORDER BY created_at DESC LIMIT 10;"
},
"finish_reason": "stop"
}
],
"usage": {
"prompt_tokens": 24,
"completion_tokens": 18,
"total_tokens": 42
}
}
Streaming
Set "stream": true. The server returns Content-Type: text/event-stream with chunks of the form:
data: {"id":"chatcmpl-…","object":"chat.completion.chunk","choices":[{"delta":{"content":"SELECT"}}]}
data: {"id":"chatcmpl-…","object":"chat.completion.chunk","choices":[{"delta":{"content":" id"}}]}
…
data: [DONE]
The final event is the literal string [DONE]. After that, the connection closes.
Examples
curl https://api.cocobox.io/v1/chat/completions \
-H "Authorization: Bearer $COCOBOX_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "sonnet",
"messages": [
{ "role": "system", "content": "You are a senior SQL author for a Postgres warehouse." },
{ "role": "user", "content": "Write a query for monthly active users for the last 6 months." }
]
}' curl -N https://api.cocobox.io/v1/chat/completions \
-H "Authorization: Bearer $COCOBOX_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "haiku",
"stream": true,
"messages": [{"role":"user","content":"List 5 ways to optimize a slow JOIN."}]
}' import OpenAI from 'openai';
const client = new OpenAI({
apiKey: process.env.COCOBOX_API_KEY,
baseURL: 'https://api.cocobox.io/v1',
});
const completion = await client.chat.completions.create({
model: 'sonnet',
messages: [{ role: 'user', content: 'SELECT version();' }],
});
console.log(completion.choices[0].message.content); from openai import OpenAI
client = OpenAI(
api_key=os.environ["COCOBOX_API_KEY"],
base_url="https://api.cocobox.io/v1",
)
completion = client.chat.completions.create(
model="sonnet",
messages=[{"role": "user", "content": "Write a CTE that counts orders per user per month."}],
)
print(completion.choices[0].message.content) # opencode is OpenAI-compatible. Point it at Cocobox:
export OPENAI_BASE_URL=https://api.cocobox.io/v1
export OPENAI_API_KEY=sk-coco-…
opencode --model sonnet Tools (function calling)
Tools are accepted in OpenAI format. Cocobox does not execute tools server-side on this endpoint — the client receives tool_calls and must invoke them itself. To get auto-orchestrated tool execution against your databases, use the MCP endpoint (or any client that already speaks MCP, like opencode or Claude Code).
{
"model": "sonnet",
"messages": [{"role":"user","content":"How many users signed up yesterday?"}],
"tools": [
{
"type": "function",
"function": {
"name": "sql_run",
"description": "Run a read-only SQL query against the connected database.",
"parameters": {
"type": "object",
"properties": { "sql": { "type": "string" } },
"required": ["sql"]
}
}
}
],
"tool_choice": "auto"
}
When the model decides to call a tool, the response contains choices[0].message.tool_calls. Execute the tool, append a { "role": "tool", "tool_call_id": "…", "content": "<json result>" } message, and call /v1/chat/completions again.
Status codes
| Status | Meaning |
|---|---|
| 200 | Success (non-stream). |
| 200 | Success (stream); response is text/event-stream. |
| 400 | Malformed body or unknown field. |
| 401 | Missing / invalid key. |
| 402 | Out of credits. |
| 403 | Scope violation. |
| 404 | Unknown model. |
| 429 | Rate limited. |
| 500 | Provider failure. Retries are safe. |
See Errors for the full envelope.