Skip to content

API Reference

REST API documentation for Marionette.

Base URL

http://localhost:8080/api/v1

Authentication

All API requests require an API key in the Authorization header:

Authorization: Bearer mk_your_api_key

Sessions

Create Session

POST /api/v1/sessions

Request:

{
  "agent": "claude",
  "api_key": "sk-ant-xxx",
  "name": "my-session",
  "labels": {
    "user": "alice",
    "project": "api"
  },
  "lifecycle_mode": "on_demand",
  "idle_timeout_seconds": 1800
}

Response:

{
  "id": "sess_0002xK9mNpV1StGXR8",
  "name": "my-session",
  "status": "pending",
  "agent": "claude",
  "workspace_id": "ws_0002xK9mNpV1StGXR9",
  "labels": {"user": "alice", "project": "api"},
  "created_at": "2024-01-15T10:30:00Z"
}

List Sessions

GET /api/v1/sessions
GET /api/v1/sessions?status=active
GET /api/v1/sessions?labels=user:alice

Get Session

GET /api/v1/sessions/{session_id}

Suspend Session

POST /api/v1/sessions/{session_id}/suspend

Resume Session

POST /api/v1/sessions/{session_id}/resume

Terminate Session

DELETE /api/v1/sessions/{session_id}

Tasks

Create Task

POST /api/v1/tasks

Request:

{
  "session_id": "sess_0002xK9mNpV1StGXR8",
  "prompt": "Build a REST API with authentication",
  "timeout_seconds": 3600,
  "max_retries": 2
}

Response:

{
  "id": "task_0002xK9mNqW2TuHYS9",
  "session_id": "sess_0002xK9mNpV1StGXR8",
  "prompt": "Build a REST API with authentication",
  "status": "pending",
  "created_at": "2024-01-15T10:35:00Z"
}

List Tasks

GET /api/v1/tasks
GET /api/v1/tasks?status=running
GET /api/v1/tasks?session_id=sess_xxx

Get Task

GET /api/v1/tasks/{task_id}

Get Task Logs

GET /api/v1/tasks/{task_id}/logs
GET /api/v1/tasks/{task_id}/logs?stream=stdout

Response:

{
  "items": [
    {"stream": "stdout", "content": "Creating main.go...", "sequence": 1, "created_at": "..."},
    {"stream": "stdout", "content": "Writing code...", "sequence": 2, "created_at": "..."}
  ],
  "total": 2
}

Execute Task

Manually trigger execution of a pending task.

POST /api/v1/tasks/{task_id}/execute

Cancel Task

POST /api/v1/tasks/{task_id}/cancel

Retry Task

Retry a failed task.

POST /api/v1/tasks/{task_id}/retry

Permission Requests

List Permissions

GET /api/v1/permissions
GET /api/v1/permissions?status=pending
GET /api/v1/permissions?session_id=sess_xxx

Get Permission

GET /api/v1/permissions/{permission_id}

Approve Permission

POST /api/v1/permissions/{permission_id}/approve

Request:

{
  "reason": "Approved for testing"
}

Deny Permission

POST /api/v1/permissions/{permission_id}/deny

Request:

{
  "reason": "Command not allowed"
}

Runners

List Runners

GET /api/v1/runners
GET /api/v1/runners?status=idle
GET /api/v1/runners?pool=macos

Get Runner

GET /api/v1/runners/{runner_id}

Tunnels

Create Tunnel

POST /api/v1/sessions/{session_id}/tunnels

Request:

{
  "type": "http",
  "local_port": 3000,
  "is_public": false
}

Response:

{
  "id": "tun_0002xK9mNrX3UvIZT0",
  "session_id": "sess_0002xK9mNpV1StGXR8",
  "type": "http",
  "local_port": 3000,
  "public_url": "https://tun-abc123.marionette.example.com",
  "token": "ttok_xxx",
  "expires_at": "2024-01-15T12:30:00Z"
}

List Tunnels

GET /api/v1/sessions/{session_id}/tunnels

Close Tunnel

DELETE /api/v1/tunnels/{tunnel_id}

Workspaces

Create Workspace

POST /api/v1/workspaces

Request:

{
  "name": "my-workspace",
  "persist": true,
  "storage_type": "volume",
  "disk_quota_mb": 1024
}

List Workspaces

GET /api/v1/workspaces

Get Workspace

GET /api/v1/workspaces/{workspace_id}

Update Workspace

PATCH /api/v1/workspaces/{workspace_id}

Delete Workspace

DELETE /api/v1/workspaces/{workspace_id}

WebSocket Endpoints

Log Streaming

Stream task logs in real-time via WebSocket.

ws://localhost:8080/api/v1/logs/{task_id}/stream

Messages:

{"stream": "stdout", "content": "Building...", "sequence": 42, "created_at": "..."}

Event Stream

Stream server events (sessions, tasks, permissions).

ws://localhost:8080/api/v1/events

Events:

  • session.status_changed
  • task.created
  • task.status_changed
  • permission.requested
  • permission.responded

Browser/Desktop Streaming

Stream browser or desktop frames via WebSocket.

ws://localhost:8080/api/v1/streams/{stream_id}/ws?token=ttok_xxx

Error Responses

All errors follow this format:

{
  "error": {
    "code": "not_found",
    "message": "Session not found",
    "details": {
      "session_id": "sess_invalid"
    }
  }
}

Error Codes

Code HTTP Status Description
bad_request 400 Invalid request format
unauthorized 401 Invalid or missing API key
forbidden 403 Insufficient permissions
not_found 404 Resource not found
conflict 409 Resource state conflict
rate_limited 429 Too many requests
internal_error 500 Server error

Rate Limiting

Default limits:

Endpoint Limit
Session creation 10/minute
Task creation 30/minute
Log streaming 100 connections

Rate limit headers:

X-RateLimit-Limit: 10
X-RateLimit-Remaining: 7
X-RateLimit-Reset: 1705315200

Pagination

List endpoints support pagination:

GET /api/v1/sessions?limit=20&offset=40

Response includes pagination info:

{
  "items": [...],
  "total": 156,
  "limit": 20,
  "offset": 40
}