> ## Documentation Index
> Fetch the complete documentation index at: https://hub.hcompany.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# List events

> Paginated list of session events.

Returns a paginated list of events for a session. Use [`/changes`](/computer-use-agents/sessions/changes) for live tailing; this endpoint is for historical pagination.

Auth is optional, so public shares are supported.

**Returns** a paginated list of `TrajectoryEvent` objects.

***

## Path parameters

<ParamField path="id" type="string" required>
  The session ID.
</ParamField>

***

## Query parameters

<ParamField query="page" type="integer" default="1">
  Page number (1-based).
</ParamField>

<ParamField query="size" type="integer" default="50">
  Items per page. Maximum: `200`.
</ParamField>

<ParamField query="sort" type="string" default="timestamp">
  Sort order. Options: `timestamp`, `-timestamp`.
</ParamField>

<ParamField query="type" type="string">
  Filter by event type, e.g. `AgentEvent` or `MetricsUpdateEvent`. See [Event shape](#event-shape) for the full list.
</ParamField>

***

## Event shape

Every event, on both this endpoint and [`/changes`](/computer-use-agents/sessions/changes), is the same envelope:

```json Event envelope theme={null}
{ "type": "AgentEvent", "data": { "...": "..." }, "timestamp": "2026-06-01T15:14:05Z" }
```

| Field       | Type   | Description                           |
| ----------- | ------ | ------------------------------------- |
| `type`      | string | The event type (see below).           |
| `data`      | object | Type-specific payload.                |
| `timestamp` | string | ISO 8601 time the event was recorded. |

### Event types (`type`)

The most common event types are below. `data` is an open JSON object whose shape varies by type, so treat this list as representative rather than exhaustive (other types such as `DelayAgentStartEvent`, `AgentRunStatusChangeEvent`, and `LiveViewUrlEvent` may appear).

| `type`                        | `data`                                            | Emitted when                                                                                                                                                                                                         |
| ----------------------------- | ------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `RequestStartEvent`           | `{}`                                              | The session request is received.                                                                                                                                                                                     |
| `RequestStartDispatchedEvent` | `{ "status": "..." }`                             | The run is dispatched for execution.                                                                                                                                                                                 |
| `AgentStartedEvent`           | `{}`                                              | The agent begins executing.                                                                                                                                                                                          |
| `AgentEvent`                  | the step event (see below)                        | The agent observes, decides, acts, or answers.                                                                                                                                                                       |
| `MetricsUpdateEvent`          | `{ "metrics": {...} }`                            | Usage and cost are rolled up. `metrics` carries `steps`, `total_cost`, `input_cost`, `output_cost`, `reasoning_cost`, and `cost_per_model[]`. Cost fields are in USD and `null` when a model's price is unavailable. |
| `ActiveStateChangeEvent`      | `{ "state": "..." }`                              | The agent's active state changes (`running`, `idle`, or `awaiting_tool_results`; the latter also carries `pending_tool_calls` for [custom tools](/computer-use-agents/custom-tools)).                                |
| `AgentCompletionEvent`        | `{ "reason": "..." }`                             | The run ends (e.g. `"finished"`).                                                                                                                                                                                    |
| `AgentErrorEvent`             | `{ "error": "...", "trace": "...", "info": ... }` | The run fails; the session moves to `failed`.                                                                                                                                                                        |

### Agent activity (`AgentEvent.data`)

The agent's step-by-step trace lives inside `AgentEvent`. Its `data` is the step event; `data.kind` tells you what happened:

| `data.kind`         | Payload (under `data`)                                                              | Meaning                                                                                                                                                             |
| ------------------- | ----------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `policy_event`      | `reasoning_content`, `content`, `tool_reqs[]`, `validation_errors[]`                | The agent's decision: its reasoning, message, and the action(s) it chose.                                                                                           |
| `observation_event` | `type`, `text`, `image`, `metadata` (see [Observation shapes](#observation-shapes)) | What the agent perceived this step.                                                                                                                                 |
| `tool_result`       | `tool_req` (`tool_name`, `args`, `id`), `result`                                    | The outcome of an action; `result` is opaque JSON.                                                                                                                  |
| `answer_event`      | `answer`                                                                            | The final answer. Same value as [`/changes`](/computer-use-agents/sessions/changes) `answer`.                                                                       |
| `error_event`       | `error`, `origin`, `tool_req?`                                                      | A recoverable error during the step (e.g. a failed or invalid action).                                                                                              |
| `message_event`     | `caller_id`, `content[]`                                                            | A user or agent message.                                                                                                                                            |
| `flow_event`        | `flow`, `origin`                                                                    | A control-flow signal such as `pause`, `resume`, or `force_answer`, including the ones you trigger via the [session controls](/computer-use-agents/sessions/pause). |

Each `tool_reqs[]` entry (and `tool_result.tool_req`) is `{ tool_name, args, id }`. `policy_event.content` and `reasoning_content` may be `null`.

Parsing a stream means switching on the outer `type`, then for `AgentEvent`, on `data.kind`:

```json AgentEvent theme={null}
{
  "type": "AgentEvent",
  "timestamp": "2026-06-01T15:14:05Z",
  "data": {
    "kind": "observation_event",
    "type": "web",
    "text": null,
    "image": { "type": "url", "source": "https://.../screenshot-7f3a.png", "media_type": "image/png" },
    "metadata": {
      "url": "https://example.com",
      "title": "Example Domain",
      "text": "# Example Domain\nThis domain is for use in illustrative examples...",
      "tabs": ["0"],
      "current_tab": "0",
      "viewport_size": [1200, 1200],
      "page_size": [1200, 3000],
      "scroll_position": [0, 0]
    }
  }
}
```

### Observation shapes

An `observation_event` is flat: `type` names the environment that produced it, `image` is the screenshot (if any), and `metadata` is that environment's snapshot, shaped by `type` (an open object, so switch on `type` to read it). The Browser emits one of two `type`s, depending on the environment's [`mode`](/computer-use-agents/browser/configuration).

The page text lives in `metadata`, not in the top-level `text`: read `metadata.text` for `web` and `metadata.page_markdown` (or `page_html`) for `textual_web`. The top-level `text` carries only occasional step notices (e.g. `[page unchanged since previous observation]`) and is `null` for most observations.

**`web`** is emitted in `visual` mode: a screenshot (top-level `image`) plus page `metadata`.

| `metadata` field  | Type   | Description                                                                     |
| ----------------- | ------ | ------------------------------------------------------------------------------- |
| `url`             | string | Current page URL.                                                               |
| `title`           | string | Page title.                                                                     |
| `text`            | string | Visible page rendered as markdown. Empty unless the mode sets `markdown: true`. |
| `tabs`            | array  | Open tab IDs.                                                                   |
| `current_tab`     | string | Active tab ID.                                                                  |
| `viewport_size`   | array  | Viewport `[width, height]` in pixels.                                           |
| `page_size`       | array  | Full page `[width, height]` in pixels.                                          |
| `scroll_position` | array  | Scroll offset `[x, y]` in pixels.                                               |
| `cursor_position` | array  | Cursor `[x, y]` in pixels, or `null`.                                           |

**`textual_web`** is emitted in `text` mode: paginated page text under `metadata`, no screenshot.

| `metadata` field | Type    | Description                                  |
| ---------------- | ------- | -------------------------------------------- |
| `url`            | string  | Current page URL.                            |
| `title`          | string  | Page title.                                  |
| `tabs`           | array   | Open tab IDs.                                |
| `current_tab`    | string  | Active tab ID.                               |
| `mode`           | string  | `"markdown"` or `"html"`.                    |
| `page_markdown`  | string  | Full page rendered as markdown.              |
| `page_html`      | string  | Full page HTML.                              |
| `text_offset`    | integer | Start character offset of the current chunk. |
| `chunk_size`     | integer | Characters per chunk.                        |
| `chunk_number`   | integer | Current chunk, 1-based.                      |
| `total_chunks`   | integer | Total chunks for the page.                   |

### Images

The `image` on an `observation_event`, and any image inside `message_event.content[]`, is `{ source, type, media_type }`. `type` is `url` for platform-served screenshots (fetch `source` with your API key) or `base64` for inline images. Images embedded in a `tool_result.result` or an `answer_event.answer` stay inline as base64 within that opaque payload, never as URLs.

***

## Examples

<CodeGroup>
  ```bash cURL theme={null}
  curl "https://agp.eu.hcompany.ai/api/v2/sessions/$SESSION_ID/events?size=10" \
    -H "Authorization: Bearer $HAI_API_KEY"
  ```

  ```python Python theme={null}
  from hai_agents import Client

  client = Client()

  page = client.sessions.list_session_events(session_id, size=10)
  for event in page.items:
      print(event.type, event.timestamp)
  ```

  ```typescript TypeScript theme={null}
  import { HaiAgentsClient } from "hai-agents";

  const client = new HaiAgentsClient();

  const page = await client.sessions.listSessionEvents({ id: sessionId, size: 10 });
  for (const event of page.items) {
    console.log(event.type, event.timestamp);
  }
  ```
</CodeGroup>
