DEVELOPER TOOLSAI

WCAG Accessibility Auditor

Crawl any website and audit it against WCAG 2.1 accessibility standards. Checks 30 rules across four severity levels, scores each site 0–100 with letter grades A through F, and provides element-level violations with CSS selectors and fix recommendations. Test multiple websites in a single run — no browser extensions or manual page-by-page testing required.

Try on Apify Store
$0.25per event
0
Users (30d)
29
Runs (30d)
90
Actively maintained
Maintenance Pulse
$0.25
Per event

Maintenance Pulse

90/100
Last Build
Today
Last Version
1d ago
Builds (30d)
8
Issue Response
N/A

Cost Estimate

How many results do you need?

audit-completeds
Estimated cost:$25.00

Pricing

Pay Per Event model. You only pay for what you use.

EventDescriptionPrice
audit-completedCharged per domain audited. Includes WCAG violation analysis across 4 severity levels, audit scores, grades, and remediation guidance.$0.25

Example: 100 events = $25.00 · 1,000 events = $250.00

Documentation

Crawl any website and audit it against WCAG 2.1 accessibility standards. Checks 30 rules across four severity levels, scores each site 0–100 with letter grades A through F, and provides element-level violations with CSS selectors and fix recommendations. Test multiple websites in a single run — no browser extensions or manual page-by-page testing required.

Why use WCAG Accessibility Auditor?

Accessibility compliance is required by law in many jurisdictions (ADA, Section 508, EN 301 549) but testing is tedious. Browser extensions check one page at a time. Enterprise tools cost thousands per year. This actor runs in the cloud, audits multiple pages per domain, tests multiple websites in a single batch, and produces machine-readable JSON you can pipe into dashboards, Jira, or CI/CD pipelines. Get a scored audit report with actionable fix recommendations for every violation.

Features

  • 30 accessibility rules covering images, forms, headings, ARIA, navigation landmarks, multimedia, tables, and document structure
  • Four severity levels — critical, serious, moderate, and minor — with configurable threshold filtering
  • WCAG 2.1 Levels A, AA, and AAA — choose the conformance level that matches your requirements
  • Multi-page crawling — automatically discovers and audits subpages, up to 50 per domain
  • Accessibility score (0–100) with letter grade (A through F) for quick comparison across sites
  • Actionable fix recommendations for every violation, written in plain language
  • Element-level detail — each violation includes the HTML snippet and CSS selector for easy developer handoff
  • Batch auditing — test dozens of websites in a single run
  • Proxy support — audit geo-restricted or rate-limited sites using Apify Proxy

Use Cases

Compliance auditing

Audit your website against WCAG 2.1 AA (the most common legal requirement) before a compliance deadline. The severity filtering lets you prioritize critical and serious violations first.

Competitor benchmarking

Score competing websites side-by-side and identify accessibility advantages your competitors are missing. Higher accessibility scores improve SEO and user experience.

CI/CD integration

Run accessibility audits automatically after each deployment via the API. Fail the pipeline if the score drops below a threshold.

Agency reporting

Web agencies can audit client websites in batch and generate structured compliance reports with scores, violation counts, and prioritized fix lists.

Regression monitoring

Schedule weekly audits to catch accessibility regressions introduced by new code deployments. Track scores over time to ensure continuous improvement.

Vendor evaluation

Score third-party tools and SaaS platforms for accessibility before procurement decisions. Filter by critical violations to identify deal-breakers.

How to Use

  1. Navigate to the actor's input page on Apify Console
  2. Enter one or more website URLs (e.g., https://example.com)
  3. Adjust Max pages per domain to control audit depth (default: 5)
  4. Select your target WCAG conformance level (A, AA, or AAA)
  5. Set the Minimum severity if you only want serious or critical issues
  6. Click Start to run the audit
  7. View results in the Dataset tab or download as JSON, CSV, or Excel

Input Parameters

ParameterTypeRequiredDefaultDescription
urlsstring[]YesWebsite URLs to audit. Bare domains auto-prefixed with https://
maxPagesPerDomainintegerNo5Maximum pages to crawl and audit per domain (1–50)
wcagLevelstringNoAATarget conformance level: A (minimum), AA (standard), AAA (enhanced)
severityThresholdstringNominorMinimum severity: minor (all), moderate, serious, critical (critical only)
proxyConfigurationobjectNoApify ProxyProxy configuration for crawling

Input Examples

Standard compliance audit:

{
  "urls": ["https://example.com"],
  "maxPagesPerDomain": 10,
  "wcagLevel": "AA",
  "severityThreshold": "minor"
}

Quick critical-only check for multiple sites:

{
  "urls": ["example.com", "competitor1.com", "competitor2.com"],
  "maxPagesPerDomain": 3,
  "wcagLevel": "AA",
  "severityThreshold": "critical"
}

Thorough AAA audit:

{
  "urls": ["https://example.com"],
  "maxPagesPerDomain": 50,
  "wcagLevel": "AAA",
  "severityThreshold": "minor"
}

Input Tips

  • Start with the homepage URL only. The actor automatically discovers and crawls subpages.
  • Use Level AA unless you have a specific reason for A or AAA. AA covers most legal requirements (ADA, Section 508, EN 301 549).
  • Increase maxPagesPerDomain for thorough audits. Default of 5 is good for quick checks; use 20-50 before compliance deadlines.
  • Filter by severity when fixing issues. Start with critical and serious violations for highest impact.

Output Example

Each item in the dataset represents one audited domain:

{
  "url": "https://example.com",
  "domain": "example.com",
  "score": 72,
  "grade": "C",
  "totalViolations": 14,
  "uniqueRulesViolated": 7,
  "violationsBySeverity": {
    "critical": 3,
    "serious": 4,
    "moderate": 5,
    "minor": 2
  },
  "violations": [
    {
      "ruleId": "img-alt",
      "description": "Images must have alt text",
      "severity": "critical",
      "wcagCriteria": "1.1.1",
      "wcagLevel": "A",
      "element": "<img src=\"/hero.jpg\" class=\"banner-image\">",
      "selector": "img.banner-image",
      "fix": "Add an alt attribute to all <img> elements. Use alt=\"\" for decorative images.",
      "pageUrl": "https://example.com"
    }
  ],
  "summary": {
    "critical": ["img-alt: Images must have alt text", "input-label: Form inputs must have associated labels"],
    "serious": ["heading-order: Heading levels should not skip"],
    "moderate": ["link-purpose: Links should not use generic text like 'click here'"],
    "minor": ["landmark-main: Page should have a <main> landmark"]
  },
  "pagesAudited": 5,
  "wcagLevel": "AA",
  "auditedAt": "2025-01-15T10:30:00.000Z"
}

Output Fields

Domain-Level Fields

FieldTypeDescription
urlstringStarting URL for this domain
domainstringNormalized domain name
scorenumberAccessibility score (0–100)
gradestringLetter grade: A (90-100), B (80-89), C (70-79), D (60-69), F (<60)
totalViolationsnumberTotal violation instances found across all pages
uniqueRulesViolatednumberNumber of distinct accessibility rules violated
violationsBySeverityobjectViolation counts broken down by severity level
summaryobjectLists of violated rule descriptions grouped by severity
pagesAuditednumberNumber of pages successfully audited
wcagLevelstringTarget conformance level used (A, AA, or AAA)
auditedAtstringISO 8601 timestamp of the audit

Violation-Level Fields

FieldTypeDescription
ruleIdstringRule identifier (e.g., img-alt, heading-order)
descriptionstringHuman-readable rule description
severitystringcritical, serious, moderate, or minor
wcagCriteriastringWCAG success criterion number (e.g., 1.1.1, 2.4.4)
wcagLevelstringWCAG level of this criterion (A, AA, or AAA)
elementstringHTML snippet of the violating element (truncated to 120 chars)
selectorstringCSS selector to locate the element (e.g., img.banner-image, #header)
fixstringPlain-language fix recommendation
pageUrlstringURL of the page where this violation was found

Programmatic Access (API)

Python

from apify_client import ApifyClient

client = ApifyClient("YOUR_API_TOKEN")

run = client.actor("ryanclinton/wcag-accessibility-auditor").call(run_input={
    "urls": ["https://example.com", "https://competitor.com"],
    "maxPagesPerDomain": 10,
    "wcagLevel": "AA",
    "severityThreshold": "minor",
})

for site in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(f"{site['domain']}: Score {site['score']}/100 ({site['grade']})")
    print(f"  Violations: {site['totalViolations']} ({site['uniqueRulesViolated']} rules)")
    for v in site["violations"]:
        if v["severity"] == "critical":
            print(f"  CRITICAL: {v['description']} on {v['pageUrl']}")

JavaScript

import { ApifyClient } from "apify-client";

const client = new ApifyClient({ token: "YOUR_API_TOKEN" });

const run = await client.actor("ryanclinton/wcag-accessibility-auditor").call({
  urls: ["https://example.com", "https://competitor.com"],
  maxPagesPerDomain: 10,
  wcagLevel: "AA",
  severityThreshold: "minor",
});

const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((site) => {
  console.log(`${site.domain}: ${site.score}/100 (${site.grade})`);
  console.log(`  Critical: ${site.violationsBySeverity.critical}`);
  console.log(`  Serious: ${site.violationsBySeverity.serious}`);
});

cURL

# Start the audit
curl -X POST "https://api.apify.com/v2/acts/ryanclinton~wcag-accessibility-auditor/runs?token=YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "urls": ["https://example.com"],
    "maxPagesPerDomain": 10,
    "wcagLevel": "AA",
    "severityThreshold": "minor"
  }'

# Fetch results (replace DATASET_ID from the run response)
curl "https://api.apify.com/v2/datasets/DATASET_ID/items?token=YOUR_API_TOKEN&format=json"

How It Works

Crawling

A CheerioCrawler starts from each input URL (labeled HOMEPAGE), audits the page, then discovers subpages via enqueueLinks with same-domain filtering. Subpages are audited up to maxPagesPerDomain. The crawler runs with 10 concurrent workers at 120 requests/minute.

Rule Engine

Each page is checked against 30 rules organized by severity. Rules receive the Cheerio $ DOM object and return an array of violations, each with the offending HTML element and a CSS selector. Rules are filtered by the target WCAG level — Level A runs 28 rules, Level AA runs all 30, Level AAA runs all 30.

Scoring Algorithm

The score starts at 100 and deducts points based on unique rules violated (not per-instance counts). This means a site with 50 images missing alt text gets the same penalty as a site with 1 — both violated the img-alt rule once.

SeverityPenalty per RuleMaximum Deduction
Critical-10 points-40 (capped)
Serious-5 points-25 (capped)
Moderate-3 points-15 (capped)
Minor-1 point-10 (capped)

Minimum possible score: 10 (all caps hit: 100 - 40 - 25 - 15 - 10).

GradeScore Range
A90–100
B80–89
C70–79
D60–69
FBelow 60

Results Aggregation

After crawling, violations from all pages are aggregated per domain. A summary groups violated rules by severity. The score and grade are calculated from the unique rules violated across all audited pages.

Accessibility Rules Reference

Critical Rules (6)

Rule IDDescriptionWCAGFix
img-altImages must have alt text1.1.1 (A)Add alt attribute to <img>. Use alt="" for decorative images
input-labelForm inputs must have associated labels1.3.1 (A)Add <label>, aria-label, or aria-labelledby
button-nameButtons must have discernible text4.1.2 (A)Add text, aria-label, or aria-labelledby to buttons
link-nameLinks must have discernible text2.4.4 (A)Add text or aria-label to <a> tags
document-titlePage must have a <title> element2.4.2 (A)Add descriptive <title> in <head>
html-lang<html> must have a lang attribute3.1.1 (A)Add lang="en" (or appropriate code) to <html>

Serious Rules (8)

Rule IDDescriptionWCAGFix
heading-orderHeading levels should not skip1.3.1 (A)Use sequential heading levels (h1 → h2 → h3)
empty-headingHeadings must not be empty1.3.1 (A)Add text content or remove empty headings
duplicate-idElement IDs must be unique4.1.1 (A)Ensure all id attributes are unique
meta-viewportViewport must not disable user scaling1.4.4 (AA)Remove user-scalable=no, set maximum-scale ≥ 2
aria-valid-attrARIA attributes must be valid4.1.2 (A)Use only valid ARIA attributes from WAI-ARIA spec
aria-rolesARIA role values must be valid4.1.2 (A)Use only valid role values from WAI-ARIA spec
frame-titleFrames/iframes must have a title2.4.1 (A)Add title attribute to <iframe> elements
select-nameSelect elements need accessible name1.3.1 (A)Add <label>, aria-label, or title to <select>

Moderate Rules (10)

Rule IDDescriptionWCAGFix
html-lang-validLang attribute must be valid BCP 473.1.1 (A)Use valid language codes (e.g., "en", "fr")
tabindex-positiveAvoid positive tabindex values2.4.3 (A)Use tabindex="0" or tabindex="-1" only
link-purposeAvoid generic link text ("click here")2.4.4 (A)Use descriptive link text
list-structureLists must contain only <li> children1.3.1 (A)Ensure <ul>/<ol> only contain <li>
table-headerData tables should have <th> cells1.3.1 (A)Add <th> elements and <thead> rows
autocomplete-validAutocomplete values must be valid1.3.5 (AA)Use standard autocomplete values
meta-refreshNo auto-refresh via <meta>2.2.1 (A)Remove <meta http-equiv="refresh">
image-redundant-altAlt text shouldn't duplicate surrounding text1.1.1 (A)Use alt="" when text is redundant
textarea-labelTextareas need accessible name1.3.1 (A)Add <label> or aria-label
svg-img-altSVGs with role="img" need accessible text1.1.1 (A)Add aria-label or <title> to SVG

Minor Rules (6)

Rule IDDescriptionWCAGFix
landmark-mainPage should have <main> landmark1.3.1 (A)Add <main> or role="main"
landmark-bannerPage should have <header> landmark1.3.1 (A)Add <header> or role="banner"
bypass-blocksPage should have skip navigation link2.4.1 (A)Add "Skip to main content" link
video-captionVideos should have captions1.2.2 (A)Add <track kind="captions">
audio-captionAudio should have text alternatives1.2.1 (A)Provide transcript or <track>
landmark-navNavigation should use <nav> element1.3.1 (A)Wrap navigation in <nav>

How Much Does It Cost?

The actor uses minimal resources (256 MB memory, Cheerio-based parsing):

ScenarioSitesPages EachEstimated CostRun Time
Quick check15~$0.005~20 seconds
Standard audit120~$0.01~1 minute
Competitor comparison105 each~$0.02~1 minute
Thorough batch1020 each~$0.05~3 minutes
Large batch5010 each~$0.10~8 minutes

Tips

  • Start with the homepage. The actor discovers subpages automatically.
  • Fix critical and serious first. These have the highest impact on users with disabilities and the biggest scoring penalties.
  • Schedule regular audits to catch regressions after code deployments.
  • Compare scores over time. The 0–100 score makes tracking progress straightforward.
  • Use severity filtering to focus developer attention. Show only critical issues in sprint planning; use the full report for quarterly reviews.
  • Export to Jira via webhook or Zapier to auto-create tickets for each critical violation.

Combine with Other Actors

ActorHow to combine
Website Content to MarkdownConvert website content to Markdown while auditing accessibility — parallel workflows
Website Change MonitorDetect page changes, then trigger accessibility re-audit for modified pages
SERP Rank TrackerCorrelate accessibility scores with search rankings to measure SEO impact
Website Tech Stack DetectorIdentify CMS and frameworks — certain tech stacks have common accessibility patterns
Shopify Store IntelligenceAudit Shopify stores for accessibility alongside product and theme analysis

Limitations

  • HTML-only analysis — uses CheerioCrawler, not a headless browser. Cannot evaluate JavaScript-rendered content, dynamic ARIA states, or client-side interactions.
  • No color contrast checking — requires visual rendering to compute contrast ratios, which Cheerio cannot do.
  • No keyboard navigation testing — cannot simulate Tab key traversal or focus management.
  • ~30-40% of WCAG issues — automated tools can detect roughly a third of accessibility problems. Many issues (meaningful alt text, logical focus order, cognitive load) require human judgment.
  • No authenticated content — only audits publicly accessible pages.
  • Rule count — checks 30 rules, not the full WCAG 2.1 specification. Covers the most impactful and automatable criteria.

Responsible Use

  • This actor only accesses publicly visible web pages.
  • Accessibility audit results should be used constructively to improve web accessibility, not to shame or penalize websites.
  • Automated audits are a starting point — always follow up with manual testing and assistive technology testing for full WCAG compliance.
  • See Apify's guide on web scraping legality for general guidance.

FAQ

What WCAG rules does this actor check? 30 rules across four severity tiers. See the Accessibility Rules Reference section above for the complete list with WCAG criteria numbers and fix recommendations.

How is the score calculated? Score starts at 100 and deducts points per unique rule violated (not per instance). Critical: -10 each (cap 40), serious: -5 (cap 25), moderate: -3 (cap 15), minor: -1 (cap 10). Minimum possible score is 10.

Does this replace a manual accessibility audit? No. Automated tools catch roughly 30-40% of WCAG issues. Many problems — meaningful alt text, logical focus order, sufficient color contrast in dynamic states — require human judgment. Use this actor as a first pass, then follow up with manual and assistive technology testing.

Can I audit sites that require authentication? No. The actor audits publicly accessible pages only.

How does this compare to axe-core or Lighthouse? Similar rule coverage to axe-core's best-practice set. Key difference: runs in the cloud, audits multiple sites in batch, and produces structured JSON for integration. Lighthouse also includes performance metrics this actor doesn't cover.

What WCAG level should I use? Level AA for most cases. It covers the requirements of ADA, Section 508, EN 301 549, and most accessibility laws. Level A is the bare minimum. Level AAA is enhanced and rarely required by law.

Integrations

  • Slack — get notified when audits find critical violations or scores drop
  • Google Sheets — export results for tracking and reporting
  • Zapier — create Jira tickets, send Slack alerts, or trigger workflows on completion
  • Make — connect audit results to multi-step automation workflows
  • Apify API — trigger audits from CI/CD pipelines or custom applications
  • Webhooks — POST results to your endpoint on completion
  • GitHub Actions — run audits as part of deployment pipelines

How it works

01

Configure

Set your parameters in the Apify Console or pass them via API.

02

Run

Click Start, trigger via API, webhook, or set up a schedule.

03

Get results

Download as JSON, CSV, or Excel. Integrate with 1,000+ apps.

Use cases

Sales Teams

Build targeted lead lists with verified contact data.

Marketing

Research competitors and identify outreach opportunities.

Data Teams

Automate data collection pipelines with scheduled runs.

Developers

Integrate via REST API or use as an MCP tool in AI workflows.

Ready to try WCAG Accessibility Auditor?

Start for free on Apify. No credit card required.

Open on Apify Store