WebSocket API
Xagent exposes WebSocket endpoints for real-time task execution and monitoring — streaming trace events, chat responses, and status updates as a task runs.
Base URL
wss://sg-origin.cloud.xagent.co # Singapore
wss://au-origin.cloud.xagent.co # AustraliaAuthentication
Connections authenticate with a token passed as a query parameter:
const ws = new WebSocket(
`wss://sg-origin.cloud.xagent.co/ws/chat/${taskId}?token=${token}`
);
ws.onmessage = (event) => {
const data = JSON.parse(event.data);
handleEvent(data);
};Chat Endpoint
wss://<your-regional-host>/ws/chat/{task_id} — real-time communication for one task: execution, status, and manual intervention. A second endpoint, wss://<your-regional-host>/ws/build/preview, streams agent previews on the Build page without persisting anything.
Client Messages
Messages you send to the server, each with a type:
{ "type": "chat", "message": "Your question here" }
{ "type": "execute_task", "query": "Task description" }
{ "type": "intervention", "step_id": "step_123", "action": "approve" }
{ "type": "pause_task" }
{ "type": "resume_task" }
{ "type": "status_request" }Server Events
Messages the server streams back. Trace events carry the fine-grained execution timeline; other types carry chat, status, and errors:
{ "type": "chat", "message": "Agent response", "step_id": "step_123" }
{ "type": "status", "status": "running", "progress": 0.5 }
{ "type": "error", "message": "Error description" }Trace events use a richer shape — see the Trace Events reference for the full catalogue.
Resume is refused while a question is unanswered
Sending { "type": "resume_task" } for a task the agent has paused itself on with an unanswered question (rather than one you paused) now returns { "type": "error", "message": "This task has an unanswered question; answer it before resuming." } instead of resuming. Answer the pending question first — see the waiting_for_user status in the Workspace SDK reference.
Pausing an already-paused task
Sending { "type": "pause_task" } for a task whose status is already paused now returns a distinct { "type": "error", "message": "Task is already paused" }, instead of the generic No live execution found to pause shown when the task is not running at all.
Error Codes
| Code | Meaning |
|---|---|
4001 | Authentication required |
4002 | Invalid token |
4003 | Task not found |
1000 | Normal closure |
1001 | Endpoint going away (e.g. server restart) |
1006 | Abnormal closure — reconnect with backoff |
Reconnect gracefully
On an unexpected close, reconnect with increasing backoff and reset the counter once a connection succeeds. Queue outbound messages while disconnected and flush them on reopen.