# EU Accessibility Act (EAA) Report: WCAG 2.2 & EN 301 549 (`bekservice-ltd/eaa-accessibility-report`) Actor

Check a website against the European Accessibility Act: WCAG 2.2 A/AA failures mapped to EN 301 549 clauses, reflow at 320 px, accessibility statement check, prioritised fixes and a draft accessibility statement.

- **URL**: https://apify.com/bekservice-ltd/eaa-accessibility-report.md
- **Developed by:** [BEK Service LTD](https://apify.com/bekservice-ltd) (community)
- **Categories:** Developer tools, SEO tools, AI
- **Security:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.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

## EU Accessibility Act (EAA) Report: WCAG 2.2 & EN 301 549

Check a website against the **European Accessibility Act** in one run. You get the **WCAG 2.2 level A and AA criteria that fail**, each mapped to its **EN 301 549 clause** (the harmonised standard the EAA relies on), a **prioritised fix list**, a check for an **accessibility statement**, and a **draft accessibility statement** you can edit and publish.

The EAA has applied since **28 June 2025** to many consumer services sold in the EU, including e-commerce, banking, e-books, transport ticketing and electronic communications. Micro-enterprises providing services are exempt; check your national law.

### What you get

For every website:

- **Summary**: criteria failed (of 55 WCAG 2.2 A/AA criteria), split by level A and AA, and the EN 301 549 clauses involved.
- **What to fix first**: failed criteria ordered by severity and by how many pages they affect, with the exact checks that failed, example elements (CSS selectors) and how to fix them.
- **All 55 criteria** with a clear result: *Fails (automated)* or *Not detected, review manually*. We never mark a criterion as "passed", because automated testing cannot prove conformance.
- **Accessibility statement check**: finds a link to an accessibility statement in 20+ EU languages (Accessibility, Barrierefreiheit, Accessibilité, Accessibilità, Accesibilidad, Toegankelijkheid…).
- **Draft accessibility statement** (Markdown) pre-filled with the failures, your organisation name and contact e-mail, clearly marked as a draft.
- A shareable **HTML report** for clients or management.

For every page: the failed WCAG criteria and the full list of issues.

### What is checked

- All **axe-core** rules tagged WCAG 2.0, 2.1 and 2.2 level A and AA (contrast, alternative text, form labels, names/roles/values, headings, lists, link text, language, target size…).
- **Reflow (WCAG 1.4.10)**: the page is rendered at 320 CSS px and horizontal scrolling is reported, excluding the allowed exceptions (tables, maps, code, media).
- **Resize text (1.4.4)**: zoom disabled in the viewport.
- **Target size (2.5.8)**: targets smaller than 24×24 px, respecting the inline-text and spacing exceptions.
- **Page language (3.1.1)** and **page title (2.4.2)**.

### How to use it

1. Add the website URL(s) under **Websites to check**.
2. Choose how many pages per website (default 10).
3. Optional: add your **organisation name** and **accessibility contact e-mail** for the draft statement.
4. Run, open **EAA summary per website**, and click the **HTML report** or **Draft statement** link.

### Output example

```json
{
  "type": "site",
  "site": "shop.example.de",
  "summary": {
    "pagesAudited": 10, "criteriaTotal": 55, "criteriaFailed": 6,
    "criteriaFailedLevelA": 4, "criteriaFailedLevelAA": 2,
    "en301549ClausesFailed": ["9.1.1.1", "9.1.3.1", "9.1.4.3", "9.2.4.4", "9.3.1.1", "9.4.1.2"],
    "automatedVerdict": "non-conformities-found"
  },
  "accessibilityStatementUrl": null,
  "priorities": [
    { "sc": "4.1.2", "name": "Name, Role, Value", "level": "A", "en301549": "9.4.1.2", "severity": "critical", "pages": 8, "fixes": [ { "check": "Form elements must have labels", "howToFix": "…" } ] }
  ],
  "reportUrl": "https://api.apify.com/v2/key-value-stores/…/records/eaa-shop.example.de-report",
  "draftStatementUrl": "https://api.apify.com/v2/key-value-stores/…/records/eaa-shop.example.de-statement"
}
```

### Run it on a schedule with Zapier

Apify has an official Zapier app, so this Actor works in a Zap with no code:

1. **Zap A:** *Schedule by Zapier* (every week or month) → *Apify: Run Actor* with `bekservice-ltd/eaa-accessibility-report` and an input such as `{"startUrls": [{"url": "https://www.example.com"}], "maxPagesPerSite": 10}`.
2. **Zap B:** *Apify: Finished Actor Run* → fetch the dataset items (rows with `type` = `site` are the summaries) → *Google Sheets*, *Gmail* or *Slack*.

For a few pages, *Run Actor and Fetch Results* does both in one step if the run finishes within about five minutes. Step-by-step recipes: https://bekservice.uk/apify-actors/

### Pricing

Pay per event, no subscription:

- **Page checked**: once for each page that is checked.
- **EAA report**: once per website, for the criteria mapping, statement check, HTML report and draft statement.

Pages that cannot be checked (blocked, unreachable, not HTML) are not charged. Set a maximum charge per run in Apify if you want a hard cap.

### Important limits

- **Automated testing finds roughly a third to a half of accessibility barriers.** It can show non-conformance; it can never prove conformance. Keyboard use, screen readers, captions, error handling and checkout journeys need a manual review.
- **Not legal advice and not a certificate.** Whether and how the EAA applies to a business depends on the national law that implements it.
- EN 301 549 v3.2.1 references WCAG 2.1. The six criteria new in WCAG 2.2 are reported as "WCAG 2.2 only".
- The Actor only reads public pages, respects robots.txt, never logs in, submits forms or adds to cart, and collects no personal data.

### Support

Found a false positive or need a language added to the statement check? Open an issue on the Actor's **Issues** tab.

Made by **BEK Service Ltd** (UK).

# Actor input Schema

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

Home page (or any page) of each website. Internal links on the same host are followed up to the page limit.

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

How many pages of each website to check. You pay per checked page.

## `organisationName` (type: `string`):

Optional. Put into the draft accessibility statement.

## `contactEmail` (type: `string`):

Optional. Put into the draft accessibility statement as the feedback contact.

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

Lower this for small or fragile websites.

## Actor input object example

```json
{
  "startUrls": [
    {
      "url": "https://apify.com"
    }
  ],
  "maxPagesPerSite": 10,
  "maxConcurrency": 4
}
```

# Actor output Schema

## `sites` (type: `string`):

No description

## `pages` (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://apify.com"
        }
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("bekservice-ltd/eaa-accessibility-report").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://apify.com" }] }

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

```

## MCP server setup

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

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/9Gifx8VODhdUWcROP/builds/O0FdBRpCTo9dT1h0e/openapi.json
