# ♿ WCAG 2.2 Accessibility Auditor — Bulk axe-core (`nexgendata/wcag-accessibility-auditor`) Actor

Bulk WCAG 2.2 accessibility auditor. Render sites with Chrome, scan with axe-core, return violations, severity, and score.

- **URL**: https://apify.com/nexgendata/wcag-accessibility-auditor.md
- **Developed by:** [Stephan Corbeil](https://apify.com/nexgendata) (community)
- **Categories:** Developer tools, Automation, Marketing
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, NaN bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per usage

This Actor is paid per platform usage. The Actor is free to use, and you only pay for the Apify platform usage, which gets cheaper the higher subscription plan you have.

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

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

## ♿ WCAG 2.2 Accessibility Auditor — Bulk axe-core

> **Audit any website for WCAG 2.2 AA compliance in seconds.** Headless Chrome renders each page, axe-core scans for violations, and you get a structured report per URL — severity, WCAG tags, failing selectors, HTML snippets, and a 0-100 accessibility score.

**Why this exists:** Enterprise accessibility platforms (Siteimprove, AudioEye, Monsido, Deque axe DevTools Pro) charge $5k–$100k/year for site-wide audits. The open-source `axe-core` engine they all use under the hood is free and MPL-licensed. This actor wraps `axe-core` in a headless Chrome runner with a clean JSON output — so devs, agencies, and SMBs can audit hundreds of pages for cents, then fix issues without paying for a dashboard they'll check twice a year.

### 🔑 Features

- **WCAG 2.2 AA by default** — includes `wcag2a`, `wcag2aa`, `wcag21aa`, `wcag22aa` tag sets
- **axe-core 4.10.0** — same engine used by Deque, Microsoft Accessibility Insights, Google Lighthouse
- **Bulk mode** — audit 100 URLs in one run, pay per URL audited
- **Severity breakdown** — critical / serious / moderate / minor counts per page
- **Top-25 failing rules** — with CSS selector, HTML snippet, and human-readable failure summary
- **0-100 accessibility score** — severity-weighted, deterministic, comparable across runs
- **Real browser rendering** — catches client-side React / Vue / Angular issues that static HTML scanners miss
- **Custom WCAG tag config** — audit against 2.0, 2.1, 2.2, or best-practice only

### 💼 Common Use Cases

- **Legal compliance** — ADA, EN 301 549, Section 508 spot-checks before launch
- **Agencies & consultancies** — white-label audits for client sites at bulk pricing
- **CI/CD gating** — fail builds on critical WCAG violations
- **Pre-redesign baseline** — scan the current site before a redesign, track improvement
- **SEO audits** — accessibility overlaps with SEO (alt text, heading structure, link labels)
- **Procurement** — audit vendor SaaS tools you're evaluating for a11y compliance
- **Lawsuit risk reduction** — screen for low-hanging a11y issues that drive serial-plaintiff demand letters

### 📥 Input Example

```json
{
  "urls": [
    "https://example.com/",
    "https://example.com/products",
    "https://example.com/checkout"
  ],
  "wcagTags": ["wcag2a", "wcag2aa", "wcag22aa"],
  "timeoutMs": 25000
}
````

### 📤 Output (per URL)

```json
{
  "url": "https://example.com/",
  "audit_engine": "axe-core 4.10.0",
  "wcag_version": "2.2",
  "total_violations": 7,
  "total_passes": 38,
  "total_incomplete": 2,
  "total_inapplicable": 62,
  "severity_breakdown": {
    "critical": 1,
    "serious": 3,
    "moderate": 2,
    "minor": 1
  },
  "wcag_tag_coverage": {
    "wcag2a": 4,
    "wcag2aa": 5,
    "wcag22aa": 1
  },
  "accessibility_score": 62,
  "top_violations": [
    {
      "rule_id": "color-contrast",
      "impact": "serious",
      "description": "Ensures the contrast between foreground and background colors meets WCAG 2 AA contrast ratio thresholds",
      "help": "Elements must meet minimum color contrast ratio thresholds",
      "help_url": "https://dequeuniversity.com/rules/axe/4.10/color-contrast",
      "wcag_tags": ["wcag2aa", "wcag143"],
      "affected_nodes": 8,
      "sample_selectors": [".nav-link", ".btn-secondary", "footer a"],
      "sample_html": ["<a class='nav-link' ...", "<button class='btn-secondary' ...", "<a href='/privacy' ..."],
      "failure_summary": "Fix any of the following:\n  Element has insufficient color contrast of 3.2:1 ..."
    }
  ]
}
```

### 🐍 Python SDK Example

```python
from apify_client import ApifyClient

client = ApifyClient("YOUR_APIFY_TOKEN")
run = client.actor("nexgendata/wcag-accessibility-auditor").call(run_input={
    "urls": [
        "https://example.com/",
        "https://example.com/about"
    ]
})

for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(f"{item['url']} → score {item['accessibility_score']} "
          f"({item['total_violations']} violations)")
    for v in item["top_violations"][:3]:
        print(f"  [{v['impact']}] {v['rule_id']} — {v['affected_nodes']} nodes")
```

### 🌐 cURL Example

```bash
curl -X POST "https://api.apify.com/v2/acts/nexgendata~wcag-accessibility-auditor/run-sync-get-dataset-items?token=YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "urls": ["https://example.com/"]
  }'
```

### 🔗 Zapier / Make.com / GitHub Actions Integration

- **GitHub Action** — run on every PR, comment on violations introduced
- **Zapier** — new page published in CMS → audit → Slack alert if score drops
- **Weekly cron** — scan your whole sitemap, track score trends over time

### ❓ FAQ

**Q: What's the difference between this and Google Lighthouse's accessibility audit?**
Lighthouse also uses axe-core under the hood, but runs only on one page at a time from DevTools. This actor is a bulk API wrapper — run it on 500 URLs programmatically and get machine-parseable JSON per page.

**Q: What WCAG version is covered?**
WCAG 2.0, 2.1, and 2.2 (Level A and AA) by default. Configure the `wcagTags` input to narrow to a specific version.

**Q: Does this catch all accessibility issues?**
No automated tool does. axe-core catches roughly 30-40% of WCAG issues — primarily the objective ones (color contrast, missing alt text, missing labels, ARIA misuse). Human testing with screen readers is still needed for the full picture. But automated audits are the cheapest way to catch the bulk of fixable issues fast.

**Q: Does it handle logged-in pages?**
Not yet. Pass only publicly-accessible URLs for now. Authentication support is on the roadmap.

**Q: What's the accessibility score based on?**
Severity-weighted deduction: critical=-15, serious=-8, moderate=-3, minor=-1, scaled by affected node count. A clean site scores 100; typical SMB sites land in 50-80 range.

**Q: Is axe-core's output reliable?**
Yes. axe-core is maintained by Deque Systems (the accessibility firm), is used by Microsoft, Google, IBM, Adobe, and has the lowest false-positive rate of any automated a11y scanner. It's the industry standard.

### 💰 Pricing (Pay-Per-Event)

- **Actor start:** $0.005
- **URL audited:** $0.01

Typical run cost: 100-URL scan = $1.005. Compare with Siteimprove (~$10k/yr starter plans) or enterprise axe DevTools Pro ($495/user/yr).

### 🔗 Related NexGenData Actors

- [Facebook Ads Library Scraper](https://apify.com/nexgendata/facebook-ads-library-scraper?fpr=2ayu9b) — research competitor ads for a/b positioning
- [Google Trends Scraper](https://apify.com/nexgendata/google-trends-scraper?fpr=2ayu9b) — track accessibility search interest
- [SaaS Pricing Tracker](https://apify.com/nexgendata/saas-pricing-tracker?fpr=2ayu9b) — compare a11y tool pricing

### 🚀 Apify Affiliate Program

New to Apify? Sign up with our [referral link](https://www.apify.com/?fpr=2ayu9b) for free platform credits.

***

*Automated WCAG 2.2 AA auditing for developers, agencies, and procurement teams who need real accessibility scans without enterprise SaaS pricing. Built by NexGenData.*

# Actor input Schema

## `urls` (type: `array`):

List of page URLs to audit (one per line). Each page is rendered with headless Chrome and scanned by axe-core.

## `wcagTags` (type: `array`):

Which WCAG tags to test against. Defaults cover WCAG 2.2 AA. Common values: wcag2a, wcag2aa, wcag21a, wcag21aa, wcag22aa, best-practice.

## `timeoutMs` (type: `integer`):

How long to wait for each page's DOMContentLoaded event before giving up.

## Actor input object example

```json
{
  "urls": [
    "https://www.w3.org/WAI/demos/bad/",
    "https://example.com/"
  ],
  "wcagTags": [
    "wcag2a",
    "wcag2aa",
    "wcag21aa",
    "wcag22aa"
  ],
  "timeoutMs": 25000
}
```

# 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 = {
    "urls": [
        "https://www.w3.org/WAI/demos/bad/",
        "https://example.com/"
    ],
    "wcagTags": [
        "wcag2a",
        "wcag2aa",
        "wcag21aa",
        "wcag22aa"
    ],
    "timeoutMs": 25000
};

// Run the Actor and wait for it to finish
const run = await client.actor("nexgendata/wcag-accessibility-auditor").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 = {
    "urls": [
        "https://www.w3.org/WAI/demos/bad/",
        "https://example.com/",
    ],
    "wcagTags": [
        "wcag2a",
        "wcag2aa",
        "wcag21aa",
        "wcag22aa",
    ],
    "timeoutMs": 25000,
}

# Run the Actor and wait for it to finish
run = client.actor("nexgendata/wcag-accessibility-auditor").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 '{
  "urls": [
    "https://www.w3.org/WAI/demos/bad/",
    "https://example.com/"
  ],
  "wcagTags": [
    "wcag2a",
    "wcag2aa",
    "wcag21aa",
    "wcag22aa"
  ],
  "timeoutMs": 25000
}' |
apify call nexgendata/wcag-accessibility-auditor --silent --output-dataset

```

## MCP server setup

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

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "♿ WCAG 2.2 Accessibility Auditor — Bulk axe-core",
        "description": "Bulk WCAG 2.2 accessibility auditor. Render sites with Chrome, scan with axe-core, return violations, severity, and score.",
        "version": "0.0",
        "x-build-id": "lrVSEE2rL7a89jqJG"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/nexgendata~wcag-accessibility-auditor/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-nexgendata-wcag-accessibility-auditor",
                "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/nexgendata~wcag-accessibility-auditor/runs": {
            "post": {
                "operationId": "runs-sync-nexgendata-wcag-accessibility-auditor",
                "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/nexgendata~wcag-accessibility-auditor/run-sync": {
            "post": {
                "operationId": "run-sync-nexgendata-wcag-accessibility-auditor",
                "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": [
                    "urls"
                ],
                "properties": {
                    "urls": {
                        "title": "URLs to audit",
                        "type": "array",
                        "description": "List of page URLs to audit (one per line). Each page is rendered with headless Chrome and scanned by axe-core.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "wcagTags": {
                        "title": "WCAG conformance tags",
                        "type": "array",
                        "description": "Which WCAG tags to test against. Defaults cover WCAG 2.2 AA. Common values: wcag2a, wcag2aa, wcag21a, wcag21aa, wcag22aa, best-practice.",
                        "default": [
                            "wcag2a",
                            "wcag2aa",
                            "wcag21aa",
                            "wcag22aa"
                        ],
                        "items": {
                            "type": "string"
                        }
                    },
                    "timeoutMs": {
                        "title": "Per-page load timeout (milliseconds)",
                        "minimum": 5000,
                        "maximum": 120000,
                        "type": "integer",
                        "description": "How long to wait for each page's DOMContentLoaded event before giving up.",
                        "default": 25000
                    }
                }
            },
            "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
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
