Documentation Index
Fetch the complete documentation index at: https://docs.knowledgestack.ai/llms.txt
Use this file to discover all available pages before exploring further.
Overview
Knowledge Stack provides two real-time communication channels:
- WebSocket — For receiving instant notifications about events in your tenant (e.g., document ingestion completed)
- Server-Sent Events (SSE) — For streaming AI assistant responses token-by-token
Both channels use Redis Streams as the underlying message transport, which enables horizontal scaling across multiple server instances.
WebSocket Notifications
Connecting
Connect to the WebSocket endpoint at:
Authentication is handled automatically via your session cookie (ks_uat). On a successful connection, you will receive a confirmation message:
{
"type": "system",
"event": "connection_established",
"connection_id": "abc-123",
"user_id": "...",
"tenant_id": "..."
}
Subscribing to Channels
After connecting, subscribe to notification channels by sending JSON messages:
{"action": "subscribe", "channel": "ks:{tenant_id}:notifications"}
You can also subscribe to user-specific notifications:
{"action": "subscribe", "channel": "ks:{tenant_id}:users:{user_id}"}
To unsubscribe:
{"action": "unsubscribe", "channel": "ks:{tenant_id}:notifications"}
Channel Security
Two security rules are enforced on all subscriptions:
- The
tenant_id in the channel must match your authenticated tenant
- For user channels, the
user_id must match your authenticated user
Notification Events
| Event | Description | Key Fields |
|---|
document_ingestion_completed | A document has finished processing | document_id, document_version_id, workflow_id |
Server Messages
| Event | Description |
|---|
connection_established | Connection accepted, includes your connection_id |
subscribed | Successfully subscribed to a channel |
unsubscribed | Successfully unsubscribed from a channel |
error | An error occurred (includes code and message) |
Connection Close Codes
| Code | Meaning |
|---|
| 4401 | Unauthorized — invalid or missing session |
| 4403 | Forbidden — you are not a member of this tenant |
| 4503 | Service unavailable — real-time features are disabled |
| 1001 | Server shutting down |
Keepalive
The connection uses standard WebSocket ping/pong frames (RFC 6455) for keepalive. No application-level heartbeat is needed.
SSE Thread Streaming
Endpoint
GET /v1/threads/{thread_id}/stream
Authentication uses standard REST authentication (session cookie).
Query Parameters
| Parameter | Type | Required | Description |
|---|
last_message_id | UUID | No | The ID of the last message you received. Used for reconnection. |
last_entry_id | string | No | The stream entry ID of the last event you received. Required when last_message_id is provided. |
Streaming Events
When the AI assistant generates a response, you receive a sequence of SSE events:
| Event | Description |
|---|
message_start | A new assistant message is beginning |
text_start | A text segment is starting |
text_delta | A chunk of text content (the delta field contains the text) |
text_end | The current text segment is complete |
step | A tool call or processing step occurred |
citations | Source citations for the response |
message_end | The assistant message is complete |
done | The stream is finished (data: [DONE]) |
The typical event lifecycle is:
message_start -> text_start -> text_delta* -> text_end -> citations? -> message_end -> done
Tool call step events may be interleaved during processing.
Each event follows this format:
id: 1706000000000-5
event: text_delta
data: {"delta":"Hello","id":"msg-uuid","part_id":"part-uuid","ts":"2026-02-17T10:30:00Z","message_id":"msg-uuid"}
Reconnection
If your connection drops while an assistant response is still streaming, you can reconnect with replay:
GET /v1/threads/{thread_id}/stream?last_message_id=abc&last_entry_id=1706000000000-5
Knowledge Stack will replay any events you missed and then continue with live events. You will receive a replay_complete event when replay is finished:
event: replay_complete
data: {"replayed_count":12,"last_entry_id":"1706000000000-50"}
If the message has already finished streaming when you reconnect, you will receive a message_not_streaming event instead. In that case, fetch the complete message via the REST API:
GET /v1/threads/{thread_id}/messages/{message_id}
Best Practices for SSE
- Open a new SSE connection when you navigate to a thread
- For reconnection mid-stream, always include both
last_message_id and last_entry_id
- Do not rely on
EventSource auto-reconnect — close the connection and open a new one with updated parameters
- The stream self-terminates when done. Open a new connection for the next message.
SSE Keepalive
The server sends SSE comment pings (: ping) every 30 seconds to keep the connection alive.
Configuration
If you are self-hosting Knowledge Stack, these settings control the real-time notification system:
| Setting | Default | Environment Variable | Description |
|---|
| Redis URL | DISABLED | REDIS_URL | Redis connection string. Set to DISABLED to turn off real-time features. |
| Max connections | 20 | REDIS_MAX_CONNECTIONS | Redis connection pool size |
| Stream TTL | 30 min | WS_STREAM_TTL_MINUTES | How long stream entries are retained |
| SSE buffer size | 1024 | SSE_QUEUE_SIZE | Maximum buffered events per subscriber |
Error Handling
| Scenario | What Happens |
|---|
| Redis is disabled | WebSocket returns close code 4503. SSE returns an error. |
| Redis goes down during use | The system automatically retries with exponential backoff |
| Your SSE client disconnects | Your subscription is cleaned up automatically |
| SSE buffer fills up | Your subscription is removed to prevent memory issues |
| Message is no longer streaming | SSE returns message_not_streaming — fetch the message via REST instead |