AIOps Bot Platform
Console

Agent HTTP Reference

Every runtime endpoint with full request/response shapes — conversations, messages, queue, crons, auth.

The complete HTTP reference for the runtime (default http://localhost:4484). All endpoints accept auth via Authorization: Bearer <key>, X-API-Key: <key>, or ?api_key=<key>.

For WebSocket events, see Agent WebSocket events.

Health

GET /health

Base fields are always public; extra fields appear when the caller is authenticated (or when no API key is configured):

// Always present
{
  "status": "ok",
  "conversations": 0,
  "authEnabled": true,
  "timestamp": 1775845291793
}

// Additional fields when authenticated:
//   "homePath": "/data/my-agent",
//   "defaultModelProfileId": "smart",
//   "allowedModelProfileIds": ["smart", ...],
//   "signedIn": true,
//   "productId": "..."

Wait for a successful health check before sending other requests.

Use GET /health for readiness checks. (GET /health/ready is not currently implemented.)

Conversations

GET    /conversations/stats            Aggregate stats (totals, groups, time buckets)
POST   /conversations                  Create a conversation
GET    /conversations                  List / filter conversations
GET    /conversations/:id              Get conversation
PATCH  /conversations/:id              Update conversation
DELETE /conversations/:id              Delete conversation
GET    /conversations/:id/summary      Message count + latest checkpoint
POST   /conversations/:id/fork         Fork a conversation

Create a conversation (all body fields optional):

POST /conversations
{
  "title": "My Assistant",
  "workspacePath": "/home/user/project",
  "modelProfileId": "smart",
  "metadata": { "groupId": "proj-1", "groupName": "Project 1" },
  "browserProfile": "default",
  "browserHeadless": true
}

modelProfileId may also be passed as llmId or provider. All three are accepted aliases for the same field.

List conversations (pagination + filtering):

GET /conversations?limit=50&offset=0
GET /conversations?groupId=proj-1
GET /conversations?timeBucket=today
GET /conversations?category=direct|subagent
ParamDescription
limitMax number to return
offsetPagination offset (default 0)
groupIdFilter by metadata.groupId
timeBuckettoday, yesterday, last7Days, older
categorydirect (normal) or subagent

When any of groupId, timeBucket, or category is present, filtered listing is used; otherwise simple listing with limit.

Stats for dashboards:

GET /conversations/stats
{
  "total": 42,
  "directCount": 38,
  "subagentCount": 4,
  "groups": [{ "id": "proj-1", "name": "Project 1", "count": 12 }],
  "timeBuckets": { "today": 3, "yesterday": 7, "last7Days": 20, "older": 12 }
}

Patch a conversation (all fields optional):

PATCH /conversations/:id
{
  "title": "New title",
  "status": "idle|running|error",
  "modelProfileId": "smart",
  "workspacePath": "/path",
  "metadata": {},
  "browserProfile": "default",
  "browserHeadless": true
}

Fork a conversation (creates a new one copied from an existing one):

POST /conversations/:id/fork
{
  "title": "Forked chat",
  "afterMessageId": "msg_xxx",
  "beforeMessageId": "msg_yyy",
  "modelProfileId": "smart",
  "workspacePath": "/home/user/project",
  "browserProfile": "default",
  "browserHeadless": true,
  "metadata": {}
}

Use afterMessageId or beforeMessageId to control where the fork splits the history.

Messages (running the agent)

POST /conversations/:id/messages     Send a message (enqueued, returns 202)
GET  /conversations/:id/messages     List messages (cursor pagination)

List messages:

GET /conversations/:id/messages?limit=50&before=1775845291793
GET /conversations/:id/messages?since=1775845291793
GET /conversations/:id/messages?last=true
ParamDescription
limitPositive integer; max messages to return
beforeMessages with timestamp before this value (ms epoch)
sinceMessages with timestamp after this value (ms epoch)
lastWhen true, return only the most recent message

Send a message:

POST /conversations/:id/messages
{ "content": "Check the server health every 5 minutes" }

Messages may include images. images accepts HTTPS image URLs, data:image/...;base64,... URLs, or objects with { "data": "<base64>", "mimeType": "image/png" }. Images are only forwarded when the selected model advertises vision support; text-only models reject the run before the image payload is sent upstream.

POST /conversations/:id/messages
{
  "content": "Describe this screenshot",
  "images": [
    { "url": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUg...", "detail": "high" }
  ]
}

Response (202 Accepted):

{
  "accepted": true,
  "conversationId": "conv_abc123",
  "queueItem": { "id": "queue_xyz", "status": "queued" },
  "status": "queued"
}

The agent processes asynchronously — track progress over WebSocket.

Queue management

GET    /conversations/:id/queue                List queue items
DELETE /conversations/:id/queue                Bulk remove items (body: { "ids": [...] })
DELETE /conversations/:id/queue/:qid           Remove a single queue item
POST   /conversations/:id/cancel               Cancel current run
POST   /conversations/:id/interrupt            Cancel and prepend a new message

List queue items supports the same cursor params as messages plus includeTerminal:

GET /conversations/:id/queue?limit=50&since=...&includeTerminal=true
ParamDescription
limitPositive integer; max items to return
beforeItems with timestamp before this value
sinceItems with timestamp after this value
includeTerminalWhen true, include completed/failed items (excluded by default)

Bulk delete:

DELETE /conversations/:id/queue
{ "ids": ["queue_a", "queue_b"] }
// → { "removed": ["queue_a", "queue_b"], "removedCount": 2 }

Cancel and interrupt accept optional control flags:

POST /conversations/:id/cancel
{ "clearQueued": true }   // optional — also drop pending queued items

POST /conversations/:id/interrupt
{
  "content": "Actually, do this instead",
  "dropQueued": true,        // optional — drop pending queued items
  "images": []               // optional — same image format as messages
}

Compaction & checkpoints

The runtime auto-compacts long conversations to fit the context window (controlled by compactionSoftThreshold / compactionHardThreshold in runtime.json). Each compaction produces a checkpoint:

GET  /conversations/:id/checkpoints           List compaction checkpoints
GET  /conversations/:id/compaction-events     List compaction event records
POST /conversations/:id/compact               Trigger manual compaction
GET  /conversations/:id/compaction-events?limit=20&before=...&since=...
POST /conversations/:id/compact               // → { "checkpoint": { "id": "ckpt_..." } }

Subagents

Conversations can spawn isolated subagent runs (e.g. via the delegate tool). Subagents run in their own context and cannot re-delegate (prevents infinite recursion).

GET /conversations/:id/subagents                  List subagents of a conversation
GET /conversations/:id/subagents/:subagentId      Get a subagent + its messages

The detail endpoint returns { "conversation": {...}, "messages": [...] } for the subagent.

Cron jobs

POST   /crons                    Create a cron job
GET    /crons                    List all cron jobs
GET    /crons/:id                Get a cron job
PATCH  /crons/:id                Update a cron job
DELETE /crons/:id                Delete a cron job
POST   /crons/:id/toggle         Enable/disable a cron job
POST   /crons/:id/run            Run a cron job immediately

Create a recurring task (new conversation each time):

POST /crons
{
  "name": "Health Check",
  "content": "Check if https://example.com is up and report the status code",
  "schedule": "*/5 * * * *",
  "workspacePath": "/home/user/project",
  "modelProfileId": "smart",
  "titlePrefix": "Health Check",
  "enabled": true
}

Create a recurring task in an existing conversation:

POST /crons
{
  "name": "Daily Summary",
  "conversationId": "conv_abc123",
  "content": "Summarize what happened today",
  "schedule": "0 9 * * *"
}
Body fieldDescription
contentRequired. Message sent when the job fires
scheduleRequired. Standard 5-field cron expression
nameHuman-readable label
conversationIdRun in an existing conversation; omit to create a new one each fire
modelProfileIdModel to use (alias: llmId)
workspacePathWorkspace for newly-created conversations
titlePrefixPrefix applied to auto-created conversation titles
enabledDefault true; set false to create paused

The same fields are accepted on PATCH /crons/:id (all optional). Run on demand:

POST /crons/:id/run
// → 200 { "status": "started", "accepted": true, ... }
// → 202 if already running: { "status": "already_running", "accepted": true }

Authentication (cloud)

GET    /auth/status               Check cloud auth status (auto-refreshes expiring tokens)
POST   /auth/session              Exchange bootstrap token for session
POST   /auth/dev-session          Exchange dev credentials for session
DELETE /auth/session              Sign out
GET    /entitlements/cache        Read cached entitlements (plan, models, usage)

GET /auth/status transparently refreshes the access token if it's within 60s of expiry; permanent failures (expired/revoked) clear the session, while transient failures (network/5xx) leave it intact.

Observability

GET /workspace-sync-audit?limit=50   Workspace sync audit log (trigger, etag, file counts)
GET /events/recent?since=<seq>       Recent buffered runtime events (HTTP fallback for WS)

GET /events/recent returns events from the in-memory buffer (the same buffer WebSocket clients replay from). Pass since=<seq> for events after a sequence number, or omit for all buffered events:

GET /events/recent
{ "events": [{ "seq": 42, "payload": "{\"type\":\"message.delta\",...}" }] }

LLMs

GET /llms                         List available LLM models (refreshes the in-memory catalog)

Agent tools

During a run the agent can use: bash (shell), browser (web automation/screenshots), cron (scheduling), and delegate (spawn an isolated subagent that cannot re-delegate). It can self-manage cron jobs — saying "check my site every 10 minutes" is enough.