> ## Documentation Index
> Fetch the complete documentation index at: https://docs.ag-ui.com/llms.txt
> Use this file to discover all available pages before exploring further.

# The Event Model

> The event envelope, its general fields, the identifiers, and the map of every event — 1.0

The base protocol is what every implementation speaks regardless of which
features it uses:

* **The event model** — this page: the envelope every event shares, its general
  fields, and the identifiers that tie events together.
* **[Run input](https://docs.ag-ui.com/spec/1.0/basic/run-input.md)** — the one message that travels
  the other way.
* **[Metadata](https://docs.ag-ui.com/spec/1.0/basic/metadata.md)** — the open channel on everything,
  and how it merges.
* **[Capabilities](https://docs.ag-ui.com/spec/1.0/basic/capabilities.md)** — what an agent declares
  about itself before a run, and what a declaration obliges.
* **[Event patterns](https://docs.ag-ui.com/spec/1.0/basic/patterns.md)** — the ways events compose
  into streams.
* **[Transports](https://docs.ag-ui.com/spec/1.0/basic/transports.md)** — how streams are framed and
  delivered.
* **[Processing model](https://docs.ag-ui.com/spec/1.0/basic/processing.md)** — what a consumer does
  with material it does not recognise.
* **[Versioning and compatibility](https://docs.ag-ui.com/spec/1.0/basic/versioning.md)** — talking to
  an older or newer peer.

All implementations MUST support the event model and the event patterns. The
[event families](https://docs.ag-ui.com/spec/1.0/events.md) beyond the run lifecycle are features: a
producer emits the ones it has something to say with.

## Events

Every event is a JSON object sharing one envelope, defined by the schema as
`BaseEvent`:

* `type` — REQUIRED. The discriminator, one of the 31 values of `EventType`.
  Every rule in this specification attaches to events through this field.
* `timestamp` — OPTIONAL. When the event was created. Informational: a consumer
  MUST NOT use it to order events — arrival order is the protocol's order. By
  convention the unit is milliseconds since the Unix epoch.
* `rawEvent` — OPTIONAL. The provider-native event this one was translated
  from, carried verbatim. A consumer MUST NOT derive protocol behaviour from
  it.
* `metadata` — OPTIONAL. See [General fields](#general-fields).

Events that can belong to a subagent's work additionally carry an OPTIONAL
`subagentRunId` (the schema's `Attributable`); the
[subagent rules](https://docs.ag-ui.com/spec/1.0/events/subagents.md) govern it. Run-scoped events —
`RUN_STARTED`, `RUN_FINISHED`, `RUN_ERROR`, `MESSAGES_SNAPSHOT` — describe the
run or the conversation as a whole and carry no attribution.

## General fields

### `metadata`

The open channel on everything: open by key, any JSON value under a key,
accumulated across the events that build an item — key by key, last write
winning, no recursion — with per-family merge targets and a reserved `ag-ui`
key. It has its own page: [Metadata](https://docs.ag-ui.com/spec/1.0/basic/metadata.md).

### Absent means absent

An optional field that has no value MUST be omitted rather than sent as `null`.

This applies to every optional field, including fields that carry arbitrary JSON
such as `rawEvent`, `RUN_FINISHED.result`, and `forwardedProps`. A whole
optional field set to `null` MUST be omitted. A required JSON payload can be
`null`, for example `CUSTOM.value` or `STATE_SNAPSHOT.snapshot`.

> [!NOTE]
>
> This is not a style preference. A consumer that must accept both spellings
> has to treat them as equal everywhere, and every such tolerance is permanent
> once shipped. The protocol carries the one spelling every implementation can
> represent.

A `null` *value under an open-by-key object* — a metadata value, something
inside `state` — is data and MUST be preserved. Only a `null` standing in for a
whole absent field is prohibited.

Where the protocol has already shipped tolerance for a `null` in an optional
position, it is handled by a compatibility shim rather than by this rule. See
[Versioning and compatibility](https://docs.ag-ui.com/spec/1.0/basic/versioning.md).

## Identifiers

* `threadId` identifies a conversation. It is minted by the application and is
  stable across runs.
* `runId` identifies one run. It MUST NOT be reused for another run on the same
  thread.
* `messageId` identifies a message. It crosses run boundaries — a snapshot in a
  later run MAY restate a message by its id — so it MUST be unique within its
  thread.
* `toolCallId` identifies one tool call, and ties its result and any interrupt
  concerning it back to it.
* `subagentRunId` is an opaque handle for one subagent *invocation*, not a
  reusable name for a subagent definition: two invocations of the same subagent
  carry two different values.

All identifiers are opaque strings: a consumer MUST NOT parse structure out of
them.

## The events

Thirty-one event types, in eight families:

| Family | Events | Pattern |
| - | - | - |
| [Runs and steps](https://docs.ag-ui.com/spec/1.0/events/lifecycle.md) | `RUN_STARTED` `RUN_FINISHED` `RUN_ERROR` `STEP_STARTED` `STEP_FINISHED` | lifecycle |
| [Text messages](https://docs.ag-ui.com/spec/1.0/events/text-messages.md) | `TEXT_MESSAGE_START` `TEXT_MESSAGE_CONTENT` `TEXT_MESSAGE_END` `TEXT_MESSAGE_CHUNK` | [streaming](https://docs.ag-ui.com/spec/1.0/basic/patterns/streaming.md) |
| [Tool calls](https://docs.ag-ui.com/spec/1.0/events/tool-calls.md) | `TOOL_CALL_START` `TOOL_CALL_ARGS` `TOOL_CALL_END` `TOOL_CALL_CHUNK` `TOOL_CALL_RESULT` | [streaming](https://docs.ag-ui.com/spec/1.0/basic/patterns/streaming.md) |
| [Reasoning](https://docs.ag-ui.com/spec/1.0/events/reasoning.md) | `REASONING_START` `REASONING_END` `REASONING_MESSAGE_START` `REASONING_MESSAGE_CONTENT` `REASONING_MESSAGE_END` `REASONING_MESSAGE_CHUNK` `REASONING_ENCRYPTED_VALUE` | [streaming](https://docs.ag-ui.com/spec/1.0/basic/patterns/streaming.md) |
| [State](https://docs.ag-ui.com/spec/1.0/events/state.md) | `STATE_SNAPSHOT` `STATE_DELTA` `MESSAGES_SNAPSHOT` | [snapshot–delta](https://docs.ag-ui.com/spec/1.0/basic/patterns/snapshots.md) |
| [Activity](https://docs.ag-ui.com/spec/1.0/events/activity.md) | `ACTIVITY_SNAPSHOT` `ACTIVITY_DELTA` | [snapshot–delta](https://docs.ag-ui.com/spec/1.0/basic/patterns/snapshots.md) |
| [Subagents](https://docs.ag-ui.com/spec/1.0/events/subagents.md) | `SUBAGENT_STARTED` `SUBAGENT_FINISHED` `SUBAGENT_ERROR` | lifecycle |
| [Passthrough](https://docs.ag-ui.com/spec/1.0/events/passthrough.md) | `RAW` `CUSTOM` | standalone |

## Schema

The full structure of the protocol is defined by the JSON Schema at
[`/spec/1.0/schema.json`](https://docs.ag-ui.com/spec/1.0/schema.json). It is the source of
truth: the TypeScript, Python and .NET models are generated from it, and where
this document mentions a field it is naming something the schema defines, never
restating its shape.

The schema deliberately does not say what this document says: ordering,
lifecycle, attribution, error handling and compatibility are behavioural, and
the schema cannot express them. If the two ever disagree about structure, the
schema wins and this document has a bug.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.