REST API

All endpoints are mounted under /api/v1 on the gateway's bind address/port. JSON in, JSON out.

Status & Sessions

Method & PathDescription
GET /api/v1/statusGateway health, version, uptime, active session count
GET /api/v1/sessionsList active WebSocket sessions
DELETE /api/v1/sessions/{session_id}Disconnect and remove a session

Channels

Method & PathDescription
GET /api/v1/channelsList registered channel adapters and connection status
GET /api/v1/channels/{channel_id}Get info + config schema for one channel
POST /api/v1/channels/{channel_id}/sendSend a message via a channel — body: {"target", "text"}

Memory

Method & PathDescription
GET /api/v1/memory/search?q=&session_id=&limit=Search long-term memory
GET /api/v1/memory/entries?session_id=&limit=List recent long-term memory entries
PATCH /api/v1/memory/entries/{entry_id}Edit content and/or importance — body: {"content"?, "importance"?}
DELETE /api/v1/memory/entries/{entry_id}Delete a single memory entry

Metrics

Method & PathDescription
GET /api/v1/metricsPrometheus text exposition format
GET /api/v1/metrics/snapshotMachine-readable JSON metrics snapshot
Channel and memory routes require a running AgentRuntime. If the runtime hasn't been injected yet (e.g. gateway still starting up), they return 503 Service Unavailable instead of a 200 with empty data.

WebSocket protocol

Connect to ws://<bind>:<port>/ws. The server sends a hello frame immediately on connect; after that, exchange JSON frames of the following shapes:

Client → Server typeServer response
ping{"type": "pong", "timestamp"}
subscribe (body: channel){"type": "subscribed", "channel"}
message (body: text, optional id){"type": "message", "text", "message_id"} — the agent's reply
anything else / invalid JSON{"type": "error", "message"}
// Example: send a chat message and get the reply
ws.send(JSON.stringify({ type: "message", text: "What's the weather like?", id: "m1" }));
// → { "type": "message", "message_id": "m1", "text": "...", "timestamp": ... }