# Static Accessibility & Site-Health Screening (`memra_media/static-web-screening`) Actor

Screens static HTML for a real subset of WCAG 2.1 A/AA failures plus common site-health issues. No browser, so it is fast and cheap. A screening pass, not an audit.

- **URL**: https://apify.com/memra\_media/static-web-screening.md
- **Developed by:** [ashanti wiggins](https://apify.com/memra_media) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.00 / 1,000 page screeneds

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

## Static Accessibility & Site-Health Screening

Fetches each URL once over HTTP and analyses the returned HTML. **No browser, no JavaScript
execution, no AI.** That makes it fast and cheap — a screening pass you can run across hundreds of
pages before deciding which ones deserve a full audit.

### What this is, and what it is not

**This is a screening pass. It is not an audit and it is not a compliance determination.**

Automated tooling of any kind catches only part of what WCAG requires, and static analysis without
a browser catches less than that. This actor is deliberately honest about the line:

| Checked | Not checked |
|---|---|
| Missing `lang` on `<html>` | Colour contrast |
| Missing or empty `<title>` | Computed ARIA roles |
| `<img>` / `<area>` without `alt` | Focus order and keyboard traps |
| Form fields with no label, `aria-label` or `aria-labelledby` | Anything requiring layout or rendering |
| Links and buttons with no accessible name | Anything injected by JavaScript |
| Skipped heading levels | Screen-reader behaviour |
| Duplicate `id` attributes | Dynamic state and live regions |
| Zoom-blocking `viewport` meta tags | |

**If you need a compliance position, you need a manual audit by a human tester.** This tool is for
triage: finding which pages are obviously broken, cheaply, at scale.

Site-health checks (optional): mixed content on HTTPS pages, missing meta description, missing or
duplicated `<h1>`, missing canonical URL.

### Output

One record per URL:

```json
{
  "url": "https://example.com/book",
  "status": 200,
  "counts": { "total": 9, "critical": 3, "serious": 4, "moderate": 2, "minor": 0 },
  "accessibility": [
    {
      "rule": "image-alt",
      "impact": "critical",
      "claim": "an <img> has no alt attribute (src=\"/hero.png\")",
      "location": "https://example.com/book line 5: <img>",
      "wcag": "1.1.1"
    }
  ],
  "siteHealth": [ ... ],
  "links": ["/menu"],
  "scope": "Static HTML screening. ..."
}
```

Every finding carries a **claim** and a **location** — a line number and the element — so a
developer can go straight to it. Every record carries the scope note, so a result cannot be
quoted out of context.

### Pricing

Pay per page screened. **A page that could not be fetched is not charged** — you do not pay for a
timeout or a 500.

### Input

| Field | Default | Notes |
|---|---|---|
| `urls` | — | Public page URLs. Required. |
| `includeSiteHealth` | `true` | Adds the site-health checks. |
| `maxConcurrency` | `5` | Lower it if a site rate-limits you. |
| `requestTimeoutSecs` | `20` | Per request. |

### Notes

Requests identify themselves as `MemraScreeningBot`. The actor reads public pages only, executes
no JavaScript, submits no forms, and stores nothing beyond the results you see.

Published by **Memra Media Group LLC**.

# Actor input Schema

## `urls` (type: `array`):

Public page URLs. Each is fetched once over HTTP and analysed as static HTML. No JavaScript is executed.

## `includeSiteHealth` (type: `boolean`):

Mixed content, meta description, h1 structure and canonical URL, alongside the accessibility checks.

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

How many pages to fetch at once. Lower this if a site rate-limits you.

## `requestTimeoutSecs` (type: `integer`):

How long to wait for a single page before giving up on it. A page that times out is reported as unfetched and is not charged.

## Actor input object example

```json
{
  "urls": [
    "https://example.com/"
  ],
  "includeSiteHealth": true,
  "maxConcurrency": 5,
  "requestTimeoutSecs": 20
}
```

# Actor output Schema

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

One record per URL: the HTTP status, the accessibility findings, the site-health findings and the counts. A page that could not be fetched appears with its error and is marked as not charged.

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

How many pages were requested, how many were screened and charged for, and how many could not be fetched.

# 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 = {
    "urls": [
        "https://example.com/"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("memra_media/static-web-screening").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 = { "urls": ["https://example.com/"] }

# Run the Actor and wait for it to finish
run = client.actor("memra_media/static-web-screening").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 '{
  "urls": [
    "https://example.com/"
  ]
}' |
apify call memra_media/static-web-screening --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,memra_media/static-web-screening"
        }
    }
}
```

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/dfOPvRNjVRo9Xd90v/builds/NnenZeibQXHO7CcJE/openapi.json
