WCAG Accessibility Audit avatar

WCAG Accessibility Audit

Pricing

from $8.50 / 1,000 domain auditeds

Go to Apify Store
WCAG Accessibility Audit

WCAG Accessibility Audit

Audit any website for WCAG 2.1 and 2.2 AA accessibility issues with axe-core in a real browser. One row per domain: issues by severity, top failing rules, sample elements, a score, and European Accessibility Act exposure signals. Optional statement, Impressum, and privacy checks.

Pricing

from $8.50 / 1,000 domain auditeds

Rating

0.0

(0)

Developer

Mamba Labs

Mamba Labs

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

9 hours ago

Last modified

Share

๐Ÿ”Ž What can WCAG Accessibility Audit do?

Give it a domain. It opens the homepage in a real Chromium browser, runs axe-core 4.14 against the standard you pick, and returns one flat row: the accessibility issues automated checks find, by severity, the worst failing rules, sample elements, a score, and European Accessibility Act (EAA) exposure signals.

Optional compliance checks add an accessibility statement link, an accessibility overlay widget, a privacy policy link, a German Impressum and its required field types, and the US privacy choice link and Global Privacy Control file.

  • Pick the standard. WCAG 2.0 A or AA, WCAG 2.1 AA, WCAG 2.2 AA, Section 508, ADA (the WCAG 2.1 AA set the ADA Title II rule names), or EN 301 549, the European standard the EAA points to.
  • One row per domain. Load a list of domains and get a table you can sort, filter, and join on domain.
  • A real browser, a hard budget. Each page gets 45 seconds. A page that runs past it, blocks the browser, or cannot be reached comes back as a free row that says what happened.
  • EAA exposure signals. EU language, EU hreflang, an EU country code domain, EUR prices, an EU country in the footer, and a cart or checkout. Signals, never a legal finding.
  • Desktop or mobile. Mobile renders at 390 by 844 with touch, where reflow and target size issues show.

๐Ÿ‘ฅ Who this is for

Accessibility and web agencies that want a first pass on a prospect list, EU e-commerce and SaaS teams preparing for the EAA, US teams checking WCAG 2.1 AA exposure under ADA Title II and Section 508, and outbound teams that sell remediation and need a reason to reach out.

โš ๏ธ What automated checks can and cannot tell you

Automated checks find a share of WCAG failures, not all of them. A row with zero failing rules is not a conformance claim, and this actor never says a site is compliant. Rules that axe cannot decide are counted in incomplete and need a human check. The score ranks sites against each other; it is not a grade under any law.

โŒจ๏ธ Input

FieldWhat it does
domainOne website domain, for example mambabuilt.com. The homepage is audited.
domainsOptional list, one row per domain. Used instead of domain when filled.
standardwcag21aa (default), wcag22aa, wcag2aa, wcag2a, section508, ada, or en301549.
pages1 to 5. Pages after the homepage come from the sitemap, or from the homepage navigation.
viewportdesktop (default) or mobile.
compliance_checksAny of accessibility_statement, overlay, privacy_policy, impressum, us_privacy_links.
skipCachefalse reuses an identical audit from the last 24 hours. true audits fresh.
max_charge_usdOptional cost cap for the run. The run stops before a domain that could cross it.

Example input:

{
"domains": ["mambabuilt.com", "example.de"],
"standard": "wcag22aa",
"pages": 2,
"compliance_checks": ["accessibility_statement", "impressum", "overlay"]
}

๐Ÿ“ค Output

One row per domain with 40 fields. Every row carries every field; a value that does not apply is null, never missing.

FieldMeaning
domainThe domain audited, without protocol or www.
url_auditedThe homepage URL after redirects.
standardThe standard whose axe rule tags were run: wcag2a, wcag2aa, wcag21aa, wcag22aa, section508, ada, or en301549.
viewportdesktop (1280 by 800) or mobile (390 by 844).
pages_requestedHow many pages the input asked for, 1 to 5.
pages_auditedHow many pages were rendered and audited. 0 when the homepage could not be audited.
urls_auditedEvery URL that was audited, homepage first.
violations_totalDistinct axe rules with at least one issue found by automated checks, across all audited pages.
violations_criticalFailing rules with impact critical.
violations_seriousFailing rules with impact serious.
violations_moderateFailing rules with impact moderate.
violations_minorFailing rules with impact minor.
violation_nodes_totalPage elements affected, summed over every failing rule and page.
passesDistinct rules that passed on every audited page.
incompleteDistinct rules axe could not decide automatically, which need a human check.
top_rules_jsonJSON array of up to 10 failing rules, worst first: rule_id, impact, nodes, wcag_tags, help_url.
sample_selectors_jsonJSON array of up to 10 CSS selectors of affected elements, as rule_id and selector pairs.
score0 to 100. 100 minus an impact weighted penalty per failing rule. The weights are arbitrary and published in the README. Not a conformance claim.
eaa_exposureTrue when at least one EU market signal is present. A signal for the European Accessibility Act, never a legal finding.
eaa_signalsWhich signals fired: eu_language, eu_hreflang, eu_tld, eur_prices, eu_country_in_footer, checkout.
compliance_checks_requestedThe compliance modes that ran for this row, or null when none were selected.
accessibility_statement_foundMode accessibility_statement: true when the homepage links to an accessibility statement or accessibility page, in any of 13 EU languages.
accessibility_statement_urlMode accessibility_statement: the linked URL.
overlay_detectedMode overlay: true when the homepage loads a known accessibility overlay widget.
overlay_vendorMode overlay: accessibe, userway, audioeye, equalweb, recite_me, max_access, eye_able, user1st, or purple_lens.
privacy_policy_foundMode privacy_policy: true when the homepage links to a privacy policy.
privacy_policy_urlMode privacy_policy: the linked URL.
impressum_foundMode impressum, German language or .de sites only: true when the homepage links to an Impressum. Null when the mode does not apply.
impressum_urlMode impressum: the linked URL.
impressum_fields_presentMode impressum: which required field types appear on the page: address, email, phone, register_number, vat_id, representative. Presence only, never the values.
us_privacy_choice_link_foundMode us_privacy_links: true when the homepage carries a Do Not Sell or Share or Your Privacy Choices link.
gpc_well_known_foundMode us_privacy_links: true when /.well-known/gpc.json answers with a gpc field.
render_statusrendered, blocked (challenge, refusal, or robots.txt), timeout (past the 45 s page budget), unreachable, or error. Only rendered rows are charged.
render_msWall time spent rendering and auditing the pages of this row.
axe_versionThe axe-core engine version that ran.
from_cacheTrue when the row came from the 24 hour cache.
row_statusok, partial (audited, but an extra page or a compliance read failed), or error (nothing audited).
error_reasonWhy a row is partial or error, in plain words. Null on ok rows.
billable_events_jsonJSON array of the events charged for this row, for example [{"event":"domain-audited","count":1}]. [] when free.
checked_atWhen the row was produced, ISO 8601 UTC.

Example row, shortened:

{
"domain": "example.de",
"standard": "wcag21aa",
"pages_audited": 1,
"violations_total": 9,
"violations_critical": 1,
"violations_serious": 4,
"violation_nodes_total": 61,
"score": 58,
"eaa_exposure": true,
"eaa_signals": ["eu_language", "eu_tld", "eur_prices", "checkout"],
"impressum_found": true,
"impressum_fields_present": ["address", "email", "register_number", "vat_id"],
"render_status": "rendered",
"row_status": "ok",
"billable_events_json": "[{\"event\":\"domain-audited\",\"count\":1},{\"event\":\"compliance-checked\",\"count\":1}]"
}

How the score works

100 minus a penalty per failing rule. Each failing rule costs its impact weight (critical 15, serious 8, moderate 4, minor 1), plus up to the same again as the number of affected elements grows toward 10. The floor is 0. The weights are arbitrary and stated here so you can rebuild the number or ignore it and use the counts directly.

๐Ÿ’ต How much does it cost?

Pay per event. You pay for audits that ran, never for a blocked, timed out, or unreachable domain.

EventFree planBronzeSilverGold
domain-audited, one per domain with a rendered audit$0.01000$0.00950$0.00900$0.00850
page-audited, each page after the homepage$0.00200$0.00190$0.00180$0.00170
compliance-checked, once per domain when any compliance check is selected$0.00300$0.00285$0.00270$0.00255
apify-actor-start, once per run$0.00250$0.00250$0.00250$0.00250

That is $10.00 per 1,000 audited homepages on the free plan, $8.50 on Gold, plus $0.0025 per run for the start event, which covers starting the browser container. Batch domains into one run to pay it once.

Free plan cap: free Apify plan users get 150 audited domains a month, which is $1.50 of evaluation. Paid plans have no cap.

Stopping at your limit: the run reads Apify's maximum cost per run and the max_charge_usd input, and stops before starting a domain it could not pay for.

๐Ÿ’ก Usage examples

Apify API

curl -X POST "https://api.apify.com/v2/acts/mambalabs~wcag-accessibility-audit/runs?token=$APIFY_TOKEN" \
-H 'content-type: application/json' \
-d '{"domains":["mambabuilt.com","example.de"],"standard":"wcag22aa"}'

Clay. Add an Apify column, pick this actor, and map your domain column to domain. Every input is read as a string, so Clay's string values work as is. One row comes back per domain.

MCP. The MCP server @mambalabsdev/mcp-wcag-accessibility-audit exposes the tool audit_wcag_accessibility to Claude, Cursor, and any MCP client.

๐Ÿงฏ Error handling

What happenedrender_statusrow_statusCharged
Audit ran on every requested pagerenderedokyes
Audit ran, but an extra page or a compliance read failedrenderedpartialyes, for what ran
Bot challenge, HTTP 403 or 429, or robots.txt disallows the homepageblockederrorno
Page did not finish in 45 secondstimeouterrorno
DNS, TLS, or connection failureunreachableerrorno
Input could not be read as a domainnullerrorno

error_reason says what happened in plain words on every partial and error row.

โš ๏ธ Limitations

  • Automated checks find a subset of WCAG failures. Keyboard flow, screen reader meaning, captions, and most content rules need a human.
  • Only the rendered state after load is audited. Menus, modals, and forms behind a click are not opened.
  • Content inside iframes, such as embedded video players and third party widgets, is not audited.
  • Media and fonts are not loaded, to stay inside 1,024 MB. Color contrast over background images can land in incomplete.
  • EAA scope, and the microenterprise exemption, cannot be read from a page. eaa_exposure is a signal.
  • The Impressum check reports which field types appear, never the values, and runs only on German language or .de sites.
  • Sites behind bot protection return blocked. No proxy is used.
  • The legal references in this README were confirmed on 2026-10-17 from ada.gov, section508.gov, gesetze-im-internet.de, cppa.ca.gov, and the W3C GPC specification. The EUR-Lex pages refused automated reads that day.

โ“ FAQ

Does this call an AI model? No. Every field comes from axe-core rules or a presence check on the page.

Why is a site I know is accessible showing failing rules? axe flags real code issues, and most large sites have some. Read top_rules_json and the help_url for each rule.

Do you respect robots.txt? Yes. A homepage disallowed for all agents is not fetched, and extra pages that are disallowed are skipped.

Is a cached row charged? Yes, at the same price, and from_cache is true on it. Set skipCache to true to audit fresh.

๐Ÿงฉ Want other GTM data?

Mamba Labs builds a fleet of GTM enrichment actors that share one flat, Clay-ready output convention, so their rows join on company_domain with no cleaning step:

๐Ÿ”ญ Account Hiring Watch๐Ÿค– Agent Accessibility Auditor
๐Ÿค– AI Tooling Detector๐Ÿ“ก GTM Signals Aggregator
๐Ÿš€ Prospect Engine๐Ÿ“ Publishing Frequency Tracker
๐Ÿฆ‹ Bluesky Brand Presence Mapper๐Ÿ”€ Career Change Signal Engine
โฉ Sequencer Lead Push๐Ÿ”„ Company Change Event Feed
๐Ÿ“‡ Company Contact Details Extractor๐Ÿงญ Company Discovery List Builder
๐Ÿข Company Firmographic Enricher๐Ÿชช Company Identity Resolver
๐ŸŒ Company Social Presence Mapper๐Ÿท๏ธ Contact Classifier
๐Ÿ“ˆ Influencer Change Monitor๐Ÿ”Ž Influencer Finder
๐Ÿงพ Influencer Lead List Builder๐Ÿ‘ค Influencer Profile Scraper
๐Ÿ“ฌ Domain Deliverability Checker๐Ÿ”— Domain to LinkedIn URL Resolver
๐Ÿ›’ Ecommerce Platform Profilerโœ‰๏ธ Work Email Waterfall
๐ŸŽช Event Presence Indexโš–๏ธ Expert Witness Directory
๐Ÿ’ต Company Funding Record๐Ÿ’ฐ Funding and Press Signal Scanner
๐Ÿ™ GitHub Organization Signal Scanner๐Ÿง‘โ€๐Ÿ’ผ GTM Hiring Signal Scraper
๐Ÿ“‹ Job Posting Monitor๐Ÿงฑ Tech Stack Signal Detector
๐ŸŽฏ ICP Fit Scorer๐Ÿ”‘ Job Board Keyword Signal Scanner
๐Ÿ” Job Change Tracker๐Ÿ›๏ธ Legal Entity Resolver
๐Ÿ“ฐ Link in Bio Scraper and Newsletter Detector๐Ÿ’ผ LinkedIn Company Page Mapper
๐Ÿ’ฌ LinkedIn Post Tracker๐Ÿ“ข Meta Ad Library Monitor
๐Ÿ“ธ Instagram Facebook Brand Presence Mapper๐Ÿ†• New Hire Finder
๐Ÿ“ฎ Outbound Stack Detector๐Ÿ“„ Page Finder and Extractor
๐Ÿง‘ People Finder & Email Verifier๐Ÿ“Œ Pinterest Brand Presence Mapper
๐Ÿ† Government Contract Award Monitor๐Ÿ“… Reporting Window Finder
๐Ÿ‘ฝ Reddit Brand Presence Mapperโญ Trustpilot Reputation Enricher
๐Ÿค Influencer Talent Agency Lookup๐Ÿ‘ฅ Team Page People Extractor
๐ŸŽต TikTok Brand Presence Mapper๐Ÿ“Š Website Traffic Rank Estimator
๐Ÿ… Workplace Program Detectorโœ–๏ธ X Brand Presence Mapper
โ–ถ๏ธ YouTube Channel Stats Extractor

Every actor in the suite takes a domain or a company and returns one flat row, so they stack in the same Clay table without reshaping anything.

๐Ÿ› ๏ธ Need something custom built for you or your team? Tell us what you are trying to find and we will build it. Talk to Mamba Labs.

๐Ÿ†˜ Support

Something wrong, or a site the actor reads incorrectly? Open an issue on the Issues tab with the domain and the row, and we will look at it.

โ„น๏ธ Sourcing and legal. Every field is a property of a website: rule results, link presence, and file presence. The Impressum check reports field types, never names, emails, or numbers. Every fetch honors robots.txt. axe-core is used unmodified under the Mozilla Public License 2.0. You are responsible for how you use the output.

Built by Mamba Labs.