Chat completions
POST /v1/chat/completions
Request body
| Field | Type | Required | Notes |
|---|---|---|---|
model | string | yes | Must be served locally or on the cloud allow-list. See Local vs. cloud routing |
messages | array | yes | { role, content }; content is a string or a ContentPart[] for multimodal input |
stream | boolean | no | Default false. See Streaming |
max_tokens | integer ≥ 1 | no | |
temperature | number, 0-2 | no | |
response_format | object | no | Passed through verbatim to the upstream, unvalidated here |
thread_id | uuid | no | Opt into server-side memory. See constraints below |
A ContentPart is { "type": "text" | "image_url", "text"?: string, "image_url"?: { "url": string, "detail"?: string } }.
curl https://ai.rcfi.co.ke/v1/chat/completions \
-H "Authorization: Bearer tak_your_key_here" \
-H "Content-Type: application/json" \
-d '{
"model": "ministral-3:3b",
"messages": [{ "role": "user", "content": "List three functions of the Controller of Budget." }],
"max_tokens": 300,
"temperature": 0.4
}'Response (non-streaming)
Returned verbatim from the upstream, whatever Ollama or OpenRouter’s own /chat/completions sent back, with no envelope added:
{
"id": "chatcmpl-1",
"object": "chat.completion",
"model": "ministral-3:3b",
"choices": [
{
"index": 0,
"message": { "role": "assistant", "content": "1. Overseeing withdrawals...\n2. Approving budgets...\n3. Reporting to Parliament..." },
"finish_reason": "stop"
}
],
"usage": { "prompt_tokens": 22, "completion_tokens": 61, "total_tokens": 83 }
}Threads (thread_id)
Passing thread_id opts into server-side memory instead of sending the full
transcript on every call. With a thread_id:
- The body must contain exactly one
usermessage, plus any number ofsystemmessages, any other mix returns400 thread_messages_invalid. - Multimodal
content(images) on the user turn is not supported with a thread and returns400 thread_multimodal_not_supported, stateless calls only for images.
Without a thread_id, the whole request is checked against the model’s
context window up front (see error conditions for the exact context_length_exceeded messages for both cases).
Streaming
Set "stream": true for an SSE relay of the upstream’s own chunks, byte for
byte, ending in a literal data: [DONE] line. Full frame examples are on the Streaming page.
Errors this endpoint can return
400 empty_messages, 400 model_not_allowed (model isn’t served at all), 403 model_not_allowed (model is served, but this key isn’t scoped to it), 400 thread_messages_invalid, 400 thread_multimodal_not_supported, 400 context_length_exceeded, 429 rate_limit_exceeded, 429 budget_exceeded, 502 upstream_error. See Errors for
the envelope shape and exact trigger conditions.