> ## Documentation Index
> Fetch the complete documentation index at: https://browseruse-0aece648-codex-api-v4-agent-docs.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Live messages

> Poll V4 run events incrementally to monitor progress or build a custom UI.

V4 exposes an ordered event stream for each run. Poll with `after` set to the previous response's `next_after` / `nextAfter` so you only receive new events.

Each event has `id`, `ts`, `type`, and `data`. Event types include run lifecycle updates, model calls, browser readiness, tool activity, artifacts, and completion.

<CodeGroup>
  ```python Python theme={null}
  import asyncio
  from browser_use_sdk.v4 import AsyncBrowserUse

  TERMINAL = {"completed", "failed", "cancelled"}

  client = AsyncBrowserUse()
  created = await client.runs.create("Find the top story on Hacker News")

  after = None
  while True:
      page = await client.runs.events(created.id, after=after, limit=100)
      for event in page.events:
          print(event.type, event.data)
      if page.next_after is not None:
          after = page.next_after

      status = await client.runs.status(created.id)
      if status.status.value in TERMINAL:
          break
      await asyncio.sleep(1)

  run = await client.runs.get(created.id)
  print(run.result)
  ```

  ```typescript TypeScript theme={null}
  import { BrowserUse } from "browser-use-sdk/v4";

  const TERMINAL = new Set(["completed", "failed", "cancelled"]);
  const client = new BrowserUse();
  const created = await client.runs.create({
    task: "Find the top story on Hacker News",
  });

  let after: number | undefined;
  while (true) {
    const page = await client.runs.events(created.id, { after, limit: 100 });
    for (const event of page.events) {
      console.log(event.type, event.data);
    }
    if (page.nextAfter != null) after = page.nextAfter;

    const { status } = await client.runs.status(created.id);
    if (TERMINAL.has(status)) break;
    await new Promise((resolve) => setTimeout(resolve, 1000));
  }

  const run = await client.runs.get(created.id);
  console.log(run.result);
  ```
</CodeGroup>

The status endpoint is intentionally tiny and cheap to poll. Fetch the full run only after its status is terminal.

## Cancel a run

<CodeGroup>
  ```python Python theme={null}
  cancelled = await client.runs.cancel(created.id)
  print(cancelled.status)
  ```

  ```typescript TypeScript theme={null}
  const cancelled = await client.runs.cancel(created.id);
  console.log(cancelled.status);
  ```
</CodeGroup>

Cancelling a run does not delete its session. You can send another turn with the same session ID.

## Related

* [Get run events](/cloud/api-v4/runs/get-run-events) — event response and cursor fields
* [Get run status](/cloud/api-v4/runs/get-run-status) — lightweight poll target
* [Follow-up tasks](/cloud/agent/follow-up-tasks) — continue or queue work in the same session
