# ♿ ADA Website Compliance Checker — WCAG Scanner (`upstanding_biobot/ada-wcag-compliance-scan`) Actor

Check any website for ADA/WCAG violations in seconds. 90+ axe-core rules, compliance score, lawsuit risk, element-level details. Bulk scan hundreds of sites. $2/scan, no subscription.

- **URL**: https://apify.com/upstanding\_biobot/ada-wcag-compliance-scan.md
- **Developed by:** [Alexander Maksimchuk](https://apify.com/upstanding_biobot) (community)
- **Categories:** Developer tools, Automation, Other
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$2,000.00 / 1,000 website scans

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/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

## ♿ ADA Website Compliance Checker

Scan any website for ADA/WCAG accessibility violations in seconds. Get every violation with severity, element-level details, fix recommendations, and a compliance score — all powered by axe-core (Deque's industry-standard engine, 90+ rules).

### 📋 Table of Contents

- [What is this?](#-what-is-this)
- [How to use](#-how-to-use)
- [Input](#-input)
- [Output](#-output)
- [JSON output example](#-json-output-example)
- [How much does it cost?](#-how-much-does-it-cost)
- [Use cases](#-use-cases)
- [Integrations](#-integrations)
- [Is it legal?](#-is-it-legal)
- [Troubleshooting](#-troubleshooting)
- [FAQ](#-faq)
- [Tech stack](#-tech-stack)
- [Feedback & issues](#-feedback--issues)

### 🤔 What is this?

ADA Website Compliance Checker is an Apify Actor that automatically tests websites against WCAG 2.1 accessibility standards. It detects violations (missing alt text, poor color contrast, keyboard navigation issues, ARIA errors, etc.) using axe-core — the same engine trusted by Microsoft, Google, and Deque. You get a structured compliance report with severity levels, CSS selectors for every broken element, and direct links to remediation guides.

**Perfect for:** agencies auditing client sites, developers pre-checking before launch, legal teams assessing lawsuit risk, and anyone who needs ADA compliance verification at scale.

### 🚀 How to use

#### Step 1: Add your URLs

In the Apify Console, enter one or more starting URLs you want to scan. You can scan a single page or enable multi-page crawling.

#### Step 2: Configure options (optional)

- **Max pages** — How many pages to crawl per starting URL (default: 1, max: 50)
- **WCAG levels** — Which conformance levels to test (A, AA, AAA)
- **Screenshot** — Capture page screenshots during scan
- **Wait for selector** — CSS selector to wait for before scanning (for SPAs)

#### Step 3: Run the Actor

Click **Start**. The Actor launches a headless Chromium browser, loads each page, runs axe-core, and pushes results to the dataset.

#### Step 4: Export results

- **Dataset** — Download as JSON, CSV, Excel, or XML from the **Output** tab
- **Key-value store** — Final aggregated output in `OUTPUT` key
- **Screenshots** — If enabled, saved as PNG files in key-value store

#### Quick start (API)

```json
{
  "startUrls": [
    { "url": "https://example.com" },
    { "url": "https://yoursite.com/pricing" }
  ],
  "maxPages": 5,
  "screenshot": false
}
````

### 📥 Input

| Field | Type | Default | Description |
|-------|------|---------|-------------|
| `startUrls` | array | **required** | URLs to scan. Format: `[{ "url": "https://..." }]` |
| `maxPages` | integer | 1 | Max pages per starting URL (1–50). Follows internal links. |
| `wcagLevels` | array | `["AA"]` | WCAG conformance levels: `"A"`, `"AA"`, `"AAA"` |
| `timeout` | integer | 30000 | Page load timeout in milliseconds |
| `screenshot` | boolean | false | Capture page screenshots during scan |
| `waitForSelector` | string | — | CSS selector to wait for before scanning (for SPA content) |

### 📤 Output

#### Per-page results (dataset)

Each scanned page is pushed as a dataset item:

| Field | Type | Description |
|-------|------|-------------|
| `url` | string | Page URL scanned |
| `pageTitle` | string | HTML `<title>` of the page |
| `scanDate` | string | ISO 8601 timestamp |
| `summary` | object | Violation counts by severity, compliance score, grade, lawsuit risk |
| `violations` | array | Each violation with ruleId, description, impact, tags, help, helpUrl, affected nodes |
| `passes` | array | Rules that passed |
| `incomplete` | array | Checks requiring manual review |

#### Final output (key-value store)

| Field | Type | Description |
|-------|------|-------------|
| `totalPages` | integer | Total pages scanned |
| `totalViolations` | integer | Aggregate violation count |
| `overallScore` | integer | Average compliance score (0–100) |
| `overallGrade` | string | Overall letter grade (A–F) |
| `overallRisk` | string | Overall lawsuit risk (Low/Medium/High/Critical) |
| `results` | array | Per-page results |

### 📄 JSON output example

Here's real output from scanning `example.com`:

```json
{
  "url": "https://example.com",
  "pageTitle": "Example Domain",
  "scanDate": "2026-07-04T02:15:33.841Z",
  "summary": {
    "totalViolations": 0,
    "critical": 0,
    "serious": 0,
    "moderate": 0,
    "minor": 0,
    "passes": 12,
    "incomplete": 0,
    "complianceScore": 100,
    "grade": "A",
    "lawsuitRisk": "Low"
  },
  "violations": [],
  "passes": [
    { "ruleId": "color-contrast", "description": "Ensures the contrast between foreground and background colors meets WCAG 2 AA contrast ratio thresholds" },
    { "ruleId": "image-alt", "description": "Ensures <img> elements have alternate text or a role of none or presentation" }
  ],
  "incomplete": []
}
```

And here's output from a site **with violations** (redacted for brevity):

```json
{
  "url": "https://example-broken-site.com",
  "pageTitle": "ACME Corp — Home",
  "scanDate": "2026-07-04T02:20:15.123Z",
  "summary": {
    "totalViolations": 4,
    "critical": 1,
    "serious": 2,
    "moderate": 1,
    "minor": 0,
    "passes": 8,
    "incomplete": 2,
    "complianceScore": 62,
    "grade": "D",
    "lawsuitRisk": "High"
  },
  "violations": [
    {
      "ruleId": "html-has-lang",
      "description": "Ensures every HTML document has a lang attribute",
      "impact": "serious",
      "tags": ["cat.language", "wcag2a", "wcag311", "ACT", "TTv5", "TT6.a"],
      "help": "The <html> element must have a lang attribute",
      "helpUrl": "https://dequeuniversity.com/rules/axe/html-has-lang",
      "nodes": [
        {
          "target": ["html"],
          "html": "<html>",
          "failureSummary": "Fix any of the following:\n  The <html> element does not have a lang attribute"
        }
      ]
    },
    {
      "ruleId": "image-alt",
      "description": "Ensures <img> elements have alternate text or a role of none or presentation",
      "impact": "critical",
      "tags": ["cat.text-alternatives", "wcag2a", "wcag111", "section508", "section508.22.a", "TTv5", "TT7.a"],
      "help": "Images must have alternate text",
      "helpUrl": "https://dequeuniversity.com/rules/axe/image-alt",
      "nodes": [
        {
          "target": ["img.hero-logo"],
          "html": "<img src=\"/logo.png\" class=\"hero-logo\">",
          "failureSummary": "Fix any of the following:\n  Element does not have an alt attribute"
        }
      ]
    },
    {
      "ruleId": "color-contrast",
      "description": "Ensures the contrast between foreground and background colors meets WCAG 2 AA contrast ratio thresholds",
      "impact": "serious",
      "tags": ["cat.color", "wcag2aa", "wcag143", "ACT", "TTv5", "TT8.c"],
      "help": "Elements must meet minimum color contrast ratio thresholds",
      "helpUrl": "https://dequeuniversity.com/rules/axe/color-contrast",
      "nodes": [
        {
          "target": [".cta-button"],
          "html": "<a href=\"/contact\" class=\"cta-button\">Contact Us</a>",
          "failureSummary": "Fix any of the following:\n  Element has insufficient color contrast of 2.8:1 (foreground: #999999, background: #f5f5f5, font-size: 14pt, font-weight: normal). Expected contrast ratio of 4.5:1"
        }
      ]
    },
    {
      "ruleId": "label",
      "description": "Ensures every form element has a label",
      "impact": "moderate",
      "tags": ["cat.forms", "wcag2a", "wcag332", "wcag412", "section508", "section508.22.n", "ACT", "TTv5", "TT5.c"],
      "help": "Form elements must have labels",
      "helpUrl": "https://dequeuniversity.com/rules/axe/label",
      "nodes": [
        {
          "target": ["#newsletter-email"],
          "html": "<input type=\"email\" id=\"newsletter-email\" placeholder=\"Email\">",
          "failureSummary": "Fix any of the following:\n  Form element does not have an explicit label\n  Form element does not have an implicit label"
        }
      ]
    }
  ]
}
```

### 💰 How much does it cost?

**$2 per website scan.** No subscription, no monthly fees. Pay only when results are returned.

#### Cost examples

| Use case | Pages | Cost |
|----------|-------|------|
| Single page audit | 1 page | $2 |
| Full website scan (10 pages) | 10 pages | $2 (counted as 1 starting URL, 10 sub-pages crawled) |
| Agency portfolio check (5 clients × 1 page) | 5 URLs | $10 |
| Bulk compliance audit (50 URLs) | 50 URLs | $100 |
| Monthly monitoring (1 site × 12 months) | 12 scans | $24/year |

> **Note:** `maxPages` crawls sub-pages within one starting URL — the $2 charge is per starting URL, not per sub-page. Scanning 1 URL with `maxPages: 50` costs $2, not $100.

### 🎯 Use cases

- **ADA compliance audits** — Scan client websites before/after remediation to measure improvement
- **Lead generation** — Scan prospects' sites, identify violations, pitch remediation services
- **Pre-launch checks** — Catch accessibility issues before deploying to production
- **Risk assessment** — Evaluate lawsuit exposure before demand letters arrive
- **Ongoing monitoring** — Schedule recurring runs to catch accessibility regressions
- **Agency bulk checks** — Scan portfolios of 50+ client sites in one run
- **Legal compliance** — Document WCAG conformance efforts for ADA, Section 508, EAA compliance

### 🔗 Integrations

#### AI agents (MCP)

This Actor works with the **Apify MCP server** (`https://mcp.apify.com`). AI agents like Claude, ChatGPT, and LlamaIndex can discover, configure, and run this Actor autonomously.

```python
## LangChain + Apify integration
from apify_client import ApifyClient
client = ApifyClient("YOUR_APIFY_TOKEN")
run = client.actor("upstanding_biobot/ada-wcag-compliance-scan").call(run_input={
    "startUrls": [{"url": "https://example.com"}]
})
dataset = client.dataset(run["defaultDatasetId"]).list_items()
```

#### Automation platforms

- **Zapier** — Trigger on new scan results → send to Google Sheets, Slack, email
- **Make (Integromat)** — Chain with other Apify Actors for full SEO audit pipelines
- **n8n** — Self-hosted automation workflows
- **Custom webhooks** — Use Apify webhooks to trigger downstream processing on completion

#### Chain with remediation report

Feed scan results directly into our companion Actor — [ADA Website Fix-It Report](https://apify.com/upstanding_biobot/ada-remediation-report) — to generate developer-ready remediation reports with code snippets, cost estimates, and fix timelines.

```json
// Scanner output → Report Actor input
{
  "scanResult": <scanner_dataset_items>
}
```

### ⚖️ Is it legal?

**Yes.** This Actor performs automated accessibility scans using axe-core, an open-source testing engine developed by Deque Systems — the same tool used by accessibility auditors and compliance consultants worldwide.

- **What it does:** Loads public web pages in a browser, runs axe-core WCAG rules, reports violations
- **What it doesn't do:** It does not modify, hack, or breach any website. It simply visits public pages and tests them
- **ADA / WCAG context:** Automated accessibility testing is a recognized best practice for WCAG conformance. The Web Content Accessibility Guidelines (WCAG) are the global standard referenced in ADA compliance litigation
- **Not legal advice:** Automated testing detects ~30-40% of WCAG violations. Manual testing is recommended for full compliance audits. This tool does not constitute legal advice or guarantee legal compliance

### 🔧 Troubleshooting

| Problem | Cause | Fix |
|---------|-------|-----|
| **Timeout error** | Page took too long to load | Increase `timeout` (default 30s). For heavy SPAs, set `waitForSelector` to wait for specific content |
| **0 violations + low score** | Page didn't fully render before scan | Set `waitForSelector` to a key content element. For React/Vue/Angular apps, wait for main content selector |
| **Empty results** | URL unreachable or redirected | Verify URL is accessible in a regular browser. Check for redirects, auth walls, or geographic blocks |
| **Memory error on large crawls** | Too many pages with screenshots | Disable `screenshot` for bulk crawls. Reduce `maxPages` |
| **SPA returns partial results** | Single-page app content not loaded | Use `waitForSelector` targeting the app's root content element (e.g., `#app`, `#root`, `.main-content`) |
| **Sub-pages not found** | No internal links on start page | Check that the starting URL has `<a href>` links to sub-pages. JavaScript-rendered nav may need `waitForSelector` |

### ❓ FAQ

<details>
<summary><strong>What is WCAG and why does it matter?</strong></summary>

WCAG (Web Content Accessibility Guidelines) is the international standard for web accessibility, published by the W3C. It defines how to make web content accessible to people with disabilities — visual, auditory, motor, cognitive. WCAG compliance is increasingly required by law: the ADA (US), Section 508 (US federal), and the European Accessibility Act (EAA) all reference WCAG conformance levels.

</details>

<details>
<summary><strong>What's the difference between WCAG A, AA, and AAA?</strong></summary>

- **Level A** — Minimum requirements (30+ rules). Must-do for basic accessibility.
- **Level AA** — Mid-range (industry standard). Most legal frameworks require AA conformance.
- **Level AAA** — Highest level. Not required for all content, but best practice for critical pages.

This Actor tests all levels by default. Use the `wcagLevels` input to restrict to specific levels.

</details>

<details>
<summary><strong>How accurate is automated testing?</strong></summary>

axe-core detects approximately 30-40% of WCAG violations automatically. It excels at technical issues (missing alt text, ARIA errors, color contrast, HTML structure) but cannot detect all issues — manual testing remains essential for full compliance. Think of automated testing as a first-pass filter that catches the most common, easily-fixable violations.

</details>

<details>
<summary><strong>What is a compliance score?</strong></summary>

The compliance score (0–100) is calculated by weighting violations by severity: critical violations deduct 25 points, serious deduct 10, moderate deduct 5, minor deduct 1. Letter grades map to score ranges: A (95-100), B (85-94), C (70-84), D (50-69), F (0-49).

</details>

<details>
<summary><strong>What is lawsuit risk?</strong></summary>

Lawsuit risk is a qualitative assessment based on violation count and severity:

- **Low** — Fewer than 5 total violations, no serious/critical
- **Medium** — 5+ violations or 2+ serious
- **High** — 10+ violations, 2+ critical, or 5+ serious
- **Critical** — 20+ violations or 5+ critical

This is not a legal assessment — it indicates relative exposure based on common ADA lawsuit patterns.

</details>

<details>
<summary><strong>Can I scan multiple sites at once?</strong></summary>

Yes. Add multiple URLs to the `startUrls` array. Each URL is charged separately ($2/scan). Use `maxPages` to also crawl sub-pages within each starting URL.

</details>

<details>
<summary><strong>Do you offer bulk discounts?</strong></summary>

The $2/scan rate applies to all volumes. For high-volume needs (1000+ scans/month), contact us — custom pricing available for agencies and enterprise.

</details>

<details>
<summary><strong>How do I fix the violations found?</strong></summary>

Each violation includes a `helpUrl` linking to Deque's remediation guide. For developer-ready fix reports with code snippets, cost estimates, and fix timelines, use our companion Actor: [ADA Website Fix-It Report](https://apify.com/upstanding_biobot/ada-remediation-report).

</details>

### 🛠️ Tech stack

- **[axe-core](https://github.com/dequelabs/axe-core)** — Deque's WCAG testing engine (90+ rules, industry standard)
- **[Playwright](https://playwright.dev/)** — Headless Chromium browser automation
- **TypeScript** — Type-safe Actor code
- **[Apify SDK](https://docs.apify.com/sdk/js/)** — Platform integration, dataset, key-value store

### 💬 Feedback & issues

Found a bug? Have a feature request? Want a custom integration?

- **Apify Console** — Use the **Issues** tab on this Actor's page
- **Review** — Leave a rating/review on the Actor's Store page
- **Direct** — We monitor all feedback through the Apify platform

***

*This Actor is not affiliated with Deque Systems. axe-core is an open-source project licensed under MPL 2.0.*

# Actor input Schema

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

URLs to scan for accessibility violations.

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

Maximum number of pages to scan per starting URL. Each page is scanned individually.

## `timeout` (type: `integer`):

Navigation timeout per page in milliseconds.

## `screenshot` (type: `boolean`):

Capture page screenshots during scan.

## `waitForSelector` (type: `string`):

CSS selector to wait for before running scan. Leave empty to scan after page load.

## `webhookUrl` (type: `string`):

POST scan results to this webhook URL when violations found. Use with Zapier, Make, Slack, or custom endpoints for ongoing monitoring alerts.

## `runLighthouse` (type: `boolean`):

Also run Google PageSpeed Insights performance audit alongside accessibility scan. Reports FCP, LCP, CLS, TBT, performance score.

## Actor input object example

```json
{
  "startUrls": [
    {
      "url": "https://example.com"
    }
  ],
  "maxPages": 1,
  "timeout": 30000,
  "screenshot": false,
  "runLighthouse": false
}
```

# 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 = {
    "startUrls": [
        {
            "url": "https://example.com"
        }
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("upstanding_biobot/ada-wcag-compliance-scan").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 = { "startUrls": [{ "url": "https://example.com" }] }

# Run the Actor and wait for it to finish
run = client.actor("upstanding_biobot/ada-wcag-compliance-scan").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 '{
  "startUrls": [
    {
      "url": "https://example.com"
    }
  ]
}' |
apify call upstanding_biobot/ada-wcag-compliance-scan --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=upstanding_biobot/ada-wcag-compliance-scan",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "♿ ADA Website Compliance Checker — WCAG Scanner",
        "description": "Check any website for ADA/WCAG violations in seconds. 90+ axe-core rules, compliance score, lawsuit risk, element-level details. Bulk scan hundreds of sites. $2/scan, no subscription.",
        "version": "1.0",
        "x-build-id": "efGBrk9Rg6phM04eD"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/upstanding_biobot~ada-wcag-compliance-scan/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-upstanding_biobot-ada-wcag-compliance-scan",
                "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/upstanding_biobot~ada-wcag-compliance-scan/runs": {
            "post": {
                "operationId": "runs-sync-upstanding_biobot-ada-wcag-compliance-scan",
                "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/upstanding_biobot~ada-wcag-compliance-scan/run-sync": {
            "post": {
                "operationId": "run-sync-upstanding_biobot-ada-wcag-compliance-scan",
                "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": [
                    "startUrls"
                ],
                "properties": {
                    "startUrls": {
                        "title": "URLs to scan",
                        "type": "array",
                        "description": "URLs to scan for accessibility violations.",
                        "items": {
                            "type": "object",
                            "properties": {
                                "url": {
                                    "type": "string",
                                    "title": "URL",
                                    "description": "URL to scan"
                                }
                            },
                            "required": [
                                "url"
                            ]
                        }
                    },
                    "maxPages": {
                        "title": "Maximum pages per URL",
                        "minimum": 1,
                        "maximum": 50,
                        "type": "integer",
                        "description": "Maximum number of pages to scan per starting URL. Each page is scanned individually.",
                        "default": 1
                    },
                    "timeout": {
                        "title": "Page timeout (ms)",
                        "minimum": 5000,
                        "maximum": 120000,
                        "type": "integer",
                        "description": "Navigation timeout per page in milliseconds.",
                        "default": 30000
                    },
                    "screenshot": {
                        "title": "Capture screenshots",
                        "type": "boolean",
                        "description": "Capture page screenshots during scan.",
                        "default": false
                    },
                    "waitForSelector": {
                        "title": "Wait for CSS selector",
                        "type": "string",
                        "description": "CSS selector to wait for before running scan. Leave empty to scan after page load."
                    },
                    "webhookUrl": {
                        "title": "Webhook URL (bulk monitoring add-on)",
                        "type": "string",
                        "description": "POST scan results to this webhook URL when violations found. Use with Zapier, Make, Slack, or custom endpoints for ongoing monitoring alerts."
                    },
                    "runLighthouse": {
                        "title": "Run Lighthouse audit (add-on)",
                        "type": "boolean",
                        "description": "Also run Google PageSpeed Insights performance audit alongside accessibility scan. Reports FCP, LCP, CLS, TBT, performance score.",
                        "default": false
                    }
                }
            },
            "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
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
