Chat API
Chat with your documents using retrieval-augmented generation (RAG). The API uses the AI SDK UIMessage contract: send a single message (one UIMessage with role and parts) and receive a streamed UIMessage response (SSE). Sessions are created upfront via POST /api/chat/sessions.
Create a session
Start a new conversation by creating a session, then send messages with that session_id.
POST /api/chat/sessionsRequest body:
{
"knowledge_base_id": "kb-uuid"
}Response:
{
"session_id": "session-uuid"
}Use session_id in all subsequent POST /api/chat requests for that conversation.
Send message (stream only)
POST /api/chatSend a single message and receive a streamed response (AI SDK UIMessage stream). Both session_id and knowledge_base_id are required.
Request
{
"message": {
"role": "user",
"parts": [{ "type": "text", "text": "What are the payment terms in the contract?" }]
},
"session_id": "session-uuid",
"knowledge_base_id": "kb-uuid",
"mode": "quick",
"language": "en"
}| Field | Type | Required | Description |
|---|---|---|---|
message | object | Yes | Single AI SDK UIMessage: role (user | assistant | system) and parts (e.g. [{ "type": "text", "text": "..." }]). |
session_id | string (UUID) | Yes | Session from POST /api/chat/sessions. |
knowledge_base_id | string (UUID) | Yes | Knowledge base to search. |
mode | string | No | quick, deep, or code. Default quick. |
language | string | No | Response language (ISO 639-1, max 10 chars). |
Response: UIMessage stream (SSE)
The response is always a Server-Sent Events stream in AI SDK UIMessage chunk format. Each line is data: <json>\n\n; chunks include:
text-delta— append to the assistant’s reply text.tool-output-available— for tools that return context and citations,outputcontainscontextandcitations. This can be for:- search_documents — RAG search over the knowledge base.
- search_documents_scoped — Search limited to documents from a previous answer.
- query_spreadsheet — Structured sort/limit on a spreadsheet; citations include
document(filename, document_type, sheet, row_start, row_end) andchunk_id(e.g.document_id:row:rowNumber).
data: [DONE]— end of stream.
Example flow:
- Call
POST /api/chat/sessionswithknowledge_base_id→ getsession_id. - Call
POST /api/chatwithmessage(one user message with one text part),session_id, andknowledge_base_id. - Consume the SSE stream; accumulate text from
text-deltaand citations fromtool-output-available(forsearch_documents,search_documents_scoped, orquery_spreadsheet).
Tools
The model can call these tools during a turn. Stream chunks will include tool-output-available for tools that return data:
| Tool | Description |
|---|---|
search_documents | RAG search over the knowledge base. |
search_documents_scoped | Search only within documents from previous citations. |
summarize_chunk | Summarize a cited document or chunk (e.g. “citation N”). |
query_spreadsheet | Run a structured sort/limit on a spreadsheet (e.g. cheapest, top N by column). |
create_share_link | Generate a shareable link for the conversation (may require user approval). |
display_chart | Render a chart (bar, line, or pie) from provided data. |
ask_confirmation | Ask the user for explicit Yes/No before proceeding. |
open_citation_in_sidebar | Open a citation in the sidebar (e.g. “open citation 3”). |
Modes
| Mode | Description |
|---|---|
quick | Fast responses, fewer chunks. |
deep | Deeper search, more context. |
code | Optimized for code-related questions. |
JavaScript example (stream)
// 1. Create session
const sessionRes = await fetch('/api/chat/sessions', {
method: 'POST',
headers: {
'Authorization': 'Bearer YOUR_API_KEY',
'Content-Type': 'application/json'
},
body: JSON.stringify({ knowledge_base_id: 'kb-uuid' })
});
const { session_id } = await sessionRes.json();
// 2. Send message and read stream
const chatRes = await fetch('/api/chat', {
method: 'POST',
headers: {
'Authorization': 'Bearer YOUR_API_KEY',
'Content-Type': 'application/json'
},
body: JSON.stringify({
message: { role: 'user', parts: [{ type: 'text', text: 'What are the payment terms?' }] },
session_id,
knowledge_base_id: 'kb-uuid',
mode: 'quick'
})
});
const reader = chatRes.body.getReader();
const decoder = new TextDecoder();
let buffer = '';
while (true) {
const { done, value } = await reader.read();
if (done) break;
buffer += decoder.decode(value, { stream: true });
// Parse SSE lines (data: {...}) and handle text-delta / tool-output-available
}For a non-streaming JSON response (e.g. from a server or API key), use the Embed API with action: 'chat'; it uses this same contract under the hood and returns { message, citations }.
Get Chat History
GET /api/chat?session_id={session_id}Get all messages in a chat session. Pass session_id as a query parameter (not in the body).
Response
{
"messages": [
{
"id": "msg-uuid",
"role": "user",
"content": "What are the payment terms?",
"created_at": "2024-01-15T10:30:00Z"
},
{
"id": "msg-uuid",
"role": "assistant",
"content": "According to the contract, payment terms are Net 30...",
"citations": [...],
"created_at": "2024-01-15T10:30:05Z"
}
]
}Persist Message
POST /api/chat/messagesPersist a user or assistant message (e.g. after consuming the stream). Use this to store messages when you handle the stream client-side and want to keep history in sync.
Request body:
| Field | Type | Required | Description |
|---|---|---|---|
session_id | string (UUID) | Yes | Session ID. |
role | string | Yes | user or assistant. |
content | string | Yes | Message text (1–500,000 chars). |
citations | object | No | Optional citations payload. |
{
"session_id": "session-uuid",
"role": "assistant",
"content": "According to the contract, payment terms are Net 30...",
"citations": [...]
}Response: 201 Created with { "data": { "id": "msg-uuid" } }.
Chat Sessions
List Sessions
GET /api/chat/sessionsList chat sessions.
Query Parameters:
| Parameter | Default | Description |
|---|---|---|
knowledge_base_id | - | Filter by knowledge base |
limit | 20 | Results per page |
offset | 0 | Pagination offset |
Response:
{
"sessions": [
{
"id": "session-uuid",
"title": "Contract Questions",
"knowledge_base_id": "kb-uuid",
"message_count": 5,
"is_shared": false,
"created_at": "2024-01-15T10:00:00Z",
"updated_at": "2024-01-15T10:30:00Z"
}
],
"total": 25,
"has_more": true
}Get Session
GET /api/chat/sessions/{id}Update Session
PATCH /api/chat/sessions/{id}Update session title.
{
"title": "Payment Terms Discussion"
}Delete Session
DELETE /api/chat/sessions/{id}Session Sharing
Enable Sharing
POST /api/chat/sessions/{id}/shareGenerate a shareable link for the session.
Response:
{
"session": {...},
"share_url": "https://your-domain.com/chat/share/token123"
}Disable Sharing
DELETE /api/chat/sessions/{id}/shareExport Session
GET /api/chat/sessions/{id}/exportExport the chat session in various formats.
Query Parameters:
| Parameter | Default | Options |
|---|---|---|
format | json | json, markdown, html |
Markdown Response:
# Chat Session: Contract Questions
## User
What are the payment terms in the contract?
## Assistant
According to the contract, payment terms are Net 30 days...
**Sources:**
- Service Agreement.pdf, page 5