# Website Accessibility Audit - WCAG 2.2 / EAA Checker (`siteauditlab/website-accessibility-audit`) Actor

Audit whole websites for WCAG 2.1/2.2 accessibility (European Accessibility Act, ADA). Crawls each site, checks every page with axe-core and returns a score, issues by severity, WCAG criteria and fixes, plus a shareable HTML report. Pay per page.

- **URL**: https://apify.com/siteauditlab/website-accessibility-audit.md
- **Developed by:** [Site Audit Lab](https://apify.com/siteauditlab) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $10.00 / 1,000 page auditeds

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

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

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
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.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

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

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Website Accessibility Audit - WCAG 2.2 / EAA Checker

Audit entire websites for accessibility issues in one run. Give a list of websites, and this Actor crawls each one, checks every page against **WCAG 2.0, 2.1 or 2.2** with the industry-standard **axe-core** engine, and returns:

- an **accessibility score out of 100** for every page,
- every issue with its **severity**, the **WCAG success criteria** it breaks, the **failing elements** and **how to fix them**,
- a **shareable HTML report** per run, ready to send to a client or your team.

Built for agencies, developers, compliance teams and anyone preparing for the **European Accessibility Act (EAA)**, in force since June 2025, or for **ADA** and **Section 508** requirements.

### Why use it

- **Whole sites, not one page.** Follows internal links and audits up to the number of pages you choose per site.
- **Bulk.** Audit hundreds of websites in a single run, for example to qualify prospects or monitor client sites.
- **Actionable.** Each issue comes with the exact CSS selector, the HTML snippet and a fix suggestion.
- **Legal mapping.** Issues are mapped to WCAG criteria (for example 1.1.1, 1.4.3, 4.1.2), the reference used by EN 301 549 and the EAA.
- **Desktop or mobile** rendering.
- **Fair pricing.** You pay per page audited. Pages that fail to load are not charged.

### Input

| Field | Description | Default |
| --- | --- | --- |
| Websites to audit | One or more URLs. The audit starts there and follows links of the same website. | required |
| Maximum pages per website | Pages to audit per site. Use 1 to audit only the URLs you entered. | 10 |
| Accessibility standard | WCAG 2.1 AA (EAA / EN 301 549), WCAG 2.2 AA, WCAG 2.0 AA (ADA, Section 508) or WCAG 2.1 AAA | WCAG 2.1 AA |
| Device | Desktop (1366 px) or mobile (390 px) | Desktop |
| Include best practices | Also report recommendations that are not strict WCAG requirements | No |
| Example elements per issue | Failing elements listed per issue | 5 |
| Proxy | Only for websites that block automated visits | None |

Example input:

```json
{
  "startUrls": [{ "url": "https://example.com" }, { "url": "https://another-site.com" }],
  "maxPagesPerSite": 20,
  "standard": "wcag21aa",
  "device": "desktop"
}
```

### Output

One dataset item per page:

```json
{
  "url": "https://example.com/contact",
  "site": "example.com",
  "pageTitle": "Contact us",
  "standard": "WCAG 2.1 AA (EN 301 549 / European Accessibility Act)",
  "score": 60,
  "passesAutomatedChecks": false,
  "issuesTotal": 5,
  "issuesCritical": 3,
  "issuesSerious": 2,
  "issuesModerate": 0,
  "issuesMinor": 0,
  "elementsAffected": 5,
  "rulesPassed": 8,
  "needsManualReview": 0,
  "violations": [
    {
      "ruleId": "image-alt",
      "impact": "critical",
      "issue": "Images must have alternative text",
      "wcagCriteria": ["1.1.1"],
      "elementsAffected": 1,
      "examples": [
        {
          "selector": "img",
          "html": "<img src=\"logo.png\">",
          "howToFix": "Fix any of the following: Element does not have an alt attribute ..."
        }
      ],
      "helpUrl": "https://dequeuniversity.com/rules/axe/4.14/image-alt?application=playwright"
    }
  ],
  "auditedAt": "2026-10-31T01:03:00.000Z"
}
```

The run's key-value store also contains:

- **REPORT**: an HTML report per website with the average score, issues ranked by severity and the pages to fix first.
- **SUMMARY**: the same summary as JSON.

Export the dataset as JSON, CSV, Excel or HTML, or call the Actor through the Apify API, on a schedule or from Make, Zapier and n8n.

### How the score works

Each page starts at 100. Every type of issue found removes points by severity: 10 for critical, 5 for serious, 2 for moderate, 1 for minor. The score helps compare pages and track progress; it is not a legal certification.

### Good to know

- Automated testing finds a large share of common accessibility problems, but not all of them. Items under `needsManualReview` and checks such as keyboard navigation or the meaning of alternative texts still need a human review to claim full conformance.
- The audit loads each page in a real Chrome browser, so content rendered by JavaScript is checked too.
- Only audit websites you own or are allowed to test.

### Next steps after the audit

- **Accessibility statement + PDF report in one run:** [Accessibility Statement Generator](https://apify.com/siteauditlab/accessibility-statement-generator) turns these results into a client-ready PDF and an EAA statement draft (English or French).
- **Free statement generator (no account):** [siteauditlab.dev/declaration-accessibilite](https://www.siteauditlab.dev/declaration-accessibilite/)
- **EAA compliance kit:** statement templates (Word, EN/FR), checklist of the 50 WCAG 2.1 AA criteria and an action plan (Excel): [siteauditlab.dev/kit-eaa](https://www.siteauditlab.dev/kit-eaa/)
- **Performance and SEO:** [Bulk Lighthouse Audit](https://apify.com/siteauditlab/bulk-lighthouse-audit) and [Website SEO Audit](https://apify.com/siteauditlab/website-seo-audit).

### FAQ

**Which standard should I choose for the European Accessibility Act?**
WCAG 2.1 AA, the level referenced by the harmonised standard EN 301 549.

**Can I audit only specific pages?**
Yes. Set "Maximum pages per website" to 1 and list the exact pages.

**Does it work on single-page applications?**
Yes. Pages are rendered in Chrome and audited once the page has loaded.

# Actor input Schema

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

Home page or any page of each website. The audit starts there and follows internal links of the same website.

## `maxPagesPerSite` (type: `integer`):

How many pages to audit for each website. Use 1 to audit only the URLs you entered.

## `standard` (type: `string`):

WCAG 2.1 AA is the level required by the European Accessibility Act (EN 301 549) and most laws.

## `device` (type: `string`):

Screen size used to load the pages.

## `includeBestPractices` (type: `boolean`):

Also report recommended practices that are not strict WCAG requirements.

## `maxElementsPerIssue` (type: `integer`):

How many failing elements (selector, HTML and fix) to list for each issue on a page.

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

Only needed for websites that block automated visits.

## Actor input object example

```json
{
  "startUrls": [
    {
      "url": "https://apify.com"
    }
  ],
  "maxPagesPerSite": 10,
  "standard": "wcag21aa",
  "device": "desktop",
  "includeBestPractices": false,
  "maxElementsPerIssue": 5,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

## `results` (type: `string`):

One item per audited page with score, issues by severity, WCAG criteria and fixes.

## `report` (type: `string`):

Shareable HTML report per website.

## `summary` (type: `string`):

Site-level summary as JSON.

# 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://apify.com"
        }
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("siteauditlab/website-accessibility-audit").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://apify.com" }] }

# Run the Actor and wait for it to finish
run = client.actor("siteauditlab/website-accessibility-audit").call(run_input=run_input)

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

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

```

## CLI example

```bash
echo '{
  "startUrls": [
    {
      "url": "https://apify.com"
    }
  ]
}' |
apify call siteauditlab/website-accessibility-audit --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,siteauditlab/website-accessibility-audit"
        }
    }
}
```

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

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/uzGKeUqX8NiUqj1o8/builds/N6SGQe2aefHXSNgFA/openapi.json
