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:
| Parameter | Type | Default | Description |
|---|---|---|---|
limit | integer | 50 | Max results |
offset | integer | 0 | Pagination offset |
channel | string | — | Filter 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:
| Parameter | Type | Default | Description |
|---|---|---|---|
limit | integer | 100 | Max messages |
before | string | — | Cursor 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 Code | Error Code | Description |
|---|---|---|
| 400 | invalid_request | Malformed request body |
| 401 | unauthorized | Missing or invalid auth token |
| 404 | not_found | Resource not found |
| 429 | rate_limited | Rate limit exceeded |
| 500 | internal_error | Internal server error |
| 503 | unavailable | Service temporarily unavailable |