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

# Run Task

> Run a scripted sequence of browser actions (navigate, click, type, scroll, evaluate, upload, authenticate, etc.) and optionally return a screenshot, PDF, or page content in the same response.

## Overview

The task runner is the workhorse of the Browser Session API. A single request can:

1. Navigate to a `url` (optional)
2. Execute a sequential list of `actions` against the active page
3. Capture output artifacts — `screenshot`, `pdf`, and/or `content` — at the end

Actions run in order. If any action fails, the task aborts and the error is returned. Use this endpoint for multi-step flows (login → search → extract) that would otherwise require multiple round trips.

## Path Parameters

<ParamField path="id" type="string" required={true}>
  Browser session ID (UUID).
</ParamField>

## Body

<ParamField body="url" type="string">
  Optional URL to navigate to before running `actions`.
</ParamField>

<ParamField body="waitUntil" type="string" default="load">
  Wait condition for the initial navigation. One of `domcontentloaded`, `load`, `networkidle`.
</ParamField>

<ParamField body="actions" type="object[]">
  Sequential list of actions to execute. See [Action schema](#action-schema) below.
</ParamField>

<ParamField body="screenshot" type="object">
  When present, a screenshot is taken after all actions complete. Supports `{ fullPage?: boolean, selector?: string }`.
</ParamField>

<ParamField body="pdf" type="object">
  When present, renders a PDF after all actions complete. Accepts the same options as `POST /browser/sessions/{id}/pdf` (format, landscape, margin, etc.). Returned base64-encoded.
</ParamField>

<ParamField body="content" type="boolean">
  When true, returns `{ html, url }` of the final page in the response.
</ParamField>

## Action schema

Every action has a `type` field. The remaining fields depend on the type.

| Type           | Required fields                            | Optional fields                                          |
| -------------- | ------------------------------------------ | -------------------------------------------------------- |
| `navigate`     | `url`                                      | `waitUntil`                                              |
| `click`        | `selector` **or** `coordinates`            | —                                                        |
| `type`         | `selector`, `text`                         | —                                                        |
| `press`        | `key`                                      | `selector`                                               |
| `scroll`       | one of `selector` / `coordinates` / `text` | —                                                        |
| `wait`         | `selector` **or** `text`                   | —                                                        |
| `evaluate`     | `script`                                   | —                                                        |
| `screenshot`   | —                                          | `selector`                                               |
| `uploadFile`   | `selector`, `filename`                     | —                                                        |
| `authenticate` | `mode` + matching fields                   | `credentialId`, `selectors`, `success`, `pauseTimeoutMs` |
| `select`       | `selector`, `text`                         | —                                                        |
| `hover`        | `selector`                                 | —                                                        |

Key per-field notes:

<ParamField body="filename" type="string">
  For `uploadFile`: must match a filename previously uploaded via `POST /browser/sessions/{id}/files`.
</ParamField>

<ParamField body="credentialId" type="string">
  For `authenticate` when `mode` is `vault` or `vault_then_prompt`: UUID of a credential from `POST /browser/credentials`. Never pass raw username/password.
</ParamField>

<ParamField body="mode" type="string">
  For `authenticate`: one of `vault`, `prompt_user`, `vault_then_prompt`.
</ParamField>

<ParamField body="selectors" type="object">
  For `authenticate`: `{ username, password, submit?, totp? }` — CSS selectors pointing at each login form field.
</ParamField>

<ParamField body="success" type="object">
  For `authenticate`: how to detect login success. `{ condition: "url" | "selector" | "text" | "networkIdle", value: string, timeoutMs?: integer }`.
</ParamField>

<ParamField body="pauseTimeoutMs" type="integer" default="300000">
  For `authenticate` with `mode: prompt_user`: max time to wait for the end-user to complete login via the live view.
</ParamField>

## Example Request

<CodeGroup>
  ```bash cURL (navigate + click + screenshot) theme={null}
  curl -X POST "https://api.scrapengine.io/api/v1/browser/sessions/baa3f390-fa6e-4a24-b84a-a575a5f3a9c7/tasks" \
    -H "Authorization: Bearer $SCRAPENGINE_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "url": "https://example.com",
      "waitUntil": "load",
      "actions": [
        { "type": "click", "selector": "a[href=\"/login\"]" },
        { "type": "type", "selector": "#email", "text": "user@example.com" },
        { "type": "type", "selector": "#password", "text": "hunter2" },
        { "type": "click", "selector": "button[type=submit]" },
        { "type": "wait", "selector": "#dashboard" }
      ],
      "screenshot": { "fullPage": true },
      "content": true
    }'
  ```

  ```bash cURL (vault authenticate + PDF) theme={null}
  curl -X POST "https://api.scrapengine.io/api/v1/browser/sessions/baa3f390-fa6e-4a24-b84a-a575a5f3a9c7/tasks" \
    -H "Authorization: Bearer $SCRAPENGINE_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "url": "https://app.example.com/login",
      "actions": [
        {
          "type": "authenticate",
          "mode": "vault",
          "credentialId": "4a0d6b3a-1f10-4c6f-8a99-8e2b7f2c1234",
          "selectors": {
            "username": "#email",
            "password": "#password",
            "submit": "button[type=submit]"
          },
          "success": { "condition": "url", "value": "/dashboard", "timeoutMs": 30000 }
        },
        { "type": "navigate", "url": "https://app.example.com/invoices/latest" }
      ],
      "pdf": { "format": "A4", "printBackground": true }
    }'
  ```
</CodeGroup>

## Response

### Success Response (201)

<ResponseField name="url" type="string">
  Effective URL of the active tab after all actions.
</ResponseField>

<ResponseField name="screenshot" type="string">
  Base64-encoded PNG, present when the request included `screenshot`.
</ResponseField>

<ResponseField name="pdf" type="string">
  Base64-encoded PDF bytes, present when the request included `pdf`.
</ResponseField>

<ResponseField name="content" type="object">
  `{ html, url }`, present when the request had `content: true`.
</ResponseField>

<ResponseField name="actionResults" type="object[]">
  One entry per action, in order. Shape depends on the action type (e.g. `evaluate` returns `{ value }`, `authenticate` returns `{ success, reason }`).
</ResponseField>

**Example Response:**

```json theme={null}
{
  "url": "https://app.example.com/dashboard",
  "screenshot": "iVBORw0KGgoAAAANSUhEUgAA...",
  "content": {
    "url": "https://app.example.com/dashboard",
    "html": "<!doctype html>..."
  },
  "actionResults": [
    { "type": "click", "ok": true },
    { "type": "type", "ok": true, "charactersTyped": 18 },
    { "type": "authenticate", "ok": true, "reason": "success" }
  ]
}
```

### Error Responses

| Status | Description                                                                                           |
| ------ | ----------------------------------------------------------------------------------------------------- |
| `400`  | Invalid body — unknown action type, missing required fields for an action, or conflicting parameters. |
| `401`  | Unauthorized — invalid or missing API key.                                                            |
| `404`  | Session not found, or a selector inside an action matched nothing.                                    |
| `408`  | An action timed out (e.g. `wait` selector did not appear, `authenticate` success condition not met).  |
| `422`  | Action failed semantically (e.g. `authenticate` with `mode: vault` and `domain_mismatch`).            |
| `503`  | The browser session is temporarily unreachable.                                                       |

## Notes

* Actions run sequentially. Order matters — put `wait` between flaky interactions.
* `screenshot`, `pdf`, and `content` are all independent and can be combined in a single task.
* For long-running login flows, prefer `authenticate` over scripted `type`/`click` pairs — it handles common anti-bot consent banners and supports vault-stored credentials.
* `filename` in `uploadFile` must be uploaded first via `POST /browser/sessions/{id}/files`.
