Threads

A thread holds conversation state on the gateway, so a client can resume a run by sending only the newest turn instead of the whole transcript every time.

POST /v1/threads

curl https://ai.rcfi.co.ke/v1/threads \
  -H "Authorization: Bearer tak_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{ "title": "Revenue enquiry #4471", "external_ref": "ticket-4471" }'

Both fields are optional, title defaults to "New thread", external_ref is a free-form string for linking a thread back to your own record (a ticket id, a case number).

GET /v1/threads

Lists this project’s threads, newest-updated first, excluding archived ones. Filter to a specific external system’s record with ?external_ref=.

curl "https://ai.rcfi.co.ke/v1/threads?external_ref=ticket-4471" \
  -H "Authorization: Bearer tak_your_key_here"

GET /v1/threads/{id}

Returns the thread plus its full message list.

{
  "id": "c4b1...-uuid",
  "title": "Revenue enquiry #4471",
  "model": "ministral-3:3b",
  "messages": [
    {
      "id": "m1-uuid",
      "role": "user",
      "content": "Angalia hali ya ombi namba 4471.",
      "model": "ministral-3:3b",
      "error": null,
      "finish_reason": null,
      "complete": true,
      "created_at": "2026-09-01T09:12:11+00:00"
    },
    {
      "id": "m2-uuid",
      "role": "assistant",
      "content": "Ombi namba 4471 liko chini ya ukaguzi...",
      "model": "ministral-3:3b",
      "error": null,
      "finish_reason": "stop",
      "complete": true,
      "created_at": "2026-09-01T09:12:13+00:00"
    }
  ]
}

complete is false only for an assistant turn that stopped on finish_reason: "length", that’s the signal a client should offer to continue rather than treat the answer as finished.

404 thread_not_found if the thread doesn’t exist or belongs to another project.

DELETE /v1/threads/{id}

Archives the thread (204, no body). This is a soft delete, the row is kept, just excluded from GET /v1/threads and no longer continuable.

POST /v1/threads/{id}/continue

Appends to the thread and returns (or streams) the assistant’s reply.

FieldTypeNotes
modelstringOptional, falls back to the thread’s own model, then the first served chat model
messagesarrayOnly system-role entries are used, and are prepended for this call
max_tokens, temperature,Same as chat completions
streambooleanDefault false, frame shapes are on the Streaming page
curl https://ai.rcfi.co.ke/v1/threads/c4b1...-uuid/continue \
  -H "Authorization: Bearer tak_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{ "messages": [{ "role": "user", "content": "Na hatua inayofuata ni ipi?" }] }'

A non-streaming call still returns this done-shaped object, not an OpenAI chat.completion. See Streaming for why.

409 nothing_to_continue if the thread’s last assistant turn already finished normally (only a turn that stopped on "length" can be continued). model is validated the same way as chat completions, a model this key can’t call still returns model_not_allowed here, even though it never overrides an already-set thread model unless you pass one.

Note: continuation always calls the local pool directly, regardless of what the resolved model would normally route to, it does not currently pass through the cloud gate described in Local vs. cloud routing.