HTTP API

The daemon exposes a RESTful HTTP API on 127.0.0.1:9999 using the v3 protocol. All endpoints except /v3/health require Bearer token authentication.

Authentication

Include the daemon token in the Authorization header on every request:

http
Authorization: Bearer opta_dk_...

The token is read from ~/.config/opta/daemon/state.json. If the token is missing or incorrect, the daemon returns 401 Unauthorized.

Token source
The CLI reads the token automatically. If you are building a custom client, read the token field from the state file.

Health & Metrics

GET/v3/health

Liveness probe. Returns daemon status, protocol version, and uptime in seconds. No authentication required.

Response

{
  "status": "ok",
  "version": "3.0.0",
  "uptime": 842
}
GET/v3/metricsAuth required

Returns daemon performance metrics including active sessions, total turns, memory usage, and tool worker pool status.

Response

{
  "activeSessions": 2,
  "totalTurns": 147,
  "memoryMB": 64,
  "toolWorkers": { "active": 3, "max": 8, "queued": 0 }
}

Sessions

Create Session

POST/v3/sessionsAuth required

Creates a new AI session. Returns the session ID and initial snapshot.

Parameters

modelstringModel identifier to use for inference
systemPromptstringOptional system prompt override
mode"chat" | "do"Session mode. 'do' enables autonomous tool execution

Response

{
  "sessionId": "sess_abc123",
  "mode": "chat",
  "model": "qwen3-30b-a3b",
  "createdAt": "2026-03-01T10:00:00.000Z"
}

Get Session

GET/v3/sessions/:idAuth required

Returns the full session detail including mode, model, turn count, and current status.

Parameters

idstringrequiredSession ID

Response

{
  "sessionId": "sess_abc123",
  "mode": "chat",
  "model": "qwen3-30b-a3b",
  "status": "idle",
  "turns": 5,
  "createdAt": "2026-03-01T10:00:00.000Z",
  "lastActivityAt": "2026-03-01T10:05:30.000Z"
}

Submit Turn

POST/v3/sessions/:id/turnsAuth required

Submits user input to the session, starting a new turn. The daemon queues the turn and begins inference. Use the events endpoint or WebSocket to stream results.

Parameters

idstringrequiredSession ID
contentstringrequiredUser message text
attachmentsAttachment[]File references to include as context

Response

{
  "turnId": "turn_001",
  "status": "queued",
  "seq": 42
}

Poll Events

GET/v3/sessions/:id/eventsAuth required

Long-polls for session events. Returns a batch of events newer than the specified sequence number. Use this for HTTP-only clients that cannot use WebSocket.

Parameters

idstringrequiredSession ID
afterSeqnumberReturn events with seq > this value. Use 0 for all events.
timeoutnumberLong-poll timeout in milliseconds (default 30000)

Response

{
  "events": [
    { "event": "turn.start", "seq": 43, "data": { "turnId": "turn_001" } },
    { "event": "turn.token", "seq": 44, "data": { "token": "Hello" } },
    { "event": "turn.token", "seq": 45, "data": { "token": " world" } }
  ],
  "lastSeq": 45
}

Cancel Session

POST/v3/sessions/:id/cancelAuth required

Cancels the currently running turn in the session. Emits a session.cancelled event. If no turn is active, returns 200 with no effect.

Parameters

idstringrequiredSession ID

Response

{ "cancelled": true }

Permissions

POST/v3/sessions/:id/permissions/:requestIdAuth required

Resolves a pending permission request. When the daemon encounters a tool call that requires user approval, it pauses and emits a permission.request event. This endpoint approves or denies the request.

Parameters

idstringrequiredSession ID
requestIdstringrequiredPermission request ID from the permission.request event
approvedbooleanrequiredWhether to approve or deny the tool call

Response

{ "resolved": true }
Timeout behavior
If a permission request is not resolved within 5 minutes, the daemon automatically denies it and emits a permission.resolved event with approved: false.

Operations

Operations are pre-defined daemon commands (model management, config changes, diagnostics) that can be triggered via the API without creating a chat session.

List Operations

GET/v3/operationsAuth required

Lists all available operations with their parameter schemas.

Response

{
  "operations": [
    {
      "id": "model.load",
      "description": "Load a model into LMX",
      "params": { "model": "string" }
    },
    {
      "id": "model.unload",
      "description": "Unload the current model",
      "params": {}
    }
  ]
}

Execute Operation

POST/v3/operations/:idAuth required

Executes a named operation. The response depends on the operation type.

Parameters

idstringrequiredOperation ID (e.g. model.load)
paramsobjectOperation-specific parameters

Response

{
  "success": true,
  "result": { "model": "qwen3-30b-a3b", "loadTimeMs": 2340 }
}

Error Format

All error responses follow a consistent JSON format:

json
{
  "error": {
    "code": "SESSION_NOT_FOUND",
    "message": "No session with id 'sess_xyz'"
  }
}

Common error codes:

  • UNAUTHORIZED — Missing or invalid Bearer token (401)
  • SESSION_NOT_FOUND — Session ID does not exist (404)
  • TURN_IN_PROGRESS — Cannot submit a new turn while one is active (409)
  • LMX_UNREACHABLE — Cannot connect to the LMX inference server (502)
  • INTERNAL_ERROR — Unexpected daemon error (500)