---
title: Event reference
description: Every event kind a session log can carry, and what each one carries with it.
sidebar:
  order: 3
---

Every event has a sequence number, a kind, and a payload. The kind is what the SSE `event` field carries; the payload is what `data` holds.

## Session and messages

| Kind | Payload |
| --- | --- |
| `session_created` | `agent_id`, `agent_version_id` — the version this session bound. |
| `message_user` | `message`, `source` (`client`, `steer`, or `external`). |
| `message_assistant` | `message`. |
| `error` | `message`. A session-level error, not a run outcome. |

`source` distinguishes input the end user typed (`client`) from input steered in mid-run (`steer`) and from input the platform injected on behalf of a background producer (`external`).

## Runs

| Kind | Payload |
| --- | --- |
| `run_queued` | `run_id`. |
| `run_started` | `run_id`. |
| `run_completed` | `run_id`. |
| `run_failed` | `run_id`, `error`. |
| `run_cancelled` | `run_id`. |

## Tools

| Kind | Payload |
| --- | --- |
| `tool_call` | `call_id`, `name`, `arguments`. |
| `tool_result` | `call_id`, `content`, `is_error`. |

## Approvals

| Kind | Payload |
| --- | --- |
| `approval_requested` | `call_id`, `server`, `tool`, `arguments`, `args_hash`. |
| `approval_resolved` | `call_id`, `decision`, `deny_message?`, `resolved_by?`. |

See [Approvals](/guides/approvals) for how to settle one.

## Clients

| Kind | Payload |
| --- | --- |
| `client_registered` | `client_id`, `name`, `lifetime`, `tools`. |
| `client_tools_updated` | `client_id`, `tools` — the whole list, always. |
| `client_left` | `client_id`, `reason` (`departed` or `timed_out`). |
| `client_tool_dispatched` | `call_id`, `client_id`, `tool`, `arguments`. |
| `client_tool_acked` | `call_id`, `client_id`. |
| `client_tool_failed` | `call_id`, `client_id`, `reason`. |

`name` on `client_registered` is the **assigned** name, not the requested one — if the session had already spent the name it asked for, a counter was appended. That assigned name is what the model sees the client's tools under, and no two registrations in a session ever share it.

`tool` on `client_tool_dispatched` is the raw name the client declared, not the namespaced one the model called. It is the event a client watches, so it names the tool the way the client knows it.

## Engine-private state

| Kind | Payload |
| --- | --- |
| `custom` | `kind`, `payload`. |

Opaque to the runtime and to you: an engine uses it to checkpoint its own state on the log. The `kind` inside the payload is the engine's own (`pi.snapshot`, say). Skip these when rendering a conversation.

:::note
The event vocabulary is versioned. New kinds can be added, so treat an unrecognized kind as something to ignore rather than something to fail on.
:::
