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

# Events

> Catalog of webhook event types and the JSON payload each one carries.

Event names follow `<entity>.<action>`.

## Envelope

All events share the same outer envelope:

```json theme={null}
{
  "id": "evt_<unique>",
  "type": "<event_type>",
  "created": "<ISO 8601 timestamp>",
  "project_id": "<your project id>",
  "text": "<one-line human-readable summary>",
  "data": { "...event-specific fields..." }
}
```

The `text` field is a one-line summary of the event built from `data`. It's intended for two use cases:

* **Slack incoming webhooks** — Slack expects `{ "text": "..." }` at the top level, so registering a Slack webhook URL as your receiver renders each event as a chat message with no relay needed.
* **Logs / CLI tools** — gives an at-a-glance description without per-type formatting.

The structured data you should integrate against still lives in `data`; treat `text` as presentation only.

The headers are described in [Overview → Receive events](/webhooks/overview#2-receive-events) and signed per [Signature verification](/webhooks/signature-verification).

## Tasks

| Event            | Fired when                                                                                                                                                                          |
| ---------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `task.completed` | A task execution finishes successfully. Carries artifacts and a recording link if a session was used.                                                                               |
| `task.failed`    | A task execution fails (any reason). The `data.error.type` field tells you whether it was `automation_failure`, `invalid_credentials`, `timeout`, `agent_error`, or `system_error`. |
| `task.cancelled` | A task execution was cancelled (e.g. via the API or dashboard).                                                                                                                     |
| `task.healed`    | Anchor's self-heal produced a new task version after a failure. The notification points at the new `healed_task_version_id` so your CI/ops can review or auto-promote the fix.      |

<Tabs>
  <Tab title="completed">
    `completed`, `failed`, and `cancelled` all include the same rich-output fields:

    * `artifacts[]` — task artifacts and per-session downloads, each with a `name`, `url`, and (when known) `size` and `content_type`. Empty when nothing was captured.
    * `recording_url` — short-lived presigned link to the primary session recording. Often missing on `task.failed` because the recording uploads asynchronously; subscribe to `session.recording.ready` if you need a stable signal that the recording is ready (then fetch it via the [Recordings API](/api-reference/recordings)).
    * `session_dashboard_url` — direct link into the Anchor dashboard for the underlying session.

    ```json theme={null}
    {
      "type": "task.completed",
      "data": {
        "task_id": "tsk_4f8w9n2b-3d5a-45e7-89ab-cdef0123456f",
        "task_version_id": "tv_demo_v3",
        "execution_id": "exr_8d2c1fda-7b6e-4a3d-9c1f-0e2b3a4c5d6e",
        "session_id": "ses_8d2c1fda",
        "execution_mode": "deterministic",
        "duration_ms": 4218,
        "cost": { "amount": 0.012, "currency": "USD" },
        "output": { "value": { "order_id": "8421", "status": "confirmed" } },
        "artifacts": [
          {
            "name": "order-confirmation.pdf",
            "url": "https://api.anchorbrowser.io/v1/executions/exr_8d2c1fda/artifacts/art_1/fetch",
            "size": 38421,
            "content_type": "application/pdf"
          }
        ],
        "recording_url": "https://anchor-recordings.s3.amazonaws.com/sessions/ses_8d2c1fda/videos/recording.mp4?...",
        "session_dashboard_url": "https://app.anchorbrowser.io/sessions/ses_8d2c1fda"
      }
    }
    ```
  </Tab>

  <Tab title="failed">
    Same shape as `task.completed` plus an `error` object. The `error.type` lets you route programmatically — one of `agent_error`, `timeout`, `automation_failure`, `invalid_credentials`, `system_error`.

    ```json theme={null}
    {
      "type": "task.failed",
      "data": {
        "task_id": "tsk_4f8w9n2b",
        "task_version_id": "tv_demo_v3",
        "execution_id": "exr_8d2c1fda",
        "session_id": "ses_8d2c1fda",
        "duration_ms": 1834,
        "cost": { "amount": 0.005, "currency": "USD" },
        "error": {
          "type": "automation_failure",
          "message": "Submit button selector did not match after 30s",
          "root_cause": "Selector drift after target site redesign"
        },
        "artifacts": [],
        "recording_url": "https://anchor-recordings.s3.amazonaws.com/sessions/ses_8d2c1fda/videos/recording.mp4?...",
        "session_dashboard_url": "https://app.anchorbrowser.io/sessions/ses_8d2c1fda"
      }
    }
    ```
  </Tab>

  <Tab title="cancelled">
    Same shape as `task.completed`, with no `output` and `type: "task.cancelled"`.

    ```json theme={null}
    {
      "type": "task.cancelled",
      "data": {
        "task_id": "tsk_4f8w9n2b-3d5a-45e7-89ab-cdef0123456f",
        "task_version_id": "tv_demo_v3",
        "execution_id": "exr_8d2c1fda-7b6e-4a3d-9c1f-0e2b3a4c5d6e",
        "session_id": "ses_8d2c1fda",
        "execution_mode": "deterministic",
        "duration_ms": 2103,
        "cost": { "amount": 0.007, "currency": "USD" },
        "artifacts": [],
        "session_dashboard_url": "https://app.anchorbrowser.io/sessions/ses_8d2c1fda"
      }
    }
    ```
  </Tab>

  <Tab title="healed">
    ```json theme={null}
    {
      "type": "task.healed",
      "data": {
        "task_id": "tsk_4f8w9n2b",
        "healed_task_version_id": "tv_demo_v4",
        "source_execution_id": "exr_8d2c1fda",
        "error_explanation": "Submit button moved into a new container.",
        "fix_suggestion": "Use accessible label selector instead of XPath.",
        "confidence_score": 0.82,
        "published_as_draft": true
      }
    }
    ```
  </Tab>
</Tabs>

## Sessions

| Event                     | Fired when                                                                                                                                                                                                          |
| ------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `session.completed`       | A browser session finished cleanly. Includes duration and resource-usage breakdown (proxy bytes, network bytes, steps, screenshots, visited domains).                                                               |
| `session.failed`          | A browser session was terminated abnormally — pod gone, browser unreachable, or any other non-clean termination.                                                                                                    |
| `session.recording.ready` | The session recording finished uploading. Carries the recording duration, size, and a dashboard URL — fetch the actual recording via the [Recordings API](/api-reference/recordings) to get a fresh presigned link. |
| `intervention.requested`  | The agent paused and is waiting for a human (CAPTCHA, MFA, custom confirm). Includes a `live_view_url` for one-click takeover.                                                                                      |
| `intervention.resolved`   | The intervention was responded to (by your code or a teammate).                                                                                                                                                     |

<Tabs>
  <Tab title="session.completed">
    ```json theme={null}
    {
      "type": "session.completed",
      "data": {
        "session_id": "ses_8d2c1fda",
        "duration_ms": 27540,
        "proxy_bytes": 2581234,
        "network_bytes_total": 4891204,
        "steps": 12,
        "domains": ["example.com", "api.example.com"],
        "session_dashboard_url": "https://app.anchorbrowser.io/sessions/ses_8d2c1fda"
      }
    }
    ```
  </Tab>

  <Tab title="session.failed">
    `reason` is a coarse machine-readable category (e.g. `browser_unreachable`, `browser_pod_not_found`); use it for routing, not user-facing messages.

    ```json theme={null}
    {
      "type": "session.failed",
      "data": {
        "session_id": "ses_8d2c1fda",
        "duration_ms": 6789,
        "reason": "browser_unreachable",
        "session_dashboard_url": "https://app.anchorbrowser.io/sessions/ses_8d2c1fda"
      }
    }
    ```
  </Tab>

  <Tab title="session.recording.ready">
    Minimal payload — the event is a "recording is ready, go fetch it" signal. To download the file, call the [Recordings API](/api-reference/recordings) with the `session_id` to get a fresh presigned URL.

    ```json theme={null}
    {
      "type": "session.recording.ready",
      "data": {
        "session_id": "ses_8d2c1fda",
        "duration_ms": 45000,
        "size_bytes": 1823456,
        "session_dashboard_url": "https://app.anchorbrowser.io/sessions/ses_8d2c1fda"
      }
    }
    ```
  </Tab>

  <Tab title="intervention.requested">
    ```json theme={null}
    {
      "type": "intervention.requested",
      "data": {
        "session_id": "ses_8d2c1fda",
        "request_id": "req_4d2e9c6a",
        "message": "Solve the captcha to continue",
        "input_type": "confirm",
        "live_view_url": "https://app.anchorbrowser.io/sessions/ses_8d2c1fda"
      }
    }
    ```
  </Tab>

  <Tab title="intervention.resolved">
    Carries just `session_id` and `request_id`. The user's actual response is **never** included in the payload.

    ```json theme={null}
    {
      "type": "intervention.resolved",
      "data": {
        "session_id": "ses_8d2c1fda",
        "request_id": "req_4d2e9c6a"
      }
    }
    ```
  </Tab>
</Tabs>

## Batches

| Event             | Fired when                                                                   |
| ----------------- | ---------------------------------------------------------------------------- |
| `batch.completed` | All sessions in a batch reached a terminal state and at least one succeeded. |
| `batch.failed`    | Every session in the batch failed (or the batch produced zero sessions).     |

Both events carry the same payload shape — only the `type` and `status` field differ.

```json theme={null}
{
  "type": "batch.completed",
  "data": {
    "batch_id": "bat_92ab7de1",
    "total_requests": 25,
    "completed_requests": 25,
    "failed_requests": 0,
    "status": "completed"
  }
}
```

```json theme={null}
{
  "type": "batch.failed",
  "data": {
    "batch_id": "bat_92ab7de1",
    "total_requests": 25,
    "completed_requests": 18,
    "failed_requests": 7,
    "status": "failed"
  }
}
```

## Identity

| Event                            | Fired when                                                                                                                                                                      |
| -------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `identity.authenticated`         | An identity successfully authenticated and is now usable for subsequent runs. Use this if you need positive confirmation that a credential rotation or first-time login worked. |
| `identity.authentication_failed` | An identity-based login attempt failed. The `failure_type` field distinguishes `invalid_credentials` (the password was wrong) from `automation_failure`.                        |

<Tabs>
  <Tab title="authenticated">
    ```json theme={null}
    {
      "type": "identity.authenticated",
      "data": {
        "identity_id": "idn_acme_orders",
        "application_id": "app_acme",
        "session_id": "ses_8d2c1fda",
        "execution_id": "exr_8d2c1fda"
      }
    }
    ```
  </Tab>

  <Tab title="authentication_failed">
    ```json theme={null}
    {
      "type": "identity.authentication_failed",
      "data": {
        "identity_id": "idn_acme_orders",
        "application_id": "app_acme",
        "execution_id": "exr_8d2c1fda",
        "failure_type": "invalid_credentials",
        "error_message": "login_succeeded was false"
      }
    }
    ```
  </Tab>
</Tabs>
