Skip to content

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.

  • 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 ws package installed (npm install ws). The browser WebSocket API cannot set the Authorization header, so the example runs in Node.
  1. 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 Authorization header, sends agent_instances/subscribe once the socket is open, prints each notification that arrives, and reconnects when the connection closes — unless the close means your token stopped being valid.

  2. 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.mjs

    You should see Subscribed to your-instance-id within a second or two. The script now waits; every change to the instance prints as an agent_instances/updated line with the full instance details.

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.

  • 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 failed with 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 failed with code -32000. You are rate limited. The error’s retry_after_ms says 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 code 1008. 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.