API & WebSocket
REST API endpoints, WebSocket protocol, and authentication for programmatic access to Chvor.
6 min read
API & WebSocket
Chvor exposes a REST API and a WebSocket endpoint for programmatic access. The API lets you send messages, manage conversations, and check server health. The WebSocket provides real-time streaming for Brain Canvas events.
The server runs on port 3001 by default (configurable via the PORT environment variable).
Authentication
If CHVOR_TOKEN is set, all API and WebSocket requests must include the token.
REST API
Pass the token in the Authorization header:
curl -H "Authorization: Bearer your-token-here" http://localhost:3001/api/health
WebSocket
Pass the token as a query parameter:
ws://localhost:3001/ws?token=your-token-here
If CHVOR_TOKEN is not set, no authentication is required. This is fine for local development but not recommended for production.
REST API Endpoints
Health Check
GET /api/health
Returns server status. Useful for monitoring and load balancer health checks.
Response:
{
"status": "ok",
"version": "1.2.0",
"uptime": 3600,
"channels": ["web", "telegram", "discord"],
"skills": 5,
"tools": 3
}
Example:
curl http://localhost:3001/api/health
Server Configuration
GET /api/config
Returns the current server configuration (excluding sensitive values like API keys).
Response:
{
"providers": ["anthropic", "openai"],
"channels": ["web", "telegram"],
"skills": [
{
"name": "code-reviewer",
"description": "Reviews code for bugs and style issues.",
"patterns": ["review this code", "code review"],
"tools": []
}
],
"mcpServers": {
"filesystem": { "status": "running", "tools": 4 },
"web-search": { "status": "running", "tools": 1 }
}
}
Example:
curl -H "Authorization: Bearer $CHVOR_TOKEN" http://localhost:3001/api/config
List Conversations
GET /api/conversations
Returns all conversations, ordered by last activity.
Query parameters:
| Parameter | Type | Description | Default |
|---|---|---|---|
limit | number | Max conversations to return | 50 |
offset | number | Pagination offset | 0 |
channel | string | Filter by channel (web, telegram, etc.) | — |
Response:
{
"conversations": [
{
"id": "conv_abc123",
"channel": "web",
"title": "Research on quantum computing",
"createdAt": "2026-03-25T10:00:00Z",
"updatedAt": "2026-03-25T10:15:00Z",
"messageCount": 12
}
],
"total": 42,
"limit": 50,
"offset": 0
}
Example:
curl -H "Authorization: Bearer $CHVOR_TOKEN" \
"http://localhost:3001/api/conversations?limit=10&channel=web"
Get Conversation
GET /api/conversations/:id
Returns a single conversation with all its messages.
Response:
{
"id": "conv_abc123",
"channel": "web",
"title": "Research on quantum computing",
"createdAt": "2026-03-25T10:00:00Z",
"messages": [
{
"id": "msg_001",
"role": "user",
"content": "Research quantum computing",
"createdAt": "2026-03-25T10:00:00Z"
},
{
"id": "msg_002",
"role": "assistant",
"content": "Here is what I found about quantum computing...",
"skill": "researcher",
"toolCalls": [
{
"tool": "web-search",
"input": { "query": "quantum computing 2026" },
"output": "..."
}
],
"createdAt": "2026-03-25T10:00:05Z"
}
]
}
Example:
curl -H "Authorization: Bearer $CHVOR_TOKEN" \
http://localhost:3001/api/conversations/conv_abc123
Send Message
POST /api/conversations
Sends a message and returns the agent’s response. This is a synchronous endpoint — it waits for the full response before returning.
Request body:
{
"message": "What is quantum computing?",
"conversationId": "conv_abc123",
"channel": "api"
}
| Field | Type | Required | Description |
|---|---|---|---|
message | string | Yes | The user’s message |
conversationId | string | No | Continue an existing conversation. Omit to start a new one. |
channel | string | No | Channel identifier. Defaults to "api". |
Response:
{
"conversationId": "conv_abc123",
"message": {
"id": "msg_003",
"role": "assistant",
"content": "Quantum computing is...",
"skill": "researcher",
"toolCalls": [],
"createdAt": "2026-03-25T10:20:00Z"
}
}
Example — new conversation:
curl -X POST http://localhost:3001/api/conversations \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $CHVOR_TOKEN" \
-d '{"message": "What is quantum computing?"}'
Example — continue existing conversation:
curl -X POST http://localhost:3001/api/conversations \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $CHVOR_TOKEN" \
-d '{
"message": "Tell me more about qubits",
"conversationId": "conv_abc123"
}'
Delete Conversation
DELETE /api/conversations/:id
Permanently deletes a conversation and all its messages.
Response:
{ "deleted": true }
Example:
curl -X DELETE -H "Authorization: Bearer $CHVOR_TOKEN" \
http://localhost:3001/api/conversations/conv_abc123
WebSocket Protocol
The WebSocket endpoint provides real-time streaming of Brain Canvas events — agent responses, tool calls, skill activations, and more.
Connecting
ws://localhost:3001/ws?token=your-token-here
In JavaScript:
const ws = new WebSocket("ws://localhost:3001/ws?token=your-token-here");
ws.onopen = () => {
console.log("Connected to Chvor");
};
ws.onmessage = (event) => {
const data = JSON.parse(event.data);
console.log("Event:", data.type, data);
};
ws.onclose = () => {
console.log("Disconnected");
};
Sending Messages
Send a message through the WebSocket for streamed responses:
ws.send(JSON.stringify({
type: "message",
conversationId: "conv_abc123", // optional — omit for new conversation
content: "Explain quantum entanglement"
}));
Event Types
The server sends events as JSON objects with a type field:
message:start
Emitted when the agent begins generating a response.
{
"type": "message:start",
"conversationId": "conv_abc123",
"messageId": "msg_004",
"skill": "researcher"
}
message:chunk
Emitted for each streamed token of the response. Use these to build the response progressively in the UI.
{
"type": "message:chunk",
"conversationId": "conv_abc123",
"messageId": "msg_004",
"content": "Quantum"
}
message:end
Emitted when the response is complete.
{
"type": "message:end",
"conversationId": "conv_abc123",
"messageId": "msg_004",
"content": "Quantum entanglement is a phenomenon where..."
}
tool:call
Emitted when the agent invokes an MCP tool.
{
"type": "tool:call",
"conversationId": "conv_abc123",
"messageId": "msg_004",
"tool": "web-search",
"input": { "query": "quantum entanglement explained" }
}
tool:result
Emitted when a tool call returns results.
{
"type": "tool:result",
"conversationId": "conv_abc123",
"messageId": "msg_004",
"tool": "web-search",
"output": "..."
}
skill:activated
Emitted when a message triggers a skill.
{
"type": "skill:activated",
"conversationId": "conv_abc123",
"skill": "researcher",
"pattern": "research {topic}",
"captured": { "topic": "quantum entanglement" }
}
error
Emitted when an error occurs during processing.
{
"type": "error",
"conversationId": "conv_abc123",
"message": "Tool 'web-search' timed out after 30s",
"code": "TOOL_TIMEOUT"
}
Error Codes
| Code | Description |
|---|---|
AUTH_REQUIRED | Token is missing or invalid |
CONVERSATION_NOT_FOUND | The specified conversation ID does not exist |
PROVIDER_ERROR | The LLM provider returned an error (rate limit, invalid key, etc.) |
TOOL_TIMEOUT | An MCP tool call did not respond in time |
TOOL_ERROR | An MCP tool returned an error |
SKILL_NOT_FOUND | Referenced skill does not exist |
Rate Limiting
Chvor does not impose its own rate limits. Rate limits come from your LLM provider. If you hit a provider rate limit, the API returns:
{
"error": "Rate limit exceeded",
"code": "PROVIDER_ERROR",
"retryAfter": 60
}
HTTP status code: 429.
CORS
In development mode, CORS is open (*). In production, the API only accepts requests from the same origin. If you need to call the API from a different domain, configure a reverse proxy that adds the appropriate CORS headers.
Next Steps
- CLI & Scripts — development and build commands.
- Environment Variables — all configuration options including
PORTandCHVOR_TOKEN. - Channel Setup — channels use these same API patterns internally.