Agent API: Getting Started
The minimal API to start a conversation, send a message, and stream the response.
The runtime exposes a local HTTP + WebSocket API (default http://localhost:4484).
This is the minimal surface to start a conversation, send a message, and stream
the reply. Once this clicks, you've got most of the platform.
All endpoints accept auth via Authorization: Bearer <key>, X-API-Key: <key>,
or ?api_key=<key> (also used in WebSocket URLs).
The core model (read this first)
Messaging is asynchronous. There is no "give me the answer" request:
POST /conversations/:id/messages→ returns202with aqueueItemimmediately.- The agent processes in the background.
- You receive the response over WebSocket — streaming token deltas, then a
run.completedevent when done.
Your app --POST /messages--> runtime (202 Accepted, queueItem)
^ |
| | processes async (LLM + tools)
<--WebSocket events-------------+
message.delta ... run.completed
You can run many conversations in parallel; each streams independently.
1. Confirm it's up
GET /health
{
"status": "ok",
"conversations": 0,
"authEnabled": true,
"timestamp": 1775845291793
}
Poll this until 200 { "status": "ok" }.
2. Authenticate (once)
Exchange a bootstrap token (issued by the dashboard) for a session:
POST /auth/session
{
"cloudBaseUrl": "https://169.63.180.31.sslip.io",
"bootstrapToken": "..."
}
// → { "signedIn": true, "productId": "...", "deviceId": "...", "entitlements": {...} }
Check status anytime with GET /auth/status.
3. Create a conversation
POST /conversations
{ "title": "My Assistant", "workspacePath": "/home/user/project" }
// → 201 { "id": "conv_abc123", ... }
workspacePath is optional but powerful — when set, the agent loads that
project's AGENTS.md into its system prompt and operates in that directory.
4. Send a message
POST /conversations/conv_abc123/messages
{ "content": "Check the server health every 5 minutes" }
// → 202
{
"accepted": true,
"conversationId": "conv_abc123",
"queueItem": { "id": "queue_xyz", "status": "queued" },
"status": "queued"
}
The request returns immediately. Move on to the WebSocket.
5. Stream the response
const ws = new WebSocket(
`ws://localhost:4484/conversations/conv_abc123/ws?api_key=${KEY}`,
);
ws.onmessage = (event) => {
const evt = JSON.parse(event.data);
switch (evt.type) {
case "run.started":
/* agent began thinking */ break;
case "message.delta":
appendToUi(evt.data.delta);
break; // stream tokens
case "message.created":
/* a full message was saved */ break;
case "run.completed":
markComplete();
break; // done!
case "run.failed":
showError(evt.data);
break;
}
};
For a basic chat UI you only need run.started, message.delta,
message.created, run.completed, and run.failed. A global stream at
ws://localhost:4484/ws delivers events for all conversations if you manage
many.
Changing direction mid-run
- Cancel the current run:
POST /conversations/:id/cancel - Interrupt — cancel and immediately inject a new message:
POST /conversations/:id/interruptwith{ "content": "..." }
Reading history
GET /conversations/:id/messages # full history
GET /conversations/:id/messages?last=true # just the latest message
Scheduled tasks (optional)
The agent can create cron jobs itself via its tools ("check my site every 10 minutes" is enough), or you can make one directly:
POST /crons
{
"name": "Daily Summary",
"content": "Summarize what happened today",
"schedule": "0 9 * * *",
"conversationId": "conv_abc123"
}
schedule is a standard 5-field cron expression. Omit conversationId to spin
up a fresh conversation each time it fires.
The full flow (copy-paste)
// 1. Spawn + wait for health (omitted — see Deployment)
// 2. Authenticate
await fetch("http://localhost:4484/auth/session", {
method: "POST",
headers: authHeaders(),
body: JSON.stringify({
cloudBaseUrl: "https://169.63.180.31.sslip.io",
bootstrapToken: "...",
}),
});
// 3. Create a conversation
const conv = await fetch("http://localhost:4484/conversations", {
method: "POST",
headers: authHeaders(),
body: JSON.stringify({
title: "Assistant",
workspacePath: "/path/to/workspace",
}),
}).then((r) => r.json());
// 4. Send a message (async — returns 202 immediately)
await fetch(`http://localhost:4484/conversations/${conv.id}/messages`, {
method: "POST",
headers: authHeaders(),
body: JSON.stringify({ content: "Hello, what can you do?" }),
});
// 5. Stream the response
const ws = new WebSocket(
`ws://localhost:4484/conversations/${conv.id}/ws?api_key=${KEY}`,
);
ws.onmessage = (event) => {
const evt = JSON.parse(event.data);
if (evt.type === "message.delta") appendToResponse(evt.data.delta);
if (evt.type === "run.completed") markComplete();
};
Where next
- Every endpoint with full request/response shapes → Agent HTTP reference
- Every event type, reconnection/replay, heartbeats → Agent WebSocket events