Chat completions

POST /v1/chat/completions

Request body

FieldTypeRequiredNotes
modelstringyesMust be served locally or on the cloud allow-list. See Local vs. cloud routing
messagesarrayyes{ role, content }; content is a string or a ContentPart[] for multimodal input
streambooleannoDefault false. See Streaming
max_tokensinteger ≥ 1no
temperaturenumber, 0-2no
response_formatobjectnoPassed through verbatim to the upstream, unvalidated here
thread_iduuidnoOpt 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 user message, plus any number of system messages, any other mix returns 400 thread_messages_invalid.
  • Multimodal content (images) on the user turn is not supported with a thread and returns 400 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.