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     # Australia

Authentication

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

CodeMeaning
4001Authentication required
4002Invalid token
4003Task not found
1000Normal closure
1001Endpoint going away (e.g. server restart)
1006Abnormal 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.

Next Steps