---
title: Automation Events | Tabstack
description: Orientation for consuming the Server-Sent Event stream from /v1/automate, covering ordering, conditional events, filtering, and consumption patterns.
---

The `/v1/automate` endpoint streams Server-Sent Events (SSE). Each event has a string `event` name and a typed `data` payload; the SDKs expose the stream as a discriminated union (`AutomateEvent` in TypeScript, matched via `event.event` in Python), so `switch`/`match` on the event name narrows the payload for you.

This page covers what the API reference can’t: the order events arrive in, which ones only fire under specific conditions, what you probably want to filter out in production, and a starter consumption pattern. For the complete list of events and their payload schemas, see the [API reference](/api/resources/agent/methods/automate/index.md).

---

## Typical event ordering

A simple task (extract the title of a single page, no form interactivity, no extraction-heavy work) produces roughly this sequence:

1. `task:trace_context`. First event after task acceptance; carries a W3C `traceId` for the run. Skipped if tracing is disabled (self-host / no active span).

2. `cdp:endpoint_connected`. Browser session attached.

3. `agent:processing` / `agent:status`. The agent builds a task plan.

4. `browser:navigated`. The initial page loads.

5. `task:started`. Execution begins; the payload echoes the plan and `successCriteria`.

6. A per-iteration loop:

   - `agent:step`. Iteration begins.
   - `agent:processing`. The agent is thinking.
   - `agent:reasoned`. Reasoning output for this step.
   - `agent:action`. The action being taken (e.g. `extract`, `click`, `done`).
   - `agent:processing`. Post-action processing.

7. `task:validated`. The completion check passes. See the [API reference](/api/resources/agent/methods/automate/index.md) for the payload fields.

8. `task:completed`. The agent decides the task is done (fires inside the agent loop).

9. `complete`. Final result event: `finalAnswer`, `stats` (action count, iteration count, duration), `success`, and an optional structured `error`.

10. `done`. Stream terminator (empty payload today, reserved for future metadata).

Longer tasks repeat step 6 multiple times and may interleave `browser:navigated`, `browser:action_started`/`browser:action_completed`, `browser:screenshot_captured`, and `agent:waiting`. The first five events and the last four are stable landmarks; everything between them is per-iteration noise you can filter down to what you actually want to display.

`complete`, `done`, and the top-level `error` event are full members of the typed `AutomateEvent` union (added in SDK 2.6.0), so an exhaustive `switch` narrows their payloads the same way it does for any other event.

---

## Conditional events

These only fire under specific conditions:

- `interactive:form_data:request` / `interactive:form_data:error`. Only when `interactive: true` is set. See the [Interactive Mode guide](/guides/interactive-mode/index.md) for the request/response cycle.
- `agent:extracted`. Fires when the task performs structured extraction.
- `task:validation_error`. Emitted if the completion check fails; rare on well-formed tasks.
- `task:aborted`. The task was terminated early.
- `browser:screenshot_captured_image`. Fires alongside `browser:screenshot_captured` when the screenshot payload is actually attached; large events, so the image variant is separate from the lightweight capture notice.
- `browser:reconnected`. The underlying browser session was re-established (e.g. after a transient disconnect).
- `ai:generation` / `ai:generation:error`. LLM-call instrumentation around agent reasoning steps.
- `cdp:endpoint_cycle`. The CDP endpoint was rotated.
- `task:metrics` / `task:metrics_incremental`. Metric emissions for tasks when metrics are enabled.

Payload shapes for each are in the [API reference](/api/resources/agent/methods/automate/index.md).

---

## Events to filter in production

Filtering is client-side. The server always emits these.

- `system:debug_compression`, `system:debug_message`. Internal diagnostics; nothing end-user-facing.
- `browser:screenshot_captured_image`. The payload carries image bytes; drop it unless you actually render screenshots.
- `agent:processing`. High frequency. If you only want state transitions (navigated, action, validated, completed), this is the first thing to filter.
- `ai:generation`. Chatty during LLM-heavy steps.

A typical progress UI only keeps `task:started`, `browser:navigated`, `agent:action`, `task:validated`, `task:completed`, and `complete`.

---

## Consumption pattern

Switch on `event.event`; the SDK narrows `event.data` for each case. Show only the events you care about and ignore the rest:

- [TypeScript](#tab-panel-268)
- [Python](#tab-panel-269)

```
import Tabstack from '@tabstack/sdk'


const client = new Tabstack()
const stream = await client.agent.automate({
task: 'Extract the page title',
url: 'https://example.com',
})


for await (const event of stream) {
switch (event.event) {
case 'task:started':
console.log('Task running:', event.data.task)
break
case 'agent:action':
console.log('Action:', event.data.action, '(value:', event.data.value, ')')
break
case 'browser:navigated':
console.log('Navigated:', event.data.url)
break
case 'complete':
if (event.data.success) {
console.log('Completed:', event.data.finalAnswer)
console.log(`  ${event.data.stats.iterations} iterations, ${event.data.stats.durationMs}ms`)
} else {
console.log(`Failed (${event.data.error?.code}):`, event.data.error?.message)
}
break
case 'error':
console.log(`Runner error (${event.data.error.code}):`, event.data.error.message)
break
}
}
```

```
from tabstack import Tabstack


client = Tabstack()
stream = client.agent.automate(
    task="Extract the page title",
    url="https://example.com",
)


for event in stream:
    match event.event:
        case "task:started":
            print("Task running:", event.data.task)
        case "agent:action":
            print("Action:", event.data.action, "(value:", event.data.value, ")")
        case "browser:navigated":
            print("Navigated:", event.data.url)
        case "complete":
            if event.data.success:
                print("Completed:", event.data.final_answer)
                print(f"  {event.data.stats.iterations} iterations, {event.data.stats.duration_ms}ms")
            else:
                code = event.data.error.code if event.data.error else "UNKNOWN"
                msg = event.data.error.message if event.data.error else ""
                print(f"Failed ({code}):", msg)
        case "error":
            print(f"Runner error ({event.data.error.code}):", event.data.error.message)
```

For a deeper walkthrough of consuming the stream end-to-end, see the [Automate event flow guide](/guides/automate-event-flow/index.md).

---

## Error handling

Failures surface in three places:

1. **HTTP-level exceptions** raised by the SDK before or during the request (e.g. a malformed body, missing task, auth failure, rate limit). These are the SDK’s typed error classes, such as `BadRequestError`, `AuthenticationError`, and `RateLimitError`. Wrap the initial `automate(...)` call and the `for await` loop with `try`/`except` (or `try`/`catch`) to handle them.
2. **Agent-level aborts** surface inside the `complete` event with `success: false` and a structured `error` payload: `{ code, message }`. The `code` is a typed enum (`TASK_ABORTED`, `MAX_ITERATIONS`, `MAX_ERRORS`, `TASK_FAILED`) you can branch on. A `task:aborted` event also fires earlier in the stream, but `complete` carries the canonical final state.
3. **Top-level `error` events** fire only if the task runner itself crashes, distinct from the agent-level aborts above. Payload: `{ success: false, error: { code, message, timestamp } }` where `timestamp` is an ISO-8601 string. This event is in the typed `AutomateEvent` union, so an exhaustive `switch` narrows it.

When in doubt, log unknown event names during development. They are either conditional events you do not handle yet, or new variants added in a later SDK version.

---

## See also

- [API reference: automate](/api/resources/agent/methods/automate/index.md). Complete event schema.
- [Automate event flow guide](/guides/automate-event-flow/index.md). Deeper consumption walkthrough.
- [Interactive Mode guide](/guides/interactive-mode/index.md). `interactive:form_data:*` usage.
