# Website Accessibility Checker (WCAG 2.1 AA, ADA, AODA, EAA) (`siftwright_data/website-accessibility-checker`) Actor

Check websites for WCAG 2.1 AA accessibility issues in a real browser. Get a score per page and every issue explained in plain English with how to fix it. ADA, AODA and EAA ready.

- **URL**: https://apify.com/siftwright_data/website-accessibility-checker.md
- **Developed by:** [Siftwright Data](https://apify.com/siftwright_data) (community)
- **Categories:** SEO tools, Developer tools
- **Stats:** 3 total users, 2 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$10.00 / 1,000 page checkeds

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 Checker (WCAG 2.1 AA)

Check any website for accessibility problems in a real Chrome browser and get a clear report per page: a score out of 100, how many issues of each severity, and **every issue explained in plain English with how to fix it**. Built on the axe-core rules engine used by most professional accessibility auditors.

Use it to check your own site, audit client sites, monitor a portfolio of stores, or find businesses whose sites need accessibility work.

### Why it matters

- **ADA (United States):** thousands of website accessibility lawsuits are filed every year, most against online stores.
- **AODA (Ontario, Canada):** organizations with 50+ employees must make their public websites meet WCAG 2.0 AA.
- **European Accessibility Act:** applies to e-commerce sites selling to EU consumers since June 2025.

All three point to WCAG AA, which is what this checker tests by default.

### What you get for each page

| Field | Example |
|---|---|
| `score` | 72 (out of 100; weighted by severity and how many elements are affected) |
| `critical` / `serious` / `moderate` / `minor` | 1 / 3 / 1 / 0 issue types |
| `totalIssues` | 46 affected elements |
| `topIssue` | Text that is too faint (31) |
| `violations` | Full list, worst first: title, why it matters, how to fix, WCAG criteria, affected element count, example selectors and HTML |
| `passedChecks`, `needsManualReview` | Rules that passed, and rules that need a human to confirm |

Example issue:

```json
{
  "id": "link-name",
  "impact": "serious",
  "title": "Links and icons with no name",
  "whyItMatters": "A screen reader announces these as just \"link\", so visitors can't tell where they go (often the cart, search or social icons).",
  "howToFix": "Give each icon link a hidden label, e.g. add aria-label=\"Cart\" to the <a> tag, or alt text to the image inside it.",
  "wcag": ["2.4.4", "4.1.2"],
  "affectedElements": 4,
  "examples": [{ "selector": "a.header__icon--cart", "html": "<a href=\"/cart\" class=\"header__icon--cart\">..." }]
}
```

### How to use

1. Paste one or more URLs into **Pages or sites to check**.
2. Leave **Pages per site** at 1 to check just those pages, or raise it (e.g. 10) to also check linked pages on the same site such as collections, product pages and contact.
3. Pick a standard (WCAG 2.1 AA is recommended) and run.
4. Open the **Overview** table for scores at a glance, or export JSON/CSV/Excel for the full issue lists.

Tip: for many sites at once, put one home page per site in the list and keep **Pages per site** small.

### Pricing

**$10 per 1,000 pages checked** ($0.01 per page). Pages that fail to load are not charged. Set a maximum cost per run and the checker stops when it is reached.

### Limits and notes

- Automated checks find roughly a third to a half of WCAG issues. Things like keyboard order, captions and meaningful alt text still need a human review; `needsManualReview` lists the rules that could not be decided automatically.
- Pages behind logins, carts and checkouts are skipped when following links.
- Some sites block automated browsers; those pages return an `error` row and are not charged.

### FAQ

**Is a score of 100 a guarantee of compliance?** No. It means no automated rule failed. Use the report to fix the bulk of issues quickly, then review the rest manually.

**Can I check mobile layouts?** Yes, turn on **Check mobile layout**.

**Can I run it on a schedule?** Yes. Save it as a task and schedule it daily or weekly to catch regressions after theme or content changes.

# Actor input Schema

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

Home pages, product pages or any URLs. Each URL is checked in a real Chrome browser.

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

1 checks only the URLs you give. Higher numbers also follow links on the same site (e.g. 10 checks the home page plus 9 linked pages such as collections, products and contact).

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

Which WCAG rule set to test against. WCAG 2.1 AA is what ADA lawsuits, Ontario AODA and the European Accessibility Act refer to.

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

Also report issues that are not strict WCAG failures but still hurt usability (e.g. missing landmarks, skipped heading levels).

## `maxExamplesPerIssue` (type: `integer`):

How many affected elements (CSS selector + HTML snippet) to include for each issue type.

## `mobile` (type: `boolean`):

Load pages at phone size (390 x 844) instead of desktop (1366 x 900).

## Actor input object example

```json
{
  "startUrls": [
    {
      "url": "https://www.allbirds.com/"
    }
  ],
  "maxPagesPerSite": 1,
  "standard": "wcag21aa",
  "includeBestPractices": false,
  "maxExamplesPerIssue": 3,
  "mobile": false
}
```

# Actor output Schema

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

One row per page.

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

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

# Run the Actor and wait for it to finish
run = client.actor("siftwright_data/website-accessibility-checker").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://www.allbirds.com/"
    }
  ]
}' |
apify call siftwright_data/website-accessibility-checker --silent --output-dataset

```

## MCP server setup

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

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/uyb3I1a6CyPMaZq6j/builds/NlEfCLuab3fEgFai3/openapi.json
