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

# Extraction Actions

> Capturing data from web pages

Extraction actions capture data from web pages during automation—essential for scraping, validation, and feeding dynamic values into subsequent actions.

## Extraction Types

| Type            | Purpose                                           | Best For                                             |
| --------------- | ------------------------------------------------- | ---------------------------------------------------- |
| `llm`           | AI-powered structured data extraction             | Tables, forms, text content                          |
| `locator`       | Extract text directly via Playwright locator      | Single values, fast extraction, no LLM tokens        |
| `network_call`  | Capture API/AJAX responses                        | API data, JSON responses                             |
| `api_call`      | Call an external REST API directly                | Webhooks, triggering jobs, polling for async results |
| `screenshot`    | Save visual snapshot                              | Receipts, proofs, visual records                     |
| `state`         | Capture page state (URL, title, storage, cookies) | Debugging auth, navigation validation                |
| `two_fa_action` | Wait for and extract 2FA code                     | 2FA codes                                            |

***

## LLM Extraction

The most powerful extraction method. Uses AI to parse page content into structured data.

```json theme={null}
{
  "extraction_action": {
    "llm": {
      "source": ["axtree"],
      "extraction_format": {
        "product_name": "str",
        "price": "str",
        "availability": "str"
      },
      "extraction_instructions": "Extract product details from the product page"
    }
  }
}
```

### Properties

| Property                  | Type                             | Default              | Description               |
| ------------------------- | -------------------------------- | -------------------- | ------------------------- |
| `source`                  | `list["axtree" \| "screenshot"]` | `["axtree"]`         | Data sources to analyze   |
| `extraction_format`       | `dict`                           | Required             | Expected output structure |
| `extraction_instructions` | `str`                            | Required             | What to extract           |
| `output_variable_names`   | `list[str]`                      | `None`               | Store values as variables |
| `llm_model_name`          | `str`                            | `"gemini-2.5-flash"` | LLM model to use          |

### Source Selection

| Source                     | Best For                               |
| -------------------------- | -------------------------------------- |
| `["axtree"]`               | Text, tables, forms (default, fastest) |
| `["screenshot"]`           | Charts, images, visual layouts         |
| `["axtree", "screenshot"]` | Complex pages needing both             |

### Extraction Format

Define output structure with type hints:

```json theme={null}
{
  "extraction_format": {
    "title": "str",
    "items": "List[str]",
    "count": "str"
  }
}
```

<Info>
  Only `str` and `List[str]` are supported types.
</Info>

### Storing as Variables

Use `output_variable_names` to make extracted values available for subsequent actions:

```json theme={null}
{
  "extraction_action": {
    "llm": {
      "extraction_format": {
        "order_ids": "List[str]",
        "total": "str"
      },
      "extraction_instructions": "Extract order IDs from the table",
      "output_variable_names": ["order_ids"]
    }
  }
}
```

After this action, use `{order_ids[0]}`, `{order_ids[index]}`, or iterate with `for_loop_node`.

### Writing Good Instructions

**Good examples:**

```json theme={null}
{"extraction_instructions": "Extract all authorization numbers from the Auth Nbr column in the Authorizations table"}
```

```json theme={null}
{"extraction_instructions": "From the patient info section, extract: name (shown as 'Name:'), DOB, and member ID"}
```

**Poor examples:**

```json theme={null}
{"extraction_instructions": "Get the data"}
```

```json theme={null}
{"extraction_instructions": "Extract the numbers"}
```

<Tip>
  Be specific about where data appears, what it looks like, and expected format.
</Tip>

***

## Locator Extraction

Extract text from a specific element on the page using a Playwright locator — no LLM tokens consumed. If the locator fails, it can fall back to LLM extraction.

```json theme={null}
{
  "extraction_action": {
    "locator": {
      "command": "get_by_role(\"cell\", name=\"Authorization Number\").locator(\"+ td\")",
      "output_variable_name": "auth_number",
      "extraction_format": {
        "auth_number": "str"
      }
    }
  }
}
```

### Properties

| Property                  | Type          | Default              | Description                                    |
| ------------------------- | ------------- | -------------------- | ---------------------------------------------- |
| `command`                 | `str`         | Required             | Playwright locator command to find the element |
| `output_variable_name`    | `str`         | Required             | Variable name to store the extracted text      |
| `extraction_format`       | `dict`        | Required             | Must contain `output_variable_name` as a key   |
| `extraction_instructions` | `str \| None` | `None`               | LLM fallback instructions if the locator fails |
| `llm_provider`            | `"gemini"`    | `"gemini"`           | LLM provider to use for fallback               |
| `llm_model_name`          | `str`         | `"gemini-2.5-flash"` | LLM model for fallback                         |

<Warning>
  `extraction_format` must contain `output_variable_name` as a key, or validation will fail.
</Warning>

### Fallback Behavior

If the locator fails to find the element or find text content, two outcomes are possible:

* **With `extraction_instructions`** — falls back to LLM extraction automatically
* **Without `extraction_instructions`** — variable is set to `None`

```json theme={null}
{
  "extraction_action": {
    "locator": {
      "command": "get_by_label(\"Total Amount\")",
      "output_variable_name": "total_amount",
      "extraction_format": {
        "total_amount": "str"
      },
      "extraction_instructions": "Extract the total amount shown on the invoice page"
    }
  }
}
```

### When to Use Locator vs LLM

| Situation                              | Use                         |
| -------------------------------------- | --------------------------- |
| Element has a stable, reliable locator | `locator` (faster, no cost) |
| Page structure changes often           | `llm`                       |
| Single known value to extract          | `locator` with LLM fallback |
| Multiple fields at once                | `llm`                       |

<Tip>
  Always provide `extraction_instructions` as a fallback. This makes the extraction resilient if the page structure changes.
</Tip>

***

## Network Call Extraction

Capture data from API requests and responses:

```json theme={null}
{
  "extraction_action": {
    "network_call": {
      "url_pattern": "https://inference-api.optexity.com/orders"
    }
  }
}
```

### Properties

| Property            | Type                      | Default        | Description                      |
| ------------------- | ------------------------- | -------------- | -------------------------------- |
| `url_pattern`       | `str \| None`             | `None`         | URL substring to match           |
| `extract_from`      | `"request" \| "response"` | `None`         | Extract from request or response |
| `download_from`     | `"request" \| "response"` | `None`         | Download as file                 |
| `download_filename` | `str \| None`             | Auto-generated | Filename for download            |

<Tip>
  Use `network_call` to *intercept* requests the page already makes. Use `api_call` (below) to *initiate* your own HTTP request to any external endpoint.
</Tip>

***

## API Call Extraction

Make an outbound REST API call directly from the automation—useful for hitting webhooks, triggering backend jobs, enriching data from a third-party service, or polling an async endpoint until it's ready. The full response is stored as a variable for use in later actions.

```json theme={null}
{
  "extraction_action": {
    "api_call": {
      "url": "https://inference-api.optexity.com/v1/orders",
      "method": "GET"
    }
  }
}
```

### Properties

| Property                | Type                                              | Default          | Description                                                            |
| ----------------------- | ------------------------------------------------- | ---------------- | ---------------------------------------------------------------------- |
| `url`                   | `str`                                             | Required         | Endpoint to call                                                       |
| `method`                | `"GET" \| "POST" \| "PUT" \| "PATCH" \| "DELETE"` | `"GET"`          | HTTP method                                                            |
| `headers`               | `dict[str, str]`                                  | `{}`             | Request headers                                                        |
| `body`                  | `dict \| str \| None`                             | `None`           | Request body. A `dict` is sent as JSON; a `str` is sent as raw content |
| `query_params`          | `dict[str, str]`                                  | `{}`             | URL query parameters                                                   |
| `output_variable_names` | `list[str]`                                       | `["api_result"]` | Variable name(s) to store the response under                           |
| `timeout`               | `float`                                           | `30.0`           | Request timeout in seconds                                             |
| `poll_condition`        | `str \| None`                                     | `None`           | Expression to re-poll until satisfied (see [Polling](#polling))        |
| `poll_interval`         | `float`                                           | `5.0`            | Seconds to wait between poll attempts                                  |
| `max_poll_attempts`     | `int`                                             | `10`             | Maximum number of poll attempts                                        |

### Response Shape

The stored variable holds a dict with the following keys:

| Key           | Type             | Description                                                 |
| ------------- | ---------------- | ----------------------------------------------------------- |
| `status_code` | `int \| null`    | HTTP status code (`null` on a connection error or timeout)  |
| `headers`     | `dict[str, str]` | Response headers                                            |
| `body`        | `any`            | Parsed JSON if the response is JSON, otherwise the raw text |
| `error`       | `str`            | Present only on failure—`"timeout"` or `"http_error"`       |

### Using the Response

Reference fields of the response in later actions with dot-path syntax: `{var.field}`, `{var.nested.field}`, and `{var.array[0].field}`. Both object keys and array indices are supported.

```json theme={null}
{
  "extraction_action": {
    "api_call": {
      "url": "https://inference-api.optexity.com/v1/customers",
      "method": "POST",
      "headers": { "Authorization": "Bearer {api_token}" },
      "body": { "email": "{customer_email}" },
      "output_variable_names": ["create_result"]
    }
  }
}
```

After this action, `{create_result.body.id}` resolves to the new customer's ID, and `{create_result.status_code}` resolves to `201`.

<Info>
  Dot-path resolution (`{var.field}`) applies only to dict-valued variables such as API responses. The existing list-indexing format `{var[0]}` from `llm` extraction is unaffected.
</Info>

### Polling

For asynchronous endpoints, set `poll_condition` to keep re-requesting until the condition is met (or `max_poll_attempts` is reached). The condition is a Python-style boolean expression evaluated against the response dict, supporting both top-level keys and dot-paths:

```json theme={null}
{
  "extraction_action": {
    "api_call": {
      "url": "https://inference-api.optexity.com/v1/jobs/{job_id}",
      "poll_condition": "body.status == 'completed'",
      "poll_interval": 10.0,
      "max_poll_attempts": 30
    }
  }
}
```

Example conditions:

| Condition                    | Meaning                                                       |
| ---------------------------- | ------------------------------------------------------------- |
| `status_code == 200`         | Stop once the request returns HTTP 200                        |
| `body.status == 'completed'` | Stop once the response body's `status` field is `"completed"` |
| `body.progress >= 100`       | Stop once `progress` reaches 100                              |

If the condition is never met within `max_poll_attempts`, the last response is stored and the automation continues.

***

## Screenshot Extraction

Save a screenshot for later analysis:

```json theme={null}
{
  "extraction_action": {
    "screenshot": {
      "filename": "confirmation.png",
      "full_page": true
    }
  }
}
```

| Property    | Type   | Default  | Description                  |
| ----------- | ------ | -------- | ---------------------------- |
| `filename`  | `str`  | Required | Output filename              |
| `full_page` | `bool` | `True`   | Entire page or viewport only |

***

## State Extraction

Capture page state, including URL/title plus browser storage and cookies:

```json theme={null}
{
  "extraction_action": {
    "state": {}
  }
}
```

### Output

`state` extraction appends an `OutputData.json_data` object with the following shape:

| Key               | Type                     | Description                                   |
| ----------------- | ------------------------ | --------------------------------------------- |
| `page_url`        | `str`                    | Current page URL                              |
| `page_title`      | `str`                    | Current page title                            |
| `local_storage`   | `dict[str, str \| null]` | All `localStorage` key/value pairs            |
| `session_storage` | `dict[str, str \| null]` | All `sessionStorage` key/value pairs          |
| `cookies`         | `list[dict]`             | Cookies from the current browser context      |
| `document_cookie` | `str`                    | `document.cookie` string for the current page |

## Two-Factor Authentication Extraction

Wait for and extract 2FA code:

```json theme={null}
{
  "extraction_action": {
    "two_fa_action": {
      "action": "email_two_fa_action",
      "output_variable_name": "two_fa_code"
    }
  }
}
```

### Properties

| Property               | Type                                                                    | Default  | Description                                       |
| ---------------------- | ----------------------------------------------------------------------- | -------- | ------------------------------------------------- |
| `action`               | `"email_two_fa_action" \| "slack_two_fa_action" \| "sms_two_fa_action"` | Required | The type of 2FA action to use                     |
| `output_variable_name` | `str`                                                                   | Required | The name of the variable to store the 2FA code in |
| `instructions`         | `str`                                                                   | `None`   | Optional Custom instructions for code extraction  |
| `max_wait_time`        | `float`                                                                 | `300.0`  | The maximum time to wait for the 2FA code         |
| `check_interval`       | `float`                                                                 | `10.0`   | The interval to check for the 2FA code            |

### Action Types

| Action Type           | Description                                       |
| --------------------- | ------------------------------------------------- |
| `email_two_fa_action` | Wait for and extract 2FA code from email          |
| `slack_two_fa_action` | Wait for and extract 2FA code from Slack          |
| `sms_two_fa_action`   | Wait for and extract 2FA code from SMS via Twilio |

For more information on how to use the 2FA code in your automation, please refer to the [Two-Factor Authentication Integration](/docs/advanced/two-fa-integration) documentation.

***

## Timing

Extraction actions have different timing defaults to allow pages to fully load:

| Property            | Default for Extractions |
| ------------------- | ----------------------- |
| `before_sleep_time` | `3.0` seconds           |
| `end_sleep_time`    | `0.0` seconds           |

Override if needed:

```json theme={null}
{
  "type": "action_node",
  "extraction_action": {
    "llm": { ... }
  },
  "before_sleep_time": 5.0
}
```

***

## When to Use Each Type

| Scenario                                | Recommended                              |
| --------------------------------------- | ---------------------------------------- |
| Extract text/tables from page           | `llm` with `axtree`                      |
| Extract a single known element          | `locator`                                |
| Extract with locator + LLM fallback     | `locator` with `extraction_instructions` |
| Charts, images, visual content          | `llm` with `screenshot`                  |
| Intercept API data the page requests    | `network_call`                           |
| Call an external API / webhook directly | `api_call`                               |
| Poll an async endpoint until ready      | `api_call` with `poll_condition`         |
| Visual proof/documentation              | `screenshot`                             |
| Validate navigation                     | `state`                                  |
