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:

ParameterTypeDescriptionDefault
limitnumberMax conversations to return50
offsetnumberPagination offset0
channelstringFilter 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"
}
FieldTypeRequiredDescription
messagestringYesThe user’s message
conversationIdstringNoContinue an existing conversation. Omit to start a new one.
channelstringNoChannel 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

CodeDescription
AUTH_REQUIREDToken is missing or invalid
CONVERSATION_NOT_FOUNDThe specified conversation ID does not exist
PROVIDER_ERRORThe LLM provider returned an error (rate limit, invalid key, etc.)
TOOL_TIMEOUTAn MCP tool call did not respond in time
TOOL_ERRORAn MCP tool returned an error
SKILL_NOT_FOUNDReferenced 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