# Email Checker (`smart-api/email-checker`) Actor

Check email HTML for client compatibility and accessibility through a simple API. The Actor checks unsupported HTML and CSS across Gmail, Outlook, Apple Mail, Yahoo, and other clients. Accessibility API detects accessibility issues such as missing alternative text and document structure problems.

- **URL**: https://apify.com/smart-api/email-checker.md
- **Developed by:** [Ondrej Skala](https://apify.com/smart-api) (community)
- **Categories:** Automation, E-commerce, SEO tools
- **Stats:** 1 total users, 0 monthly users, 0.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $15.00 / 1,000 results

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.

Learn more: https://docs.apify.com/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

### What does Email Compatibility and Accessibility Checker do?

**Email Compatibility and Accessibility Checker analyzes rendered email HTML before you send it.** It identifies HTML and CSS features that email clients do not fully support and detects structural accessibility violations. Checks cover Gmail, Outlook, Apple Mail, Yahoo Mail, and many other client variants.

Paste content into the Apify Input tab for a one-off combined check, or use one of three real-time standby endpoints. Apify provides API access, scheduling, integrations, monitoring, and a persistent result dataset without requiring you to operate a separate service.

### Why use Email Compatibility and Accessibility Checker?

Email clients support a smaller and less consistent set of web features than modern browsers. At the same time, missing alternative text, unnamed links or buttons, invalid ARIA attributes, and poor document structure can make an email difficult to use with assistive technology. This Actor helps you:

- catch compatibility and accessibility regressions in one API call;
- focus compatibility checks on a specific email-client family;
- inspect exact client variants affected by a feature;
- locate accessibility failures with selectors and remediation guidance;
- retain structured results for CI, reporting, and automation.

This Actor analyzes email markup. It does not validate mailbox addresses, send messages, or guarantee inbox placement.

### How to use Email Compatibility and Accessibility Checker

1. Open the Actor in Apify Console.
2. Paste rendered email HTML into the Input tab.
3. Optionally provide standalone CSS and select an email-client preset.
4. Start the Actor. HTML input runs both checks; CSS-only input runs compatibility checking.
5. Review the Output dataset and follow each diagnostic's message or help link.

For API usage, call the Actor's Standby URL and use the endpoint that matches your workflow. Normal runs process one input and exit immediately; only Apify-managed Standby runs keep the HTTP server alive.

### Input

#### `POST /check-compatibility`

Runs only email-client compatibility analysis. Provide `html`, `css`, or both, plus an optional `preset`:

```json
{
    "html": "<!doctype html><html><body><picture><img src=\"hero.png\" alt=\"Hero\"></picture></body></html>",
    "css": ".button { cursor: pointer; }",
    "preset": "gmail"
}
```

Supported presets are `all-clients`, `gmail`, `outlook`, `apple-mail`, and `yahoo`.

#### `POST /check-accessibility`

Runs only accessibility analysis. It accepts one required field:

```json
{
    "html": "<!doctype html><html><body><img src=\"hero.png\"></body></html>"
}
```

#### `POST /check`

Runs both checks and returns both result sets. `html` is required because accessibility analysis needs a document. `css` and `preset` are optional and affect the compatibility check.

All content fields accept up to 750,000 characters, and the complete HTTP request body must remain below one megabyte.

### Output

The combined endpoint returns a summary plus nested results:

```json
{
    "checkType": "combined",
    "checkedAt": "2026-08-05T12:00:00.000Z",
    "success": false,
    "errorCount": 4,
    "warningCount": 0,
    "violationCount": 3,
    "violationNodeCount": 3,
    "incompleteCount": 1,
    "compatibility": {
        "checkType": "compatibility",
        "preset": "gmail",
        "clientPatterns": ["gmail.*"],
        "diagnostics": []
    },
    "accessibility": {
        "checkType": "accessibility",
        "engineVersion": "4.12.1",
        "violations": [
            {
                "id": "image-alt",
                "impact": "critical",
                "help": "Images must have alternative text",
                "helpUrl": "https://dequeuniversity.com/rules/axe/4.12/image-alt",
                "nodes": [{ "target": ["img"], "failureSummary": "Fix the missing alternative text" }]
            }
        ]
    }
}
```

Every API result is also stored in the default dataset with a `checkType` of `compatibility`, `accessibility`, or `combined`. Submitted HTML and CSS are not stored, and raw HTML node snippets are removed from accessibility findings. You can download the dataset in various formats such as JSON, HTML, CSV, or Excel.

### Data table

| Field                             | Meaning                                                           |
| --------------------------------- | ----------------------------------------------------------------- |
| `checkType`                       | The check that produced the record.                               |
| `success`                         | Whether the selected check found no failing errors or violations. |
| `errorCount` / `warningCount`     | Email-client compatibility totals.                                |
| `violationCount`                  | Number of failing accessibility rules.                            |
| `violationNodeCount`              | Number of DOM nodes affected by those rules.                      |
| `incompleteCount`                 | Rules that require additional review.                             |
| `compatibility` / `accessibility` | Full nested results on combined checks.                           |

### How much does it cost to check email quality?

Cost depends mainly on how long the standby Actor remains running and its assigned memory. Compatibility checks are lightweight. Accessibility checks create an isolated JSDOM document and require more CPU and memory. For occasional work, submit several checks during one run and stop it afterward. Apify's free tier may cover light testing; review current platform pricing before operating an always-on endpoint.

### Tips and advanced options

- Use a focused compatibility preset during development, then run `all-clients` before release.
- Send rendered HTML rather than a component or unrendered template.
- Treat `incomplete` accessibility findings as manual-review tasks.
- Accessibility checks run without executing scripts or loading external resources.
- JSDOM has no visual layout engine, so the `color-contrast` rule is disabled. Test contrast and responsive layout in real browsers and inboxes.
- If compatibility data is unavailable for a detected feature on a specific client, the Actor skips only that client and returns a warning diagnostic instead of failing the check.
- Use a normal Actor run for one-off checks so the run exits after saving its result. Use the Standby URL only when you need a real-time API; Standby consumes compute until Apify's configured idle timeout stops the server.
- Run `bun run test:bun` locally to exercise all three HTTP endpoints against representative compatibility and accessibility failures.

### FAQ, disclaimers, and support

**Does a passing result guarantee an accessible, compatible email?** No. Automated checks find many issues but cannot replace manual assistive-technology and inbox testing.

**Is my complete email stored?** No. Only sanitized findings and summary data are persisted.

**Does the Actor crawl websites?** No. Compatibility data and checking engines run locally, so proxy rotation is unnecessary.

Use the Actor's **Issues** tab to report bugs, request another preset, or ask for help. Custom integrations and tailored email-quality workflows can also be developed on request.

# Actor input Schema

## `html` (type: `string`):

Rendered email HTML. When supplied through Actor input, both compatibility and accessibility checks run.

## `css` (type: `string`):

Optional standalone CSS for email-client compatibility checking.

## `preset` (type: `string`):

The email-client group against which compatibility is checked.

## Actor input object example

```json
{
  "html": "<!doctype html>\n<html>\n  <body>\n    <picture><img src=\"hero.png\" alt=\"Hero\"></picture>\n  </body>\n</html>",
  "preset": "all-clients"
}
```

# Actor output Schema

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

Structured results for checks submitted through Actor input or the standby API.

## `standbyApi` (type: `string`):

Base URL of the running real-time email checker API.

# 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 = {
    "html": `<!doctype html>
<html>
  <body>
    <picture><img src="hero.png" alt="Hero"></picture>
  </body>
</html>`
};

// Run the Actor and wait for it to finish
const run = await client.actor("smart-api/email-checker").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 = { "html": """<!doctype html>
<html>
  <body>
    <picture><img src=\"hero.png\" alt=\"Hero\"></picture>
  </body>
</html>""" }

# Run the Actor and wait for it to finish
run = client.actor("smart-api/email-checker").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 '{
  "html": "<!doctype html>\\n<html>\\n  <body>\\n    <picture><img src=\\"hero.png\\" alt=\\"Hero\\"></picture>\\n  </body>\\n</html>"
}' |
apify call smart-api/email-checker --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,smart-api/email-checker"
        }
    }
}

```

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/9RjN1C9dxNjBmTp8v/builds/pQloisxtuXFBm7Ebg/openapi.json
