Skip to main content

Gateway REST API

The ClawDesk gateway exposes a REST API on the configured port (default :1420). All endpoints use JSON request/response bodies.

Base URL

http://localhost:1420/api/v1

Authentication

API requests require a valid bearer token when authentication is enabled:

Authorization: Bearer <token>

Health Check

GET /api/v1/health

Returns the gateway's health status.

Response 200 OK:

{
"status": "healthy",
"version": "0.1.0",
"uptime_secs": 3600,
"channels_active": 3,
"providers_active": 2
}

Messages

POST /api/v1/message

Send a message through the agent pipeline.

Request Body:

{
"session_id": "sess_abc123",
"channel_id": "telegram",
"content": "What is the weather like today?",
"metadata": {
"user_id": "user_456",
"thread_id": "thread_789"
}
}

Response 200 OK:

{
"id": "msg_def456",
"session_id": "sess_abc123",
"role": "assistant",
"content": "I don't have access to real-time weather data...",
"model": "claude-sonnet-4-20250514",
"tokens_used": {
"input": 142,
"output": 87
},
"timestamp": "2026-02-17T10:30:00Z"
}

Error 400 Bad Request:

{
"error": "invalid_request",
"message": "session_id is required"
}

Error 429 Too Many Requests:

{
"error": "rate_limited",
"message": "Rate limit exceeded",
"retry_after_secs": 30
}

Sessions

GET /api/v1/sessions

List all active sessions.

Query Parameters:

ParameterTypeDefaultDescription
limitinteger50Max results
offsetinteger0Pagination offset
channelstringFilter by channel ID

Response 200 OK:

{
"sessions": [
{
"id": "sess_abc123",
"channel_id": "telegram",
"created_at": "2026-02-17T09:00:00Z",
"last_active": "2026-02-17T10:30:00Z",
"message_count": 12
}
],
"total": 1,
"limit": 50,
"offset": 0
}

GET /api/v1/sessions/:id

Get a specific session by ID.

Response 200 OK:

{
"id": "sess_abc123",
"channel_id": "telegram",
"created_at": "2026-02-17T09:00:00Z",
"last_active": "2026-02-17T10:30:00Z",
"message_count": 12,
"model": "claude-sonnet-4-20250514",
"metadata": {}
}

Error 404 Not Found:

{
"error": "not_found",
"message": "Session sess_xyz not found"
}

DELETE /api/v1/sessions/:id

Delete a session and its conversation history.

Response 204 No Content (empty body)

GET /api/v1/sessions/:id/messages

Get the conversation history for a session.

Query Parameters:

ParameterTypeDefaultDescription
limitinteger100Max messages
beforestringCursor for pagination

Response 200 OK:

{
"messages": [
{
"id": "msg_001",
"role": "user",
"content": "Hello!",
"timestamp": "2026-02-17T09:00:00Z"
},
{
"id": "msg_002",
"role": "assistant",
"content": "Hi! How can I help you?",
"timestamp": "2026-02-17T09:00:01Z",
"model": "claude-sonnet-4-20250514"
}
],
"has_more": false
}

POST /api/v1/sessions/:id/compact

Trigger context compaction for a session. Summarizes older messages to free token budget.

Response 200 OK:

{
"session_id": "sess_abc123",
"messages_before": 45,
"messages_after": 12,
"tokens_saved": 8420
}

Channels

GET /api/v1/channels

List all registered channels and their status.

Response 200 OK:

{
"channels": [
{
"id": "telegram",
"name": "Telegram",
"status": "connected",
"capabilities": ["threaded", "reactions", "streaming"],
"message_count": 1420
},
{
"id": "discord",
"name": "Discord",
"status": "connected",
"capabilities": ["threaded", "reactions", "group_management"],
"message_count": 890
}
]
}

Configuration

GET /api/v1/config

Get the current runtime configuration (sensitive values redacted).

Response 200 OK:

{
"gateway": {
"host": "0.0.0.0",
"port": 1420
},
"providers": {
"anthropic": { "enabled": true, "default_model": "claude-sonnet-4-20250514" },
"openai": { "enabled": true, "default_model": "gpt-4o" }
},
"fallback": {
"chain": ["anthropic", "openai", "ollama"],
"strategy": "sequential"
}
}

Models

GET /api/v1/models

List all available models across registered providers.

Response 200 OK:

{
"models": [
{
"id": "claude-sonnet-4-20250514",
"provider": "anthropic",
"capabilities": ["chat", "streaming", "function_calling"],
"context_window": 200000
},
{
"id": "gpt-4o",
"provider": "openai",
"capabilities": ["chat", "streaming", "function_calling", "json_mode"],
"context_window": 128000
}
]
}

Error Format

All errors follow a consistent format:

{
"error": "error_code",
"message": "Human-readable description",
"details": {}
}
Status CodeError CodeDescription
400invalid_requestMalformed request body
401unauthorizedMissing or invalid auth token
404not_foundResource not found
429rate_limitedRate limit exceeded
500internal_errorInternal server error
503unavailableService temporarily unavailable