# Website Accessibility Auditor (`master_invictus/accessibility-auditor`) Actor

Crawl a site and audit each page against WCAG 2.x A / AA / AAA with axe-core: violations, impact, selectors, scores.

- **URL**: https://apify.com/master_invictus/accessibility-auditor.md
- **Developed by:** [Frank Nagy](https://apify.com/master_invictus) (community)
- **Categories:** Developer tools, SEO tools
- **Security:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 96.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per event

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

## WCAG Accessibility Auditor (axe-core)

Crawls a website in headless Chromium and runs **axe-core** on every page against **WCAG 2.0/2.1/2.2 Level A, AA or AAA**. Use it for ADA, European Accessibility Act (EAA), AODA (Ontario) and Section 508 self-checks.

**Input:** `startUrls[]` (default and prefill: `https://example.com`, one public page), `maxPages` (default 10), `sameDomain` crawl (default on), `wcagLevel` (A / AA / AAA, default AA), `viewportWidth` / `viewportHeight` (default 1280×800, so you can audit mobile layouts). An empty input uses those defaults.

**Output: one record per page** (`type: "page"`):

- `url`, `finalUrl`, `httpStatus`, `status` (`blocked` when a bot challenge was served), `wcagLevel`
- `violations[]`, each with `id`, `impact` (critical/serious/moderate/minor), `wcagTags`, `help`, `helpUrl`, `nodeCount` and up to 3 `samples` (selector plus an HTML snippet cut to 250 characters)
- `passesCount`, `incompleteCount` (rules that need manual review)
- `summary`, which has `score`, the **MasterInvictus accessibility score (not a WCAG certification)** (0-100, weighted by impact; also given in `scoreLabel`), `violationRules`, `violationNodes` and `byImpact`

**Plus one run summary record** (`type: "summary"`, also saved to the key-value store as `SUMMARY`). It has pages audited, errored, and blocked, the average **MasterInvictus accessibility score (not a WCAG certification)** (`averageScore`), total failing elements and the top 10 violations across the site. A bot-challenge page (Cloudflare "Just a moment...", a `challenges.cloudflare.com` iframe or script, a `cf-chl` marker, or HTTP 403/503 with `cf-ray`) is `status: "blocked"` and is not audited.

**Fails loudly:** the run exits non-zero when the input is invalid or no page could be audited.

**Limits:** automated tools catch roughly 30-50% of WCAG issues. This is not a legal compliance certificate, and manual review is still needed.

### Pricing (pay-per-event): events approved by Money; prices are suggested

| Event | Suggested price |
|---|---|
| `run-started`: custom flat event, charged once per run after the first page is audited successfully (not Apify's memory-scaled `apify-actor-start`). A run that audits zero pages is not charged. | $0.02 |
| `page-audited`: per successfully audited page | $0.005 |

Pages that error or are blocked by a bot challenge are not charged. When publishing, configure `run-started` as a custom event. Do not enable the synthetic start event, which is priced per GB of memory.

### License note

Accessibility rules come from [axe-core](https://github.com/dequelabs/axe-core) by Deque Systems, licensed under **MPL-2.0**, which allows commercial use. axe-core is used unmodified as an npm dependency. Its source and license are available at the link above.

***

Built and maintained by **MasterInvictus**.

# Actor input Schema

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

Pages to audit first. Same-domain links found on them are queued if crawling is on. When omitted, the run audits https://example.com (one public page).

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

Maximum number of pages to audit (each audited page is one billable event).

## `sameDomain` (type: `boolean`):

Follow links on the same host (www. ignored). Off = audit only the start URLs.

## `wcagLevel` (type: `string`):

Which axe-core WCAG tag set to run (cumulative: AA includes A).

## `viewportWidth` (type: `integer`):

Browser viewport width. Use e.g. 390 to audit the mobile layout.

## `viewportHeight` (type: `integer`):

Browser viewport height.

## Actor input object example

```json
{
  "startUrls": [
    {
      "url": "https://example.com"
    }
  ],
  "maxPages": 10,
  "sameDomain": true,
  "wcagLevel": "AA",
  "viewportWidth": 1280,
  "viewportHeight": 800
}
```

# Actor output Schema

## `pages` (type: `string`):

One row per audited page: MasterInvictus accessibility score (not a WCAG certification), failed rules, impact breakdown.

## `violations` (type: `string`):

One row per violated rule per page, with WCAG tags, fix link and sample selectors.

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

Pages audited, average MasterInvictus accessibility score (not a WCAG certification) and top violations across the site.

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

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

```

## MCP server setup

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

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/1kqUMuALCutqhUTdo/builds/x7p7VDoyCugIe3RA1/openapi.json
