# Accessibility Scanner (`gabrielaxy/accessibility-scanner`) Actor

Scan any website for WCAG accessibility compliance using axe-core. Get detailed reports with fix code suggestions, severity scores, and remediation priorities. Supports CI/CD integration with threshold-based pass/fail and competitor benchmarking to compare your accessibility against others.

- **URL**: https://apify.com/gabrielaxy/accessibility-scanner.md
- **Developed by:** [Gabriel Antony Xaviour](https://apify.com/gabrielaxy) (community)
- **Categories:** Automation, SEO tools, Developer tools
- **Stats:** 7 total users, 0 monthly users, 100.0% runs succeeded, 0 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/actors/running/actors-in-store.md#pay-per-usage

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — 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

## Accessibility Scanner

Crawl websites and analyze them for WCAG accessibility compliance using axe-core. Helps make the web accessible for people with disabilities by identifying issues like missing alt text, color contrast problems, keyboard navigation failures, and more.

### Features

- **WCAG Compliance Testing**: Test against WCAG 2.0/2.1 at A, AA, or AAA levels
- **Multi-page Crawling**: Automatically discover and audit all pages on a website
- **Issue Categorization**: Issues grouped by severity (critical, serious, moderate, minor)
- **Compliance Score**: Get an overall accessibility score (0-100)
- **Multiple Output Formats**: JSON, HTML report, or CSV export
- **Screenshots**: Visual evidence of pages with accessibility issues
- **Remediation Guide**: Prioritized list of fixes with quick wins highlighted
- **Fix Code Snippets**: Automatic before/after code suggestions for each issue
- **CI/CD Integration**: Threshold-based pass/fail with SARIF output for GitHub
- **Competitor Benchmarking**: Compare your score against competitors

### Input

| Field | Type | Description | Default |
|-------|------|-------------|---------|
| `startUrl` | string | URL of the website to audit | (required) |
| `maxPages` | integer | Maximum pages to crawl (1-500) | 50 |
| `wcagLevel` | string | WCAG level: wcag2a, wcag2aa, wcag2aaa, wcag21a, wcag21aa, wcag21aaa | wcag21aa |
| `includeGlobs` | array | Only audit URLs matching these patterns | \[] |
| `excludeGlobs` | array | Skip URLs matching these patterns | \["**/login**", "**/admin**"] |
| `outputFormat` | string | Output format: json, html, csv | html |
| `generateScreenshots` | boolean | Capture screenshots of pages with issues | true |
| `proxyConfig` | object | Proxy configuration | {} |

### Output

#### Summary (OUTPUT key)

```json
{
  "summary": {
    "startUrl": "https://example.com/",
    "wcagLevel": "wcag21aa",
    "pagesScanned": 50,
    "totalIssues": 234,
    "critical": 12,
    "serious": 45,
    "moderate": 89,
    "minor": 88,
    "wcagScore": 62,
    "scanDuration": 120,
    "timestamp": "2024-01-15T10:30:00Z"
  },
  "issues": [...],
  "pageBreakdown": [...],
  "remediation": {
    "quickWins": [...],
    "majorEffort": [...]
  }
}
```

#### Dataset

Each page result is pushed to the dataset with:

- URL, title, timestamp
- All accessibility issues found
- Issue counts by severity
- Screenshot key (if enabled)

#### Reports

- `accessibility-report` - Full report in requested format (JSON/HTML/CSV)
- `screenshot-*` - Screenshots of pages with issues

### Accessibility Checks

Based on [axe-core](https://github.com/dequelabs/axe-core), this actor checks for:

- **Images**: Missing alt text, decorative images
- **Color**: Contrast ratios, color-only information
- **Forms**: Missing labels, error identification
- **Navigation**: Keyboard accessibility, skip links, focus indicators
- **Structure**: Heading hierarchy, landmarks, lists
- **Links**: Descriptive link text
- **Tables**: Headers, captions, scope attributes
- **ARIA**: Valid roles, required attributes
- **Language**: Document language specification

### Example

Audit a website for WCAG 2.1 AA compliance:

```json
{
  "startUrl": "https://example.com/",
  "maxPages": 100,
  "wcagLevel": "wcag21aa",
  "outputFormat": "html",
  "generateScreenshots": true
}
```

### CI/CD Integration

The scanner supports CI/CD pipeline integration with threshold-based pass/fail and SARIF output for GitHub Code Scanning.

#### CI/CD Input Options

| Field | Type | Description | Default |
|-------|------|-------------|---------|
| `ciMode` | boolean | Enable CI/CD integration with threshold checks | false |
| `scoreThreshold` | integer | Fail if accessibility score is below this value (0-100) | 70 |
| `maxCriticalIssues` | integer | Fail if critical issues exceed this count | 0 |
| `outputSarif` | boolean | Generate SARIF format for GitHub Code Scanning | false |

#### GitHub Actions Example

```yaml
## .github/workflows/accessibility.yml
name: Accessibility Check

on: [push, pull_request]

jobs:
  a11y:
    runs-on: ubuntu-latest
    steps:
      - name: Run Accessibility Scan
        uses: apify/apify-action@v1
        with:
          actor: your-username/accessibility-scanner
          input: |
            {
              "startUrl": "${{ github.event.repository.homepage }}",
              "ciMode": true,
              "scoreThreshold": 80,
              "maxCriticalIssues": 0,
              "outputSarif": true
            }
          token: ${{ secrets.APIFY_TOKEN }}

      - name: Upload SARIF to GitHub Security
        uses: github/codeql-action/upload-sarif@v2
        with:
          sarif_file: accessibility-report-sarif.json
        if: always()
```

#### CI/CD Example Input

Run with strict accessibility requirements:

```json
{
  "startUrl": "https://example.com/",
  "maxPages": 50,
  "ciMode": true,
  "scoreThreshold": 80,
  "maxCriticalIssues": 0,
  "outputSarif": true
}
```

The actor will exit with code 1 if:

- The accessibility score is below the threshold
- The number of critical issues exceeds the maximum allowed

### Competitor Benchmarking

Compare your website's accessibility against competitors with the benchmark mode.

#### Benchmark Input Options

| Field | Type | Description | Default |
|-------|------|-------------|---------|
| `benchmarkMode` | boolean | Enable competitor comparison mode | false |
| `competitorUrls` | array | List of competitor URLs to compare against | \[] |
| `pagesPerSite` | integer | Number of pages to scan per site (1-50) | 10 |

#### Benchmark Example

```json
{
  "startUrl": "https://your-site.com/",
  "benchmarkMode": true,
  "competitorUrls": [
    "https://competitor-a.com/",
    "https://competitor-b.com/"
  ],
  "pagesPerSite": 10,
  "outputFormat": "html"
}
```

#### Benchmark Output

The benchmark report includes:

- **Your Score**: Your site's accessibility score (0-100)
- **Ranking**: Where you stand among competitors (#1, #2, etc.)
- **Industry Average**: Average score across all scanned sites
- **Comparison Chart**: Visual bar chart comparing all sites
- **Recommendations**: Actionable insights like "You're X points below average"

### Understanding the Score

The accessibility score (0-100) is calculated based on:

- **Critical issues**: -10 points each
- **Serious issues**: -5 points each
- **Moderate issues**: -2 points each
- **Minor issues**: -1 point each

Score grades:

- **A (90-100)**: Excellent accessibility
- **B (80-89)**: Good accessibility
- **C (70-79)**: Fair accessibility
- **D (60-69)**: Poor accessibility
- **F (0-59)**: Failing accessibility

### Why Accessibility Matters

- **1 billion people** worldwide have disabilities
- **98% of websites** fail basic accessibility standards
- Legal requirements (ADA, Section 508, WCAG) make this valuable for organizations
- Better accessibility improves SEO and user experience for everyone

### Limitations

- JavaScript-heavy SPAs may require additional configuration
- Some dynamic content loaded after page load may be missed
- Automated testing catches ~30% of accessibility issues; manual testing is still recommended
- Rate limiting may apply to large sites

### Testing Tip

Use the [W3C BAD (Before and After Demonstration)](https://www.w3.org/WAI/demos/bad/before/home.html) site to test the scanner - it's intentionally inaccessible!

### Support

For issues or feature requests, please open an issue on GitHub.

### Resources

- [WCAG 2.1 Guidelines](https://www.w3.org/TR/WCAG21/)
- [axe-core Rules](https://dequeuniversity.com/rules/axe/4.8)
- [WebAIM Contrast Checker](https://webaim.org/resources/contrastchecker/)

# Actor input Schema

## `startUrl` (type: `string`):

URL of the website to audit for accessibility

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

Maximum number of pages to audit

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

WCAG conformance level to test against

## `includeGlobs` (type: `array`):

Only audit URLs matching these patterns

## `excludeGlobs` (type: `array`):

Skip URLs matching these patterns

## `outputFormat` (type: `string`):

Format for the accessibility report output

## `generateScreenshots` (type: `boolean`):

Capture screenshots of pages with issues

## `proxyConfig` (type: `object`):

Proxy configuration for requests

## `ciMode` (type: `boolean`):

Enable CI/CD integration with threshold checks

## `scoreThreshold` (type: `integer`):

Fail if accessibility score is below this value (0-100)

## `maxCriticalIssues` (type: `integer`):

Fail if critical issues exceed this count

## `outputSarif` (type: `boolean`):

Generate SARIF format for GitHub Code Scanning

## `benchmarkMode` (type: `boolean`):

Compare accessibility against multiple sites

## `competitorUrls` (type: `array`):

List of competitor URLs to compare against

## `pagesPerSite` (type: `integer`):

Number of pages to scan per site in benchmark mode

## Actor input object example

```json
{
  "startUrl": "https://example.com/",
  "maxPages": 50,
  "wcagLevel": "wcag21aa",
  "excludeGlobs": [
    "**/login**",
    "**/admin**"
  ],
  "outputFormat": "html",
  "generateScreenshots": true,
  "ciMode": false,
  "scoreThreshold": 70,
  "maxCriticalIssues": 0,
  "outputSarif": false,
  "benchmarkMode": false,
  "competitorUrls": [],
  "pagesPerSite": 10
}
```

# Actor output Schema

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

Dataset containing all accessibility issues found per page with severity, WCAG guidelines, and fix suggestions

# 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 = {
    "startUrl": "https://example.com/",
    "excludeGlobs": [
        "**/login**",
        "**/admin**"
    ],
    "competitorUrls": []
};

// Run the Actor and wait for it to finish
const run = await client.actor("gabrielaxy/accessibility-scanner").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 = {
    "startUrl": "https://example.com/",
    "excludeGlobs": [
        "**/login**",
        "**/admin**",
    ],
    "competitorUrls": [],
}

# Run the Actor and wait for it to finish
run = client.actor("gabrielaxy/accessibility-scanner").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 '{
  "startUrl": "https://example.com/",
  "excludeGlobs": [
    "**/login**",
    "**/admin**"
  ],
  "competitorUrls": []
}' |
apify call gabrielaxy/accessibility-scanner --silent --output-dataset

```

## MCP server setup

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

```

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/OyXzdLsk9OxQm6c6p/builds/t3Ql32jI08swL2Dhb/openapi.json
