# AI Web Task Runner (`solutionssmart/ai-web-task-runner`) Actor

Run natural-language browser tasks with Playwright. Extract structured data, follow task-relevant links, capture screenshots, generate reports, and export reusable scripts.

- **URL**: https://apify.com/solutionssmart/ai-web-task-runner.md
- **Developed by:** [Solutions Smart](https://apify.com/solutionssmart) (community)
- **Categories:** AI, Agents
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $50.00 / 1,000 results

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

### What does AI Web Task Runner do?

AI Web Task Runner is an Apify Actor that turns **natural-language browser tasks** into controlled Playwright automation runs.

It can:

- browse public websites
- follow task-relevant links
- extract structured results
- capture screenshots
- save raw HTML
- generate a human-readable report
- export a reusable Playwright Python script from the successful task trajectory

This Actor is designed for **public-web automation, extraction, research, and script generation**.

It is **not** a login bot, spam bot, comment bot, messaging bot, or anti-bot bypass tool.

### How it differs from a fixed scraper

Most scrapers are built for one website and one output shape.

AI Web Task Runner is different:

- you describe the task in natural language
- the Actor opens one or more start URLs
- it follows task-relevant public pages
- it records an action trajectory
- it extracts best-effort results even without an LLM
- it can optionally use an LLM for safer planning, schema mapping, and summarization

This makes it useful for a wider class of public-web tasks than a single-purpose scraper, while still staying controlled and safety-constrained.

### Main modes

#### `run_task`

Default mode.

Use this for general browser-task execution, such as:

- finding features
- locating pricing information
- summarizing a product page
- finding the correct public page for a business task

#### `extract`

Use this for structured extraction.

If you provide an `extractionSchema`, the Actor tries to map observed content into that schema.

#### `research`

Use this to browse task-relevant public pages and produce a summary with source URLs.

#### `generate_script`

Use this to run a task and export a reusable standalone Playwright Python script based on the successful action trajectory.

#### `audit_lead`

Optional compatibility mode.

This preserves the previous lead/contact-audit workflow and outputs company-profile style results for website contact and outreach auditing.

### Input examples

#### Example 1: Pricing extraction

```json
{
  "task": "Find the pricing plans and extract plan name, price, billing period, and main features.",
  "startUrls": [
    { "url": "https://example.com/" }
  ],
  "mode": "extract",
  "extractionSchema": {
    "plans": [
      {
        "name": "",
        "price": "",
        "billingPeriod": "",
        "features": []
      }
    ]
  },
  "maxPages": 5,
  "captureScreenshots": true
}
```

#### Example 2: Research task

```json
{
  "task": "Find what services this company offers and summarize them with source URLs.",
  "startUrls": [
    { "url": "https://example.com/" }
  ],
  "mode": "research",
  "maxPages": 6,
  "maxDepth": 2,
  "sameDomainOnly": true
}
```

#### Example 3: Generate reusable Playwright script

```json
{
  "task": "Open the website, navigate to the pricing page, and extract the pricing table.",
  "startUrls": [
    { "url": "https://example.com/" }
  ],
  "mode": "generate_script",
  "generateReusableScript": true,
  "maxPages": 5,
  "captureScreenshots": true
}
```

#### Example 4: Optional lead audit template

```json
{
  "task": "Audit this website for contact and sales outreach readiness.",
  "startUrls": [
    { "url": "https://example.com/" }
  ],
  "mode": "audit_lead",
  "maxPages": 5,
  "captureScreenshots": true
}
```

### Output record types

For all main modes except `audit_lead`, the **default dataset** contains only:

#### `task_result`

One final task-level record. This is the main export row and the recommended unit for pricing and CSV export.

Detailed page snapshots and extracted items are stored in the key-value store and referenced from the final task result.

It contains:

- task
- mode
- final status
- pages visited
- steps executed
- summary
- result payload
- confidence
- screenshot keys
- report key
- trajectory key
- generated script key if applicable
- page snapshots key
- extracted items key

#### `audit_lead` compatibility output

When `mode = audit_lead`, the **default dataset** contains:

- `company_profile`

The older `page` records are preserved as compatibility artifacts in the key-value store, not as billable default dataset rows.

### Key-value store artifacts

For the main task-runner modes, the Actor saves:

- `REPORT.html`
- `TASK_RESULT.json`
- `TASK_TRAJECTORY.json`
- `PAGE_SNAPSHOTS.json`
- `EXTRACTED_ITEMS.json`
- `GENERATED_SCRIPT_RECORD.json` if enabled
- `generated_script.py` if enabled
- `generated_script_metadata.json` if enabled
- screenshots if enabled
- raw HTML if `saveHtml = true`

This means the default dataset stays clean and export-friendly, while detailed execution artifacts remain available in the key-value store.

For `audit_lead`, compatibility artifacts include:

- `COMPANY_PROFILES.json`
- `PAGE_RECORDS.json`
- `REPORT.html`
- `run_log.json`

### Generated Playwright script

When `generateReusableScript = true` or `mode = generate_script`, the Actor saves:

- `generated_script.py`
- `generated_script_metadata.json`

The generated script:

- is standalone Playwright Python
- is based on the recorded safe action trajectory
- includes comments for the reproduced browser steps
- contains no secrets
- does not rely on arbitrary LLM-generated executable code

### Safety model

The Actor only allows a fixed safe action set:

- `visit_url`
- `click_link_text`
- `click_css_selector`
- `type_text`
- `press_key`
- `select_option`
- `wait`
- `extract_current_page`
- `collect_links`
- `stop`

The Actor does **not** allow:

- arbitrary Python execution
- shell execution
- unrestricted JavaScript execution
- login/cookie automation in V1
- posting, commenting, or messaging automation
- paywall bypass
- CAPTCHA bypass
- destructive actions
- purchases or form submissions that change state

### Deterministic vs LLM-assisted mode

#### Deterministic mode

If `llmProvider = none`, the Actor still works.

It will:

- open start URLs
- collect page snapshots
- infer task keywords
- follow obvious task-relevant links within limits
- extract visible text, headings, links, tables, prices, emails, phones, and structured candidates
- produce a best-effort task result

#### LLM-assisted mode

If an LLM provider is configured, the Actor may use the model for:

- safe action planning
- choosing the next allowed action
- mapping page snapshots into `extractionSchema`
- summarizing findings

The LLM is constrained to structured JSON outputs and validated before use.

If the LLM fails, the Actor falls back to deterministic behavior.

### Optional lead-audit template

The older lead/contact-auditor behavior is still available in:

```json
"mode": "audit_lead"
```

That mode keeps:

- lead-audit heuristics
- page-level contact findings
- company profile aggregation
- compatibility outputs for outreach workflows

It is now an optional template mode, not the main identity of the Actor.

### Example use cases

- Extract pricing plans from a SaaS website
- Extract a table from a public webpage
- Research product features from a company website
- Find contact or sales paths from a public website
- Summarize same-domain public pages related to a topic
- Generate a reusable Playwright script for a repeated browser task

### Limitations

- This Actor is intended for public websites.
- It does not support login-heavy or state-changing automation in V1.
- Deterministic extraction is heuristic and best-effort.
- Some websites hide key data behind scripts, forms, or client-side UI patterns.
- LLM mode can improve planning and summarization, but it is still constrained and fallback-safe.
- It is not an anti-bot bypass product.

### Troubleshooting

#### I only got the homepage

Increase `maxDepth` or start from a more relevant public page.

#### The final result is incomplete

Increase:

- `maxPages`
- `maxDepth`
- `timeoutSeconds`

and consider using `extract` mode with an `extractionSchema`.

#### The Actor did not visit the page I expected

Check:

- `TASK_TRAJECTORY.json`
- `PAGE_SNAPSHOTS.json`
- `EXTRACTED_ITEMS.json`
- `REPORT.html`

These artifacts show what the Actor actually saw and did.

#### I want the older contact-audit behavior

Use:

```json
"mode": "audit_lead"
```

#### The Actor should not submit forms or log in

That is expected in V1. The safety model deliberately avoids state-changing automation.

# Actor input Schema

## `task` (type: `string`):

Describe the browser task in natural language.

## `startUrls` (type: `array`):

One or more public URLs where the task should begin.

## `mode` (type: `string`):

Choose how the Actor should execute the browser task.

## `extractionSchema` (type: `object`):

Optional JSON schema for structured extraction.

## `outputFormat` (type: `string`):

Preferred final task result format.

## `maxPages` (type: `integer`):

Maximum number of pages to visit.

## `maxSteps` (type: `integer`):

Maximum number of safe browser actions to execute.

## `maxDepth` (type: `integer`):

Maximum link depth from the start URLs.

## `sameDomainOnly` (type: `boolean`):

If enabled, only follow links within the same registered domain.

## `captureScreenshots` (type: `boolean`):

Save screenshots of visited pages.

## `saveHtml` (type: `boolean`):

Save raw HTML for visited pages.

## `generateReusableScript` (type: `boolean`):

Generate a standalone Playwright Python script from the successful task trajectory.

## `llmProvider` (type: `string`):

Optional provider for action planning, extraction mapping, and summarization.

## `llmApiKey` (type: `string`):

Optional secret API key for the selected LLM provider.

## `llmModel` (type: `string`):

Optional specific model identifier.

## `temperature` (type: `number`):

Controls response randomness for LLM-assisted mode.

## `proxyConfiguration` (type: `object`):

Optional proxy settings.

## `headless` (type: `boolean`):

Run Playwright in headless mode.

## `timeoutSeconds` (type: `integer`):

Maximum run time in seconds.

## `waitUntil` (type: `string`):

Playwright wait condition for navigations.

## Actor input object example

```json
{
  "task": "Find the main product features on this website and summarize them.",
  "startUrls": [
    {
      "url": "https://example.com/"
    }
  ],
  "mode": "run_task",
  "extractionSchema": {},
  "outputFormat": "auto",
  "maxPages": 5,
  "maxSteps": 20,
  "maxDepth": 1,
  "sameDomainOnly": true,
  "captureScreenshots": true,
  "saveHtml": false,
  "generateReusableScript": false,
  "llmProvider": "none",
  "temperature": 0.2,
  "headless": true,
  "timeoutSeconds": 180,
  "waitUntil": "domcontentloaded"
}
```

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "task": "Find the main product features on this website and summarize them.",
    "startUrls": [
        {
            "url": "https://example.com/"
        }
    ],
    "extractionSchema": {}
};

// Run the Actor and wait for it to finish
const run = await client.actor("solutionssmart/ai-web-task-runner").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "task": "Find the main product features on this website and summarize them.",
    "startUrls": [{ "url": "https://example.com/" }],
    "extractionSchema": {},
}

# Run the Actor and wait for it to finish
run = client.actor("solutionssmart/ai-web-task-runner").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "task": "Find the main product features on this website and summarize them.",
  "startUrls": [
    {
      "url": "https://example.com/"
    }
  ],
  "extractionSchema": {}
}' |
apify call solutionssmart/ai-web-task-runner --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,solutionssmart/ai-web-task-runner"
        }
    }
}

```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/cn3TJ3JL4qYMRLZ6Q/builds/2iXztBzRks7bK8alg/openapi.json
