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

# The Event object

> One thing that happened, in one envelope, whichever transport carries it.

```json theme={null}
{
  "id": "evt_9f2c81b4d7e6",
  "type": "run.completed",
  "created_at": "2026-08-30T12:00:04Z",
  "seq": 4,

  "origin": "agent",
  "source": { "kind": "run", "id": "7c9e6679-7425-40de-944b-e07fc1f90ae7" },
  "parent": null,

  "context": {
    "workspace_id": "0f3a8821-…",
    "connection_id": "c4b1…",
    "agent_id": "a91e…",
    "agent_key": "support",
    "thread_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
    "subject_ref": "user_9f2"
  },

  "run_id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
  "thread_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",

  "data": { }
}
```

## Attributes

<ResponseField name="id" type="string" required>
  `evt_` plus hex. Stable across retries and replays — use it to deduplicate.
</ResponseField>

<ResponseField name="type" type="string" required>
  One of the types below.
</ResponseField>

<ResponseField name="source" type="object" required>
  The unit of work this is about: `{ kind, id }`. `kind` is `run` for agent work, `request` for a bare product call, `endpoint` for a test delivery.
</ResponseField>

<ResponseField name="parent" type="object">
  The enclosing unit of work, when there is one. Null on everything delivered today, because a nested unit's terminal event is not sent — the outer one already reports it.
</ResponseField>

<ResponseField name="origin" type="string" required>
  Which surface produced the work: `agent`, `api`, `mcp`, `console` or `playground`.
</ResponseField>

<ResponseField name="seq" type="integer">
  Orders events within one `source`. Null where there is no ordering to express, such as a product request.
</ResponseField>

<ResponseField name="context" type="object" required>
  Tenancy and routing: `workspace_id`, and where they apply `connection_id`, `agent_id`, `agent_key`, `thread_id`, `subject_ref`, `product`. A key is omitted rather than sent as null — a run whose agent uses no connection has no `connection_id`.
</ResponseField>

<ResponseField name="run_id" type="uuid">
  Compatibility alias for `source.id` on run events. Present so existing SDK code keeps working; new code should read `source`.
</ResponseField>

<ResponseField name="thread_id" type="uuid">
  Compatibility alias for `context.thread_id`. Also names the realtime channel.
</ResponseField>

<ResponseField name="data" type="object">
  Type-specific payload. Omitted entirely when the endpoint is set to send ids only.
</ResponseField>

## Types

| Type | `data` carries | Webhook |
| - | - | - |
| `run.started` | `agent` | yes |
| `run.completed` | `state`, `cost_credits`, `reason` | yes |
| `run.failed` | `error` | yes |
| `elicitation.requested` | the question | yes |
| `action.proposed` | `tool_call_id`, `patch_ref`, `args` | yes |
| `write.confirmation_requested` | `tool_call_id`, `patch_ref`, `summary`, `risk` | yes |
| `handoff.requested` | handoff payload | yes |
| `message.completed` | the final assistant message | yes |
| `tool_call.started` | `name`, `args` | yes |
| `tool_call.completed` | `name`, `status`, `result` | yes |
| `plan.updated` | `steps` | yes |
| `extract.completed` | the extract result | yes |
| `extract.failed` | `error` | yes |
| `message.delta` | a content fragment | no |
| `message.block` | `role`, `content`, `parts`, `seq` | no |

`tool_call.completed` reports `status` as `ok`, `failed`, `declined` or `denied` — `declined` meaning a held write was rejected, `denied` meaning policy refused the call.

Arguments and results are redacted before an event is built, per the patch's declaration.

## Transports

Every type reaches [realtime](/api-reference/realtime) subscribers on `private-thread-{thread_id}`, except the ones with no thread — a bare product call like `extract.completed` has no conversation to publish into.

All but `message.delta` and `message.block` are deliverable to [webhook endpoints](/api-reference/webhook-endpoint). Streaming fragments and render blocks stay realtime-only: one is a poor fit for HTTP, the other is something a UI draws.

Product events fire only when you call the product directly. An extract that runs inside an agent is a step of that run, and the run's own events already report it.


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