Email Accessibility Check (HTML email templates)
Pricing
from $10.00 / 1,000 template checkeds
Email Accessibility Check (HTML email templates)
Batch-checks HTML email templates for machine-checkable accessibility problems: missing alt text, low colour contrast, missing lang and title, layout tables without role=presentation, heading jumps, vague link text, tiny or all-caps text. One row and one report per template.
Pricing
from $10.00 / 1,000 template checkeds
Rating
0.0
(0)
Developer
Jack Valmadre
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
15 days ago
Last modified
Categories
Security
Limited permissionsShare
Check a batch of HTML email templates for accessibility problems a machine can verify. Give the actor template URLs, paste the HTML, or point it at a key-value store of uploaded .html files. For each template you get one dataset row (counts by severity and rule, plus every finding) and a readable HTML and Markdown report in the key-value store.
Limit: CSS visibility is approximate. Text in a padded box with line-height:0; overflow:hidden can be skipped even when it is readable, including cells with 12px padding. Review those templates in your email clients. This tool does not render emails or replace manual accessibility testing.
Each finding has a rule ID, a severity, a plain-English message, the element's CSS selector path, its line number and a snippet of the start tag, so you can find it in your template.
What it checks
| Rule ID | Severity | What it flags | Based on |
|---|---|---|---|
img-alt-missing | error | <img> with no alt attribute | WCAG 2.2 SC 1.1.1 |
img-spacer-alt | warning | Spacer or tracking image (1-2 px wide/high, or named like spacer.gif) whose alt is not empty | WCAG 2.2 SC 1.1.1 |
img-alt-filename | warning | Alt text that is a file name (IMG_0042.jpg) | WCAG 2.2 SC 1.1.1 |
link-no-name | error | Link with no text and only images with empty or missing alt | WCAG 2.2 SC 2.4.4 |
link-text-vague | warning | Link text such as "click here", "here", "read more", "learn more" | WCAG 2.2 SC 2.4.4 |
link-text-url | warning | Link text that is a bare URL | WCAG 2.2 SC 2.4.4 |
contrast-low | error | Text whose colour and background colour are both declared, with a contrast ratio below 4.5:1 (3:1 for large text: 24px, or 18.66px bold), computed with the WCAG 2.x relative-luminance formula | WCAG 2.2 SC 1.4.3 |
html-lang-missing | error | <html> without lang (or xml:lang) | WCAG 2.2 SC 3.1.1 |
title-missing | warning | No <title>, or an empty one | WCAG 2.2 SC 2.4.2 |
table-role-missing | warning | Table without role="presentation" (or none) that has no <th>, <caption> or summary, so it is treated as a layout table | WCAG 2.2 SC 1.3.1 |
heading-order | warning | Heading level that skips a level (<h1> then <h3>) | WCAG 2.2 SC 1.3.1 (practice check) |
font-size-small | warning | Text with a declared font size below 14px (configurable) | practice check, not a WCAG rule |
all-caps-text | warning | 20+ letters over 3+ words in capitals, typed or via text-transform: uppercase | practice check, not a WCAG rule |
preheader-missing | info | No hidden preheader text before the first visible text | practice check |
Styles are read from inline style attributes, <style> blocks (type, class, ID and descendant selectors, with specificity and !important), and legacy attributes (bgcolor, background, <font color size>, <body text>). The checker skips text it classifies as hidden, including display:none, zero font size, visibility:hidden, mso-hide:all and aria-hidden. Zero height or max-height with overflow:hidden clips block and inline-block boxes in this model; ordinary inline and table boxes are treated differently. Supported font: shorthand sizes, line-height resets and calc() sizes are resolved, so a descendant setting its own size inside a zero-font-size wrapper can be checked. This is a CSS approximation, not browser layout. Padding and partial clipping can cause readable text to be skipped, particularly with zero line height and hidden overflow.
Automated checks use pinned open-source HTML email templates and synthetic CSS regression cases. They do not establish email-client rendering, screen-reader usability or WCAG conformance.
What it does not check
Each report has a Not checked section that counts what the actor could not assess in that template, for example:
- text over background images or gradients (contrast can't be measured from HTML);
- text whose colour or background is not declared (the email client's default applies; we don't guess);
- colours written as
hsl(),var()or other forms it can't resolve; @mediablocks (dark-mode and mobile styles) and complex selectors (pseudo-classes, attribute selectors);- external stylesheets (not fetched);
- text inside images and whether alt text is accurate (needs a person);
- whether a plain-text version is sent (that is set in your email platform, not in the HTML).
This actor does not certify WCAG conformance or legal compliance (for example under accessibility laws). It runs a fixed list of automated checks; many accessibility requirements need a person to judge, and email clients change how HTML is rendered.
Input
- Template URLs: links to raw HTML templates that work without a login. Private and local network addresses are refused; each download has a 30-second network timeout and a 5 MB limit by default.
- HTML templates (pasted): a JSON list of
{"name": "...", "html": "..."}objects, or plain HTML strings. - Key-value store with uploaded templates: pick a store from your account; every record whose key ends in
.html/.htmor whose content type is HTML is checked (or only the keys you list). - Include notes (default on), Minimum font size (default 14px), Maximum template size (default 5 MB).
Up to 500 templates per run.
Output
Dataset: one row per template (view "Templates"; view "Findings" shows one line per finding):
{"name": "newsletter.html", "source": "https://example.com/newsletter.html", "status": "checked","errors": 2, "warnings": 1, "infos": 0,"issuesByRule": {"contrast-low": 1, "img-alt-missing": 1, "link-text-vague": 1},"findings": [{"rule": "contrast-low", "severity": "error", "line": 19,"selector": "html > body > table > tr > td > p:nth-of-type(1)", "snippet": "<p class=\"muted\">","message": "Contrast 2.32:1 (#aaaaaa on #ffffff); needs 4.5:1 for normal text (16px).","text": "Low contrast grey text on white.", "contrastRatio": 2.32, "required": 4.5,"foreground": "#aaaaaa", "background": "#ffffff"}],"notChecked": [{"what": "text over background images (contrast not measurable)", "count": 1}],"reportKey": "001-newsletter.html", "reportUrl": "https://api.apify.com/v2/key-value-stores/.../records/001-newsletter.html"}
(Shortened example.) A template that can't be loaded gets a row with status load-failed and the reason.
Key-value store: NNN-<name>.html and NNN-<name>.md per template, and OUTPUT with run totals.
If your account's storage access is set to Restricted, the reportUrl link opens only while you are signed in to Apify; you can also open the reports from the run's Storage tab.
Pricing
Pay per event:
- US$0.01 per template checked (event
template-checked): each HTML email template that was loaded and checked, whether pasted, fetched from a URL or read from a key-value store. Templates that fail to load (load-failed) and templates listed asskippedare not charged. - Our start charge, once per run: US$0.00005 per GB of run memory, minimum one GB (event
apify-actor-start). At this actor's default 256 MB that is US$0.00005 per run; at its 2 GB maximum, US$0.0001.
There's no extra charge for platform usage. For example, a run that checks 100 templates at the default memory costs 100 × US$0.01 + US$0.00005 = about US$1.00; the prefilled form holds two templates (one URL and one pasted), so running it as it opens costs 2 × US$0.01 plus the start charge. Apify shows the price before you run, and you can cap the cost of a run: if you set a maximum charge per run, the actor stops checking templates when it is reached and gives each remaining template a skipped row, which is not charged.
Privacy
Templates are loaded into the run, checked in memory and written only to your own Apify storage. Nothing is sent anywhere else. Pasted HTML is kept in the run input like any Apify input.
Support
Open an issue on the actor's Issues tab. This actor is built and maintained by AI agents for Madrasco; replies may be AI-assisted and a human owner can be reached on request through the Issues tab.