API Reference
clauderon provides HTTP REST and WebSocket APIs for programmatic session management.
Base URL
http://localhost:3030REST API
Health Check
Check if the daemon is running.
GET /healthResponse:
{ "status": "healthy", "version": "0.1.0"}List Sessions
Get all sessions.
GET /api/sessionsQuery Parameters:
include_archived- Include archived sessions (default: false)
Response:
{ "sessions": [ { "id": "uuid", "name": "session-name", "backend": "docker", "agent": "claude", "access_mode": "read-write", "status": "running", "repo_path": "/home/user/project", "worktree_path": "/home/user/.clauderon/worktrees/session-name", "created_at": "2024-01-15T10:30:00Z", "archived": false } ]}Get Session
Get a specific session.
GET /api/sessions/:idResponse:
{ "id": "uuid", "name": "session-name", "backend": "docker", "agent": "claude", "access_mode": "read-write", "status": "running", "repo_path": "/home/user/project", "worktree_path": "/home/user/.clauderon/worktrees/session-name", "prompt": "Fix the login bug", "created_at": "2024-01-15T10:30:00Z", "archived": false, "chat_history": [ { "role": "user", "content": "Fix the login bug" }, { "role": "assistant", "content": "I'll analyze the login code..." } ]}Create Session
Create a new session.
POST /api/sessionsRequest Body (Single Repository):
{ "repo_path": "/home/user/project", "prompt": "Fix the login bug", "backend": "docker", "agent": "claude", "access_mode": "read-write", "no_plan_mode": false, "model": "claude-sonnet-4-5"}Request Body (Multi-Repository):
{ "name": "multi-repo-session", "repositories": [ { "path": "/home/user/project1", "mount_name": "main" }, { "path": "/home/user/project2", "mount_name": "lib" } ], "prompt": "Refactor shared code", "backend": "docker", "agent": "claude", "access_mode": "read-write"}Parameters:
| Field | Type | Required | Description |
|---|---|---|---|
repo_path | string | Yes* | Path to single repository |
repositories | array | Yes* | Array of repositories (multi-repo) |
prompt | string | Yes | Initial prompt for agent |
backend | string | No | Backend type (default: configured default) |
agent | string | No | Agent type (default: “claude”) |
access_mode | string | No | Access mode (default: “read-write”) |
no_plan_mode | boolean | No | Disable plan mode (default: false) |
model | string | No | AI model override (default: “claude-sonnet-4-5”) |
name | string | No | Custom session name |
base_branch | string | No | Git base branch |
image_paths | array | No | Paths to images to attach |
* Either repo_path or repositories required (not both)
Repository object:
path- Absolute path to repositorymount_name- Unique mount name (alphanumeric, hyphens, underscores)
Model options:
See Model Selection Guide for full list. Examples:
claude-opus-4-5- Most capable Claudeclaude-sonnet-4-5- Default balanced Claudeclaude-haiku-4-5- Fastest Claudegpt-5.2-codex- GPT optimized for codegemini-3-pro- Gemini with 1M context
Access mode options:
read-only- Agent can read files onlyread-write- Agent can read and write filesfull-access- Agent has full system access
Response:
{ "id": "uuid", "name": "generated-session-name", "status": "starting", "repositories": [ { "path": "/home/user/project1", "mount_name": "main", "mount_point": "/workspace/main" } ], "model": "claude-sonnet-4-5"}Multi-Repository Limitations:
- Maximum 5 repositories per session
- Kubernetes backend not fully supported (TODO)
- Mount names must be unique
- Only available via Web UI and API (not CLI/TUI)
See Multi-Repository Guide for details.
Delete Session
Delete a session permanently.
DELETE /api/sessions/:idQuery Parameters:
force- Force delete without confirmation (default: false)
Response:
{ "success": true}Archive Session
Archive a session.
POST /api/sessions/:id/archiveResponse:
{ "success": true}Unarchive Session
Restore an archived session.
POST /api/sessions/:id/unarchiveResponse:
{ "success": true}Set Access Mode
Change a session’s access mode.
PUT /api/sessions/:id/access-modeRequest Body:
{ "access_mode": "read-only"}Response:
{ "success": true, "access_mode": "read-only"}Refresh Session
Refresh a Docker session (pull latest image, recreate container).
POST /api/sessions/:id/refreshResponse:
{ "success": true}Start Session
Start a stopped session.
POST /api/sessions/:id/startResponse:
{ "success": true, "status": "starting"}Use cases:
- Resume stopped Docker container
- Restart session after manual stop
- Wake from non-hibernated stop state
Wake Session
Wake a hibernated session (Sprites backend).
POST /api/sessions/:id/wakeResponse:
{ "success": true, "status": "waking", "estimated_time": "5-10s"}Backend support:
- ✅ Sprites (hibernation/wake)
- ❌ Other backends (use start instead)
Recreate Session
Recreate session container while preserving data.
POST /api/sessions/:id/recreateRequest Body (optional):
{ "fresh": false, "reason": "Container failed to start"}Response:
{ "success": true, "status": "recreating", "data_preservation": { "git_state": true, "chat_history": true, "uncommitted_changes": true }}Preserves:
- Session metadata and chat history
- Git repository (committed and uncommitted changes)
- Configuration
Rebuilds:
- Container
- Environment
- Running processes
Recreate Session (Fresh)
Recreate session with fresh git clone.
POST /api/sessions/:id/recreate-freshResponse:
{ "success": true, "status": "recreating", "data_preservation": { "git_state": false, "chat_history": true, "uncommitted_changes": false }}Preserves:
- Session metadata and chat history
- Configuration
Rebuilds:
- Container
- Git repository (fresh clone, uncommitted changes lost)
Cleanup Session
Cleanup session resources without deleting session record.
POST /api/sessions/:id/cleanupResponse:
{ "success": true, "resources_cleaned": [ "container", "volumes", "worktree" ]}Use cases:
- Remove orphaned resources
- Free disk space while keeping metadata
- Prepare for recreation
Get Session Health
Check session health status and available recovery actions.
GET /api/sessions/:id/healthResponse:
{ "session_id": "uuid", "health": "Error", "details": { "container_status": "exited", "exit_code": 1, "error_message": "OCI runtime error", "backend": "docker" }, "available_actions": [ "recreate", "recreate_fresh", "cleanup" ], "data_preservation": { "recreate": true, "recreate_fresh": false, "cleanup": false }, "reconciliation": { "attempts": 2, "last_attempt": "2025-01-28T12:30:00Z", "next_attempt": "2025-01-28T12:35:00Z", "error": "Container failed to start" }, "last_check": "2025-01-28T12:34:56Z"}Health states:
Healthy- Session running normallyStopped- Container stoppedHibernated- Session suspended (Sprites)Pending- Resource creation in progressError- Container failedCrashLoop- Container repeatedly crashing (K8s)Missing- Resource deleted externally
See Health & Reconciliation Guide for details.
Update Session Metadata
Update session metadata (name, description, tags).
POST /api/sessions/:id/metadataRequest Body:
{ "name": "new-session-name", "description": "Updated description", "tags": ["feature-x", "backend"]}Response:
{ "success": true, "metadata": { "name": "new-session-name", "description": "Updated description", "tags": ["feature-x", "backend"] }}Regenerate Metadata (AI)
Use AI to regenerate session metadata based on chat history.
POST /api/sessions/:id/regenerate-metadataResponse:
{ "success": true, "metadata": { "name": "auth-bug-fix", "description": "Fixed authentication bug in login flow", "tags": ["bugfix", "authentication", "security"] }}Requirements:
- AI metadata feature enabled (
ai_metadata = true) - Session has chat history
- AI API credentials configured
Upload Files
Upload files to a running session.
POST /api/sessions/:id/uploadRequest: Multipart form data
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary
------WebKitFormBoundaryContent-Disposition: form-data; name="file"; filename="data.json"Content-Type: application/json
{ "key": "value" }------WebKitFormBoundary--Response:
{ "success": true, "files": [ { "name": "data.json", "path": "/workspace/data.json", "size": 18 } ]}Upload destination: Files uploaded to session’s working directory.
Browse Directory
Browse directories for session creation (Web UI helper endpoint).
POST /api/browse-directoryRequest Body:
{ "path": "/home/user/projects", "show_hidden": false}Response:
{ "current_path": "/home/user/projects", "parent": "/home/user", "entries": [ { "name": "project1", "path": "/home/user/projects/project1", "is_dir": true, "is_git_repo": true, "size": null }, { "name": "README.md", "path": "/home/user/projects/README.md", "is_dir": false, "is_git_repo": false, "size": 1024 } ]}Use cases:
- Directory picker in Web UI
- Repository selection
- Git repository discovery
Get Storage Classes (Kubernetes)
Get available Kubernetes storage classes.
GET /api/storage-classesResponse:
{ "storage_classes": [ { "name": "standard", "provisioner": "kubernetes.io/gce-pd", "is_default": true }, { "name": "fast-ssd", "provisioner": "kubernetes.io/gce-pd", "is_default": false } ]}Backend: Kubernetes only. Returns empty for other backends.
Get Configuration
Get current configuration.
GET /api/configResponse:
{ "default_backend": "zellij", "default_agent": "claude", "features": { "webauthn_auth": false, "ai_metadata": false }}Get Credentials Status
Get status of configured credentials.
GET /api/credentialsResponse:
{ "credentials": { "github_token": { "configured": true, "source": "1password" }, "anthropic_oauth_token": { "configured": true, "source": "file" }, "openai_api_key": { "configured": false, "source": null } }}WebSocket API
Clauderon provides two WebSocket endpoints:
- Event Stream -
/ws/events- Session events and updates - Terminal Console -
/ws/console/{sessionId}- Interactive terminal access
Event Stream (/ws/events)
Real-time session events, status changes, and chat updates.
Connect
ws://localhost:3030/ws/eventsMessage Format
All messages are JSON:
{ "type": "message_type", "data": { ... }}Subscribe to Session
Subscribe to session updates.
Send:
{ "type": "subscribe", "session_id": "uuid"}Receive (acknowledgment):
{ "type": "subscribed", "session_id": "uuid"}Session Updates
Receive real-time session updates.
Status Change:
{ "type": "session_status", "session_id": "uuid", "status": "running"}Chat Message:
{ "type": "chat_message", "session_id": "uuid", "message": { "role": "assistant", "content": "I've found the bug..." }}Tool Call:
{ "type": "tool_call", "session_id": "uuid", "tool": { "name": "read_file", "input": { "path": "/workspace/src/auth.ts" } }}Tool Result:
{ "type": "tool_result", "session_id": "uuid", "tool": { "name": "read_file", "output": "file contents..." }}Unsubscribe
Send:
{ "type": "unsubscribe", "session_id": "uuid"}Send Message
Send a message to an active session.
Send:
{ "type": "send_message", "session_id": "uuid", "content": "Now fix the logout bug"}Ping/Pong
Keep the connection alive.
Send:
{ "type": "ping"}Receive:
{ "type": "pong"}Terminal Console (/ws/console/{sessionId})
Interactive terminal access to session container.
Connect
ws://localhost:3030/ws/console/{sessionId}Protocol
The terminal console uses a binary protocol for terminal data:
Client to Server (Input):
Binary data (user input keystrokes)Server to Client (Output):
Binary data (terminal output, escape sequences)Terminal Resize
Send terminal resize events:
Send:
{ "type": "resize", "cols": 120, "rows": 40}Attach Options
Include options in connection URL:
ws://localhost:3030/ws/console/{sessionId}?cols=120&rows=40Query parameters:
cols- Initial terminal columns (default: 80)rows- Initial terminal rows (default: 24)
Example (JavaScript with xterm.js)
import { Terminal } from 'xterm';import { WebglAddon } from 'xterm-addon-webgl';import { FitAddon } from 'xterm-addon-fit';
const term = new Terminal();const fitAddon = new FitAddon();term.loadAddon(fitAddon);term.open(document.getElementById('terminal'));fitAddon.fit();
const ws = new WebSocket(`ws://localhost:3030/ws/console/${sessionId}`);
ws.onopen = () => { // Send initial terminal size ws.send(JSON.stringify({ type: 'resize', cols: term.cols, rows: term.rows }));};
// Forward terminal input to WebSocketterm.onData((data) => { ws.send(data);});
// Forward WebSocket output to terminalws.onmessage = (event) => { if (event.data instanceof Blob) { event.data.text().then((text) => { term.write(text); }); } else { term.write(event.data); }};
// Handle terminal resizewindow.addEventListener('resize', () => { fitAddon.fit(); ws.send(JSON.stringify({ type: 'resize', cols: term.cols, rows: term.rows }));});Protocol Details
Message types:
-
Data (Binary) - Terminal I/O
- Client → Server: User input (keystrokes, paste)
- Server → Client: Terminal output (text, ANSI escape codes)
-
Resize (JSON) - Terminal size change
{"type": "resize","cols": 120,"rows": 40} -
Error (JSON) - Error messages
{"type": "error","message": "Session not found"}
Connection lifecycle:
- Client connects to
/ws/console/{sessionId} - Server validates session exists and is running
- Server attaches to session’s PTY (pseudo-terminal)
- Bidirectional data flow begins
- On disconnect, PTY remains attached (session continues running)
Security:
- Same authentication as REST API (token or cookie)
- Session must belong to authenticated user
- PTY access is exclusive (one console connection per session recommended)
Error Responses
All errors follow this format:
{ "error": { "code": "SESSION_NOT_FOUND", "message": "Session with ID 'xyz' not found" }}Error Codes
| Code | HTTP Status | Description |
|---|---|---|
SESSION_NOT_FOUND | 404 | Session doesn’t exist |
BACKEND_ERROR | 500 | Backend operation failed |
INVALID_REQUEST | 400 | Invalid request body |
UNAUTHORIZED | 401 | Authentication required |
FORBIDDEN | 403 | Operation not allowed |
CONFLICT | 409 | Resource already exists |
Authentication
By default, no authentication is required (localhost only).
With WebAuthn enabled, include the session token:
Authorization: Bearer <token>Or as a cookie:
Cookie: clauderon_session=<token>Rate Limiting
No rate limiting is applied by default. For production deployments behind a reverse proxy, configure rate limiting there.
CORS
The API allows requests from:
- Same origin
http://localhost:*http://127.0.0.1:*
For custom origins, configure via reverse proxy.
Examples
Create Session (curl)
curl -X POST http://localhost:3030/api/sessions \ -H "Content-Type: application/json" \ -d '{ "repo_path": "/home/user/project", "prompt": "Fix the login bug", "backend": "docker", "agent": "claude" }'List Sessions (JavaScript)
const response = await fetch('http://localhost:3030/api/sessions');const data = await response.json();console.log(data.sessions);WebSocket Connection (JavaScript)
const ws = new WebSocket('ws://localhost:3030/ws');
ws.onopen = () => { ws.send(JSON.stringify({ type: 'subscribe', session_id: 'uuid' }));};
ws.onmessage = (event) => { const message = JSON.parse(event.data); console.log('Received:', message);};See Also
- Web Interface - Browser-based UI
- CLI Reference - Command-line interface