# ADA Website Accessibility Checker: WCAG 2.1 AA, plain language (`examsens.ai/ada-checker`) Actor

Tests web pages against WCAG 2.1 Level A and AA, the standard the US Department of Justice names for state and local government websites under ADA Title II, and explains every problem found in plain language with what to fix. Automated tests only; not a compliance certificate or legal advice.

- **URL**: https://apify.com/examsens.ai/ada-checker.md
- **Developed by:** [Ed Rayyis](https://apify.com/examsens.ai) (community)
- **Categories:** Developer tools, SEO tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $45.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

## ADA Website Accessibility Checker: WCAG 2.1 AA, plain language

Give it your pages, or a site to crawl, and it tests each page against WCAG 2.1 Level A and AA in headless Chrome with axe-core, the open source accessibility rules engine. Every problem found comes with a plain language explanation of what the guideline asks for, a severity rating, the elements affected, and what to change, so you can hand the list to your web team.

This tool runs automated tests. It does not certify that a site meets the ADA, WCAG or any other standard. It does not make a site compliant. It is not legal advice.

### Which standard it checks, and why

The Americans with Disabilities Act (ADA) covers state and local governments under Title II and businesses open to the public under Title III \[5].

**Title II, state and local governments.** In April 2024 the US Department of Justice published a rule that adopts the Web Content Accessibility Guidelines (WCAG) version 2.1, Level AA, as the technical standard for the web content and mobile apps of state and local governments \[2]. The rule, at 28 CFR 35.200, refers to the Level A and AA success criteria and conformance requirements of WCAG 2.1 \[1]. An interim final rule published on 20 April 2026 moved the compliance dates to 26 April 2027 for public entities with a total population of 50,000 or more, and to 26 April 2028 for public entities with a total population under 50,000 and for special district governments \[3]\[4]. In that interim final rule, the Department says it plans further rulemaking on the substance of the 2024 rule \[3].

**Title III, businesses open to the public.** The Department's guidance on web accessibility says it has no regulation setting out detailed web standards, that businesses can choose how they make their online goods and services accessible, and that WCAG and the Section 508 Standards give helpful guidance \[5].

This actor tests against WCAG 2.1 Level A and AA, the standard named in the Title II rule. Every finding names the WCAG 2.1 success criterion it relates to.

### What automated testing can and cannot find

axe-core 4.13.0 runs 62 rules for WCAG 2.1 Level A and AA. Those rules cover 19 of the 50 success criteria at those levels. The rest need a person: whether alt text describes the image, whether captions match what is said, whether every task on a page can be done with a keyboard.

The axe-core project states that the engine finds on average 57% of WCAG issues automatically \[6]. The Department's guidance says a clean report from an automated checker does not by itself mean a site is accessible, and suggests pairing automated checks with a manual check \[5]. A page with no problems in this report can still have barriers. Plan a manual review as well.

### Input

- Pages or sites (required)
- Crawl the site (default off). Follows links from each start page to pages on the same site, skipping files such as PDF and images.
- Maximum pages per site (default 20) and maximum crawl depth (default 2)
- Exclude URLs: regular expressions for crawled links to skip
- Respect robots.txt (default on). Applies to crawled links. Pages you list are always tested.
- List what needs a person to check (default on)
- Device: desktop (1366 by 900) or mobile (iPhone 13 profile)
- One row per affected element (default off), for a flat CSV or Excel export
- Examples per problem (default 5). The full count is always given.
- HTML report (default on)
- Wait until, wait for selector, extra delay (default 1,000 ms), page timeout (default 30 seconds), pages at once (default 3)

### Output

One dataset row per page (`type: page`):

- `url`, `finalUrl`, `status`, `title`, `standardChecked`, `device`
- `summary`: one plain sentence, such as "Found 5 problem types affecting 44 elements. Rated critical: 1.1.1 Non-text Content, 4.1.2 Name, Role, Value."
- `problemCount`, `affectedElementCount`, `highestSeverity`
- `problems`: one entry per WCAG 2.1 success criterion with a problem, most severe first. Each has `criterion`, `criterionName`, `level`, `whatItMeans` (what the criterion asks for, in plain words), `severity`, `affectedElements`, a link to the W3C explanation, and `fixes`. Each fix has the `issue`, `severity`, `howToFix`, a `learnMore` link, and `examples` with the CSS selector and HTML of affected elements.
- `needsHumanReview`: checks the automated tests could not decide, with the criteria they relate to
- `axeVersion`, `checkedAt`

Severity is the impact rating axe-core gives each issue: Critical, Serious, Moderate or Minor.

One summary row per site (`type: summary`): pages tested, pages with problems, pages not tested, affected elements, the ten most common problems with what they mean, a plain summary sentence, a notice on the limits of automated testing, and the link to the HTML report.

With one row per affected element on, each listed element also gets a row (`type: issue`) with the page, criterion, severity, issue, selector, HTML and how to fix.

A page that cannot be tested gets `ok: false` and an `error`: an address that is not a web address, a host that does not resolve, a page that answers with an HTTP error such as 404, or a file such as a PDF. The run carries on with the next page.

The HTML report is saved as `report.html` in the run's key value store. It lists the problems for each site and page in plain language and opens in any browser.

### Pricing

Pay per event: one event per page tested. Pages that cannot be tested are not charged. The run stops when it reaches the maximum charge you set.

### Scope and conduct

Only public pages are opened. The actor does not log in, fill in forms or collect personal data. Each page opens in a fresh browser context with no cookies carried over. No proxies are used. Test sites you are allowed to test.

axe-core 4.13.0 is included unchanged under the Mozilla Public License 2.0 \[7], and its license file ships with the actor.

### Support

Questions and problems: the Issues tab on this page. Replies are written by an AI assistant on behalf of the developer and reviewed by the developer.

### References

\[1] Electronic Code of Federal Regulations, 28 CFR 35.200, Requirements for web and mobile accessibility. https://www.ecfr.gov/current/title-28/chapter-I/part-35/subpart-H/section-35.200

\[2] Federal Register, 24 April 2024, Nondiscrimination on the Basis of Disability; Accessibility of Web Information and Services of State and Local Government Entities, 89 FR 31320, section I.D, Overview of Key Provisions of This Final Rule. https://www.federalregister.gov/documents/2024/04/24/2024-07758/nondiscrimination-on-the-basis-of-disability-accessibility-of-web-information-and-services-of-state

\[3] Federal Register, 20 April 2026, Extension of Compliance Dates for Nondiscrimination on the Basis of Disability; Accessibility of Web Information and Services of State and Local Government Entities, 91 FR 20902, Summary, section I (Background and Legal Authority) and section II (Need for This Interim Rule). https://www.federalregister.gov/documents/2026/04/20/2026-07663/extension-of-compliance-dates-for-nondiscrimination-on-the-basis-of-disability-accessibility-of-web

\[4] ADA.gov, Fact Sheet: New Rule on the Accessibility of Web Content and Mobile Apps Provided by State and Local Governments. https://www.ada.gov/resources/2024-03-08-web-rule/

\[5] ADA.gov, Guidance on Web Accessibility and the ADA, sections "When the ADA Requires Web Content to be Accessible" and "How to Make Web Content Accessible to People with Disabilities". https://www.ada.gov/resources/web-guidance/

\[6] axe-core README, opening section. https://github.com/dequelabs/axe-core

\[7] axe-core LICENSE (Mozilla Public License 2.0). https://github.com/dequelabs/axe-core/blob/develop/LICENSE

# Actor input Schema

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

Pages to test against WCAG 2.1 Level A and AA. With crawling on, each one is also a starting point for finding more pages on the same site.

## `crawl` (type: `boolean`):

Follow links from each start page to other pages on the same site, up to the page and depth limits below.

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

Crawling stops adding pages for a site once this many are queued, start pages included. Each page tested is one billable event.

## `maxCrawlDepth` (type: `integer`):

How many clicks away from a start page the crawl may go. 1 tests the pages linked from the start page.

## `excludePatterns` (type: `array`):

Crawled links that match any of these are skipped, for example /blog/ or ?page=

## `respectRobotsTxt` (type: `boolean`):

Skip crawled links that the robots.txt file of the site disallows. Start pages you list are always tested.

## `includeManualReview` (type: `boolean`):

List the checks the automated tests could not decide, such as text over a background image.

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

Desktop uses a 1366 by 900 window. Mobile uses an iPhone 13 profile (390 by 664 CSS pixels, phone user agent, touch).

## `issueRows` (type: `boolean`):

Also add a dataset row for every affected element listed, for a flat CSV or Excel export to hand to a web team.

## `maxElementsPerRule` (type: `integer`):

How many affected elements to list as examples for each issue on a page. The full count is always given.

## `htmlReport` (type: `boolean`):

Save a plain language report of the whole run as report.html in the key value store. Its link is in each summary row.

## `waitUntil` (type: `string`):

When the page counts as loaded before testing starts.

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

Optional CSS selector to wait for before testing, for pages that build their content with JavaScript.

## `delayMs` (type: `integer`):

Wait this long after loading before testing.

## `timeoutSecs` (type: `integer`):

Give up on a page that does not load within this time.

## `maxConcurrency` (type: `integer`):

How many pages to test in parallel.

## Actor input object example

```json
{
  "startUrls": [
    {
      "url": "https://www.ada.gov/"
    }
  ],
  "crawl": false,
  "maxPagesPerSite": 20,
  "maxCrawlDepth": 2,
  "respectRobotsTxt": true,
  "includeManualReview": true,
  "device": "desktop",
  "issueRows": false,
  "maxElementsPerRule": 5,
  "htmlReport": true,
  "waitUntil": "load",
  "delayMs": 1000,
  "timeoutSecs": 30,
  "maxConcurrency": 3
}
```

# Actor output Schema

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

No description

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

No description

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

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

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "startUrls": [
        {
            "url": "https://www.ada.gov/"
        }
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("examsens.ai/ada-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.ada.gov/" }] }

# Run the Actor and wait for it to finish
run = client.actor("examsens.ai/ada-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.ada.gov/"
    }
  ]
}' |
apify call examsens.ai/ada-checker --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,examsens.ai/ada-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/gW6dYaaxTahYryiIK/builds/SJMPcWG8W8Y9FWfR7/openapi.json
