Stream agent instance updates
When you want to watch a run as it happens — waiting out a smoke test, or feeding live status into your own tooling — polling the HTTP API works, but a subscription is cheaper and faster. By the end of this page, you have a script that prints every change to one instance until you stop it.
The subscription lives on the WebSocket API. WebSocket API covers the connection and message format in full; this page is the shortest path to a working stream.
Before you start
Section titled “Before you start”- An API token for the account the instance belongs to. Create one from the Account › API tokens tab.
- The ID of the agent instance you want to watch. Find it on the Agent page › Instances tab.
- Node.js with the
wspackage installed (npm install ws). The browserWebSocketAPI cannot set theAuthorizationheader, so the example runs in Node.
-
Save this script as
stream-instance.mjs:import WebSocket from "ws";const token = process.env.PREFACTOR_API_TOKEN;const instanceId = process.env.PREFACTOR_AGENT_INSTANCE_ID;if (!token || !instanceId) {console.error("Set PREFACTOR_API_TOKEN and PREFACTOR_AGENT_INSTANCE_ID");process.exit(1);}function connect() {const ws = new WebSocket("wss://app.prefactorai.com/api/v1/ws", {headers: { Authorization: `Bearer ${token}` },});ws.on("open", () => {ws.send(JSON.stringify({jsonrpc: "2.0",id: 1,method: "agent_instances/subscribe",params: { agent_instance_id: instanceId },}),);});ws.on("message", (data) => {const message = JSON.parse(data.toString());if (message.id !== undefined) {if (message.error) {console.error("Subscribe failed:", JSON.stringify(message.error));ws.close();} else {console.log(`Subscribed to ${instanceId}`);}return;}if (message.method === "error") {console.error("Prefactor is closing the stream:", message.params.message);return;}console.log(message.method, JSON.stringify(message.params));});ws.on("close", (code) => {if (code === 1008) {console.error("Authentication is no longer valid - check the API token.");process.exit(1);}console.log(`Connection closed (${code}); reconnecting in 5s`);setTimeout(connect, 5000);});ws.on("error", (err) => {console.error("Connection error:", err.message);});}connect();The script does four things: opens the socket with the token in the
Authorizationheader, sendsagent_instances/subscribeonce the socket is open, prints each notification that arrives, and reconnects when the connection closes — unless the close means your token stopped being valid. -
Run it with your token and instance ID:
Terminal window PREFACTOR_API_TOKEN=your-token PREFACTOR_AGENT_INSTANCE_ID=your-instance-id node stream-instance.mjsYou should see
Subscribed to your-instance-idwithin a second or two. The script now waits; every change to the instance prints as anagent_instances/updatedline with the full instance details.
Verify
Section titled “Verify”With the script running, make the instance change — let the agent finish its run, or terminate the instance from the Agent instance page. A notification prints each time. If the instance is deleted, you get one agent_instances/deleted message and then nothing further.
If it didn’t work
Section titled “If it didn’t work”Connection error: Unexpected server response: 401. The token is missing, malformed, or no longer valid. Create a fresh one from the Account › API tokens tab.Subscribe failedwith code-32602. The instance ID is wrong, or the token’s account cannot see that instance. Check the ID on the Agent page › Instances tab.Subscribe failedwith code-32000. You are rate limited. The error’sretry_after_mssays how long to wait; Rate limits covers how limits are applied.- The script exits after
Prefactor is closing the stream. The token was revoked, suspended, or expired mid-stream, and Prefactor closed the connection with code1008. Re-authenticate with a valid token. Subscribed to ...prints, but no notifications arrive. Notifications only fire when the instance changes. Record a span or let the run finish; if it stays silent, check that you subscribed to the right instance ID.
Related
Section titled “Related”- WebSocket API — the full protocol: methods, notifications, error codes, and close codes.
- Rate limits — how limits are applied to socket calls.
- Instance — the lifecycle you are watching.
- Handle instance termination — how your agent finds out when Prefactor stops a run.