# AI Selector Repair Tool (`automation-lab/ai-selector-repair`) Actor

Fix broken CSS and XPath selectors with AI. Provide a URL and broken selectors — get back updated, working selectors with confidence scores and explanations of what changed in the page structure.

- **URL**: https://apify.com/automation-lab/ai-selector-repair.md
- **Developed by:** [Stas Persiianenko](https://apify.com/automation-lab) (community)
- **Categories:** AI, Developer tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, NaN bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per event

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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

## What's an Apify Actor?

Actors are a software tools running on the Apify platform, for all kinds of web data extraction and automation use cases.
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.

In JavaScript/TypeScript projects, use official [JavaScript/TypeScript client](https://docs.apify.com/api/client/js.md):

```bash
npm install apify-client
```

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python.md):

```bash
pip install apify-client
```

In shell scripts, use [Apify CLI](https://docs.apify.com/cli/docs.md):

````bash
# MacOS / Linux
curl -fsSL https://apify.com/install-cli.sh | bash
# Windows
irm https://apify.com/install-cli.ps1 | iex
```bash

In AI frameworks, you might use the [Apify MCP server](https://docs.apify.com/platform/integrations/mcp.md).

If your project is in a different language, use 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

## AI Selector Repair Tool

### What does AI Selector Repair Tool do?

**AI Selector Repair Tool** fixes broken CSS and XPath selectors using AI-powered analysis. When a website changes its layout and your scrapers break, this tool takes your broken selectors and the target URL, analyzes the current page structure with an LLM (Claude or GPT), and returns **updated working selectors** with confidence scores and explanations of what changed.

Instead of manually inspecting HTML diffs and rewriting selectors by hand, let AI handle the tedious work. The tool fetches the current page, sends the HTML and broken selectors to an LLM, and validates that the repaired selectors actually match elements on the page.

Try it now on the [Apify platform](https://apify.com/automation-lab/ai-selector-repair) — no coding required.

### Who is AI Selector Repair Tool for?

🔧 **Web Scraping Engineers**
- Fix broken scraper selectors without manually inspecting page source
- Integrate into CI/CD pipelines to auto-repair selectors when scrapers fail
- Batch-repair multiple selectors from a single broken scraper

📊 **Data Teams**
- Keep data pipelines running when source websites update their layouts
- Reduce downtime between website changes and scraper fixes
- Get confidence scores to decide whether to auto-deploy fixes or flag for review

🤖 **Automation Builders**
- Maintain browser automation scripts (Playwright, Puppeteer, Selenium) when target pages change
- Fix test suite selectors that break after UI updates
- Build self-healing automation workflows

🏢 **Scraper-as-a-Service Providers**
- Reduce maintenance cost across hundreds of scrapers
- Automate the most common scraper failure mode (selector breakage)
- Pair with [Scraper Regression Watchdog](https://apify.com/automation-lab/scraper-regression-watchdog) for detect-then-fix pipelines

### Why use AI Selector Repair Tool?

- 🧠 **AI-powered analysis** — uses Claude or GPT to understand what the selector was targeting, not just string matching
- ✅ **Validation built in** — repaired selectors are tested against the actual page HTML before being returned
- 📊 **Confidence scores** — each repair includes a 0-1 confidence score so you know when to auto-deploy vs. review manually
- 💡 **Change explanations** — understand WHY your selector broke (class renamed, element restructured, etc.)
- 🔄 **CSS and XPath** — supports both selector types, with intelligent type detection
- 🌐 **No login required** — works on any publicly accessible page
- ⚡ **HTTP-first** — lightweight HTTP fetching keeps costs low (no browser overhead)
- 🔗 **API, scheduling, integrations** — run via API, schedule recurring repairs, integrate with 5,000+ apps via Zapier and Make
- 🤝 **Pairs with Watchdog** — combine with [Scraper Regression Watchdog](https://apify.com/automation-lab/scraper-regression-watchdog) for automated detect-and-fix workflows

### What data can you extract?

AI Selector Repair Tool returns one result per input selector:

| Field | Type | Description |
|-------|------|-------------|
| `originalSelector` | string | The broken selector you provided |
| `repairedSelector` | string | The AI-suggested fix |
| `selectorType` | string | `css` or `xpath` |
| `confidence` | number | Confidence score (0-1) |
| `status` | string | `repaired`, `unchanged`, or `failed` |
| `explanation` | string | What changed in the page structure |
| `matchedElements` | number | How many elements the repaired selector matches |
| `url` | string | The page URL that was analyzed |

### How much does it cost to repair broken selectors?

AI Selector Repair Tool uses pay-per-event pricing:

| Event | Price |
|-------|-------|
| Run started | $0.01 per run |
| Selector repaired | $0.003 per selector |

**Example costs:**
- 🔹 Repair 5 selectors: $0.01 + (5 × $0.003) = **$0.025**
- 🔹 Repair 20 selectors: $0.01 + (20 × $0.003) = **$0.07**
- 🔹 Repair 100 selectors: $0.01 + (100 × $0.003) = **$0.31**

**Note:** You also pay for the LLM API calls (Anthropic or OpenAI) using your own API key. Claude Sonnet typically costs $0.003-0.01 per selector depending on HTML size.

With Apify's **free plan** ($5 monthly credits), you can repair approximately **160 selectors** per month (Apify costs only, LLM costs separate).

### How to repair broken selectors

1. Go to [AI Selector Repair Tool](https://apify.com/automation-lab/ai-selector-repair) on Apify
2. Enter the **URL** of the page where your selectors are broken
3. Add your **broken selectors** to the list (CSS or XPath)
4. Optionally add **descriptions** of what each selector targets (improves accuracy)
5. Enter your **Anthropic or OpenAI API key**
6. Click **Start** and wait for results
7. Review the repaired selectors, confidence scores, and explanations
8. Update your scraper code with the new selectors

**Example input for Hacker News:**
```json
{
    "url": "https://news.ycombinator.com",
    "selectors": [".storylink", "td.title > a.storylink"],
    "selectorDescriptions": ["Story title link", "Story title link (alternative)"],
    "anthropicApiKey": "sk-ant-..."
}
````

**Example input for an e-commerce site:**

```json
{
    "url": "https://example.com/products",
    "selectors": [
        ".product-card .price-tag",
        "div.product-listing span.old-price",
        "//div[@class='product']//span[@class='discount-badge']"
    ],
    "selectorDescriptions": [
        "Product price element",
        "Original price (before discount)",
        "Discount badge on product cards"
    ],
    "anthropicApiKey": "sk-ant-..."
}
```

### Input parameters

| Parameter | Type | Required | Default | Description |
|-----------|------|----------|---------|-------------|
| `url` | string | Yes | — | URL of the page where selectors are broken |
| `selectors` | string\[] | Yes | — | List of broken CSS or XPath selectors |
| `oldHtml` | string | No | — | Old HTML snapshot for better change detection |
| `selectorDescriptions` | string\[] | No | — | What each selector was supposed to target |
| `anthropicApiKey` | string | \* | — | Anthropic API key (provide this OR OpenAI key) |
| `openaiApiKey` | string | \* | — | OpenAI API key (alternative to Anthropic) |
| `model` | string | No | `claude-sonnet-4-20250514` | LLM model to use |
| `maxHtmlLength` | number | No | `50000` | Max HTML chars sent to LLM |
| `proxyConfiguration` | object | No | — | Proxy settings for fetching the page |

\*At least one API key (Anthropic or OpenAI) is required.

### Output example

```json
[
    {
        "originalSelector": ".storylink",
        "repairedSelector": ".titleline > a",
        "selectorType": "css",
        "confidence": 0.95,
        "status": "repaired",
        "explanation": "Hacker News renamed the 'storylink' class to 'titleline' and wrapped it in a span. The link is now a direct child of '.titleline'.",
        "matchedElements": 30,
        "url": "https://news.ycombinator.com"
    },
    {
        "originalSelector": "td.title > a.storylink",
        "repairedSelector": "td.title .titleline > a",
        "selectorType": "css",
        "confidence": 0.9,
        "status": "repaired",
        "explanation": "The 'storylink' class was removed. Links are now inside a '.titleline' span within the title cell.",
        "matchedElements": 30,
        "url": "https://news.ycombinator.com"
    }
]
```

### Tips for best results

- 📝 **Add selector descriptions** — telling the AI "this selects the product price" dramatically improves accuracy vs. just providing the selector string
- 📄 **Provide old HTML when possible** — if you have a cached copy of the page when selectors worked, include it via `oldHtml` for much better change detection
- 🎯 **Start with Claude Sonnet** — it provides the best accuracy. Switch to Haiku or GPT-4o Mini for bulk repairs where speed matters more than precision
- 💰 **Reduce `maxHtmlLength` for simple pages** — if the target elements are near the top of the page, 10,000-20,000 chars is usually enough
- ⚡ **Batch related selectors** — send all broken selectors for one page in a single run to save on start event costs
- 🔍 **Check confidence scores** — auto-deploy repairs with confidence ≥ 0.8, manually review anything below
- 🔄 **Pair with Scraper Regression Watchdog** — detect breakage automatically, then feed broken selectors into this tool

### Integrations

- 📊 **AI Selector Repair → Google Sheets** — export repaired selectors to a spreadsheet for team review before deploying fixes
- 🔔 **Scraper Regression Watchdog → AI Selector Repair → Slack** — automated pipeline: detect broken scraper, repair selectors, notify team with results
- 🔄 **AI Selector Repair → Make/Zapier** — trigger selector repair when a scraper fails, then auto-update the scraper configuration
- ⏰ **Scheduled selector health checks** — run weekly on critical scrapers to proactively catch selector drift before it causes failures
- 🔗 **Webhooks** — get real-time notifications when repairs are complete, trigger downstream scraper updates automatically

### Using the Apify API

#### Node.js

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

const client = new ApifyClient({ token: 'YOUR_APIFY_TOKEN' });

const run = await client.actor('automation-lab/ai-selector-repair').call({
    url: 'https://example.com/products',
    selectors: ['.product-card .price', '.old-product-name'],
    selectorDescriptions: ['Product price', 'Product name'],
    anthropicApiKey: 'sk-ant-...',
});

const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);
```

#### Python

```python
from apify_client import ApifyClient

client = ApifyClient("YOUR_APIFY_TOKEN")

run = client.actor("automation-lab/ai-selector-repair").call(run_input={
    "url": "https://example.com/products",
    "selectors": [".product-card .price", ".old-product-name"],
    "selectorDescriptions": ["Product price", "Product name"],
    "anthropicApiKey": "sk-ant-...",
})

items = client.dataset(run["defaultDatasetId"]).list_items().items
print(items)
```

#### cURL

```bash
curl "https://api.apify.com/v2/acts/automation-lab~ai-selector-repair/runs?token=YOUR_APIFY_TOKEN" \
  -X POST \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://example.com/products",
    "selectors": [".product-card .price", ".old-product-name"],
    "selectorDescriptions": ["Product price", "Product name"],
    "anthropicApiKey": "sk-ant-..."
  }'
```

### Use with AI agents via MCP

AI Selector Repair Tool is available as a tool for AI assistants that support the [Model Context Protocol (MCP)](https://docs.apify.com/platform/integrations/mcp).

#### Setup for Claude Code

```bash
claude mcp add --transport http apify "https://mcp.apify.com?tools=automation-lab/ai-selector-repair"
```

#### Setup for Claude Desktop, Cursor, or VS Code

Add this to your MCP config file:

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com?tools=automation-lab/ai-selector-repair"
        }
    }
}
```

#### Example prompts

- "My scraper for example.com broke. The selector `.product-list .item-price` no longer works. Can you fix it?"
- "Check if these selectors still work on https://news.ycombinator.com: `.storylink`, `.score`"
- "I have 10 broken selectors for my e-commerce scraper. Here they are: \[...]. Fix them all and tell me which ones you're confident about."

### Is it legal to use AI Selector Repair Tool?

AI Selector Repair Tool only reads publicly accessible web pages — it does not bypass any authentication, CAPTCHA, or access controls. The tool analyzes page structure to help you maintain your web scrapers.

You should always review the Terms of Service of any website you scrape and ensure your usage complies with applicable laws including GDPR and CCPA. For more information, see Apify's guide on [ethical web scraping](https://blog.apify.com/is-web-scraping-legal/).

### FAQ

**How accurate are the repaired selectors?**
Accuracy depends on the complexity of the page change. For simple class renames or element restructuring, accuracy is typically 85-95%. For major page redesigns, accuracy drops — use the confidence score to gauge reliability. Providing selector descriptions and old HTML significantly improves accuracy.

**How much does it cost per repair?**
Apify charges $0.003 per selector + $0.01 per run. LLM API costs (your own key) add approximately $0.003-0.01 per selector with Claude Sonnet, depending on HTML size. Total cost per selector is typically $0.006-0.013.

**Can it fix XPath selectors?**
Yes. The AI understands both CSS and XPath selectors. However, CSS selector repairs can be validated against the page HTML directly, while XPath repairs rely on the AI's confidence score for validation.

**Why are my repaired selectors showing 0 matched elements?**
This usually means the page requires JavaScript rendering to display the target elements. Try: (1) providing the rendered HTML via `oldHtml`, (2) using a proxy if the page is geo-restricted, or (3) checking that the URL is correct and the page is publicly accessible.

**Why did the confidence score drop to 0.3?**
A low confidence score (0.3 or below) means the repaired selector was validated against the page HTML but matched 0 elements. This typically indicates the repair needs manual review — the AI found a plausible fix but couldn't confirm it works.

**Which LLM model should I use?**
Claude Sonnet 4 (default) offers the best accuracy. Claude Haiku 4.5 is 3-5x cheaper and still good for straightforward repairs. GPT-4o Mini is comparable to Haiku in both cost and quality. Use the best model for critical selectors, cheaper models for bulk operations.

### Other scraper tools

- 🔍 [Scraper Regression Watchdog](https://apify.com/automation-lab/scraper-regression-watchdog) — detect when your scrapers break before users notice

# Actor input Schema

## `url` (type: `string`):

URL of the page where selectors are broken.

## `selectors` (type: `array`):

List of CSS or XPath selectors that no longer work on the target page.

## `oldHtml` (type: `string`):

Paste old HTML of the page for better context on what changed. Optional but improves accuracy.

## `selectorDescriptions` (type: `array`):

Describe what each selector was supposed to target (e.g., 'article title link', 'price element'). Must match the order of broken selectors.

## `anthropicApiKey` (type: `string`):

Your Anthropic API key for Claude. Get one at console.anthropic.com.

## `openaiApiKey` (type: `string`):

Your OpenAI API key (alternative to Anthropic). Provide one of: Anthropic, OpenAI, or OpenRouter key.

## `openrouterApiKey` (type: `string`):

Your OpenRouter API key (alternative to Anthropic/OpenAI). Supports all major models via openrouter.ai.

## `model` (type: `string`):

Select which LLM model to use for analysis.

## `maxHtmlLength` (type: `integer`):

Maximum number of characters of HTML to send to the LLM. Lower values reduce cost but may miss context.

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

Use a proxy to access geo-restricted or blocked pages.

## Actor input object example

```json
{
  "url": "https://news.ycombinator.com",
  "selectors": [
    ".titleline > a",
    "span.titleline > a"
  ],
  "selectorDescriptions": [
    "Story title link on HN front page",
    "Story title link (span variant)"
  ],
  "model": "claude-sonnet-4-20250514",
  "maxHtmlLength": 50000
}
```

# Actor output Schema

## `overview` (type: `string`):

No description

# 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 = {
    "url": "https://news.ycombinator.com",
    "selectors": [
        ".titleline > a",
        "span.titleline > a"
    ],
    "selectorDescriptions": [
        "Story title link on HN front page",
        "Story title link (span variant)"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("automation-lab/ai-selector-repair").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 = {
    "url": "https://news.ycombinator.com",
    "selectors": [
        ".titleline > a",
        "span.titleline > a",
    ],
    "selectorDescriptions": [
        "Story title link on HN front page",
        "Story title link (span variant)",
    ],
}

# Run the Actor and wait for it to finish
run = client.actor("automation-lab/ai-selector-repair").call(run_input=run_input)

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

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

```

## CLI example

```bash
echo '{
  "url": "https://news.ycombinator.com",
  "selectors": [
    ".titleline > a",
    "span.titleline > a"
  ],
  "selectorDescriptions": [
    "Story title link on HN front page",
    "Story title link (span variant)"
  ]
}' |
apify call automation-lab/ai-selector-repair --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=automation-lab/ai-selector-repair",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "AI Selector Repair Tool",
        "description": "Fix broken CSS and XPath selectors with AI. Provide a URL and broken selectors — get back updated, working selectors with confidence scores and explanations of what changed in the page structure.",
        "version": "0.1",
        "x-build-id": "sgvwuIFVDl5NpYnTR"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/automation-lab~ai-selector-repair/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-automation-lab-ai-selector-repair",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        },
        "/acts/automation-lab~ai-selector-repair/runs": {
            "post": {
                "operationId": "runs-sync-automation-lab-ai-selector-repair",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor and returns information about the initiated run in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/runsResponseSchema"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/acts/automation-lab~ai-selector-repair/run-sync": {
            "post": {
                "operationId": "run-sync-automation-lab-ai-selector-repair",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "inputSchema": {
                "type": "object",
                "required": [
                    "url",
                    "selectors"
                ],
                "properties": {
                    "url": {
                        "title": "Page URL",
                        "type": "string",
                        "description": "URL of the page where selectors are broken."
                    },
                    "selectors": {
                        "title": "Broken Selectors",
                        "type": "array",
                        "description": "List of CSS or XPath selectors that no longer work on the target page.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "oldHtml": {
                        "title": "Old HTML Snapshot",
                        "type": "string",
                        "description": "Paste old HTML of the page for better context on what changed. Optional but improves accuracy."
                    },
                    "selectorDescriptions": {
                        "title": "Selector Descriptions",
                        "type": "array",
                        "description": "Describe what each selector was supposed to target (e.g., 'article title link', 'price element'). Must match the order of broken selectors.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "anthropicApiKey": {
                        "title": "Anthropic API Key",
                        "type": "string",
                        "description": "Your Anthropic API key for Claude. Get one at console.anthropic.com."
                    },
                    "openaiApiKey": {
                        "title": "OpenAI API Key",
                        "type": "string",
                        "description": "Your OpenAI API key (alternative to Anthropic). Provide one of: Anthropic, OpenAI, or OpenRouter key."
                    },
                    "openrouterApiKey": {
                        "title": "OpenRouter API Key",
                        "type": "string",
                        "description": "Your OpenRouter API key (alternative to Anthropic/OpenAI). Supports all major models via openrouter.ai."
                    },
                    "model": {
                        "title": "Model",
                        "enum": [
                            "claude-sonnet-4-20250514",
                            "claude-haiku-4-5-20251001",
                            "gpt-4o-mini",
                            "gpt-4o"
                        ],
                        "type": "string",
                        "description": "Select which LLM model to use for analysis.",
                        "default": "claude-sonnet-4-20250514"
                    },
                    "maxHtmlLength": {
                        "title": "Max HTML Length",
                        "minimum": 5000,
                        "maximum": 200000,
                        "type": "integer",
                        "description": "Maximum number of characters of HTML to send to the LLM. Lower values reduce cost but may miss context.",
                        "default": 50000
                    },
                    "proxyConfiguration": {
                        "title": "Proxy Configuration",
                        "type": "object",
                        "description": "Use a proxy to access geo-restricted or blocked pages."
                    }
                }
            },
            "runsResponseSchema": {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "string"
                            },
                            "actId": {
                                "type": "string"
                            },
                            "userId": {
                                "type": "string"
                            },
                            "startedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "finishedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "status": {
                                "type": "string",
                                "example": "READY"
                            },
                            "meta": {
                                "type": "object",
                                "properties": {
                                    "origin": {
                                        "type": "string",
                                        "example": "API"
                                    },
                                    "userAgent": {
                                        "type": "string"
                                    }
                                }
                            },
                            "stats": {
                                "type": "object",
                                "properties": {
                                    "inputBodyLen": {
                                        "type": "integer",
                                        "example": 2000
                                    },
                                    "rebootCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "restartCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "resurrectCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "computeUnits": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "options": {
                                "type": "object",
                                "properties": {
                                    "build": {
                                        "type": "string",
                                        "example": "latest"
                                    },
                                    "timeoutSecs": {
                                        "type": "integer",
                                        "example": 300
                                    },
                                    "memoryMbytes": {
                                        "type": "integer",
                                        "example": 1024
                                    },
                                    "diskMbytes": {
                                        "type": "integer",
                                        "example": 2048
                                    }
                                }
                            },
                            "buildId": {
                                "type": "string"
                            },
                            "defaultKeyValueStoreId": {
                                "type": "string"
                            },
                            "defaultDatasetId": {
                                "type": "string"
                            },
                            "defaultRequestQueueId": {
                                "type": "string"
                            },
                            "buildNumber": {
                                "type": "string",
                                "example": "1.0.0"
                            },
                            "containerUrl": {
                                "type": "string"
                            },
                            "usage": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "integer",
                                        "example": 1
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "usageTotalUsd": {
                                "type": "number",
                                "example": 0.00005
                            },
                            "usageUsd": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "number",
                                        "example": 0.00005
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
