# HTML Email Debugger (`enosgb/html-email-debugger`) Actor

Analyze CSS in emails and identify compatibility issues with major email clients like Gmail, Outlook, and Apple Mail. Includes link and image extraction with historical comparison to track improvements over time.

- **URL**: https://apify.com/enosgb/html-email-debugger.md
- **Developed by:** [Enos Melo](https://apify.com/enosgb) (community)
- **Categories:** Automation, E-commerce
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, NaN bookmarks
- **User rating**: No ratings yet

## Pricing

from $20.00 / 1,000 analyses

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 a software tools running on the Apify platform, for all kinds of web data extraction and automation use cases.
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.

In JavaScript/TypeScript projects, use official [JavaScript/TypeScript client](https://docs.apify.com/api/client/js.md):

```bash
npm install apify-client
```

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python.md):

```bash
pip install apify-client
```

In shell scripts, use [Apify CLI](https://docs.apify.com/cli/docs.md):

````bash
# MacOS / Linux
curl -fsSL https://apify.com/install-cli.sh | bash
# Windows
irm https://apify.com/install-cli.ps1 | iex
```bash

In AI frameworks, you might use the [Apify MCP server](https://docs.apify.com/platform/integrations/mcp.md).

If your project is in a different language, use 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

## HTML Email Debugger

Analyze CSS in emails and identify compatibility issues with major email clients like Gmail, Outlook, and Apple Mail. Includes link and image extraction with historical comparison to track improvements over time.

### What does this Actor do?

The **HTML Email Debugger** analyzes the HTML code of an email marketing campaign and automatically identifies which CSS properties and HTML elements are not supported by major email clients. It checks compatibility with Gmail, Outlook (all versions), Apple Mail, and Yahoo Mail, generating a detailed report with:

- List of issues found, classified by severity (critical, warning, info)
- Practical suggestions for fixing each problem
- Compatibility matrix showing support per client
- Score (0-100) and grade (A-F) indicating email quality
- Visual HTML report for easy analysis
- **Extracted links and images** for audit purposes
- **Historical comparison** to track improvements between runs

### How does it work?

1. You provide the HTML code of your email (or URL to a template)
2. The Actor parses the HTML and extracts all CSS properties and elements used
3. Compares each property with the Can I Email compatibility database
4. Checks best practices specific to email marketing
5. Extracts all links (URL, text, anchor) and images (src, alt, dimensions)
6. Can compare with previous run to show improvements or regressions
7. Generates a complete report with all issues and suggestions

### Input

| Field                  | Type    | Description                                                                                                                                          |
| ---------------------- | ------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- |
| htmlContent            | string  | Complete HTML code of the email to analyze. Can be a full email (with `<html>`, `<head>`, `<body>`) or just a fragment. Max recommended size: 500KB. |
| inputUrl               | string  | Public URL of an HTML page for the Actor to fetch and analyze. Useful for pointing to a hosted template. Mutually exclusive with htmlContent.        |
| emailClients           | array   | Which email clients to include in the report. If not provided, checks all 10 priority clients.                                                       |
| severityFilter         | string  | Filter report by minimum severity level: "all" (default), "warning", or "critical"                                                                   |
| includePassingChecks   | boolean | If true, also includes properties that passed (supported in all selected clients). Useful for complete audits.                                       |
| outputFormat           | string  | Output format: "detailed" (default), "summary", or "matrix"                                                                                          |
| compareWithPreviousRun | string  | Run ID of a previous analysis to compare with. Get this from Apify Console URL. If provided, output includes comparison with previous results.       |

### Supported Email Clients

- Gmail (Webmail)
- Gmail (iOS)
- Gmail (Android)
- Outlook 2016 (Windows)
- Outlook 2019 (Windows)
- Outlook 365 (Windows)
- Outlook 365 (Mac)
- Apple Mail (macOS)
- Apple Mail (iOS)
- Yahoo Mail (Webmail)

### Output

The Actor generates two outputs:

1. **Dataset**: JSON object with complete report including:
    - Issues found with severity, description, suggestions
    - Compatibility matrix per client
    - Score (0-100) and grade (A-F)
    - HTML structure report (table layout, max-width, meta tags, etc.)
    - **Extracted links**: Array of `{url, text, anchor}` for each `<a>` tag
    - **Extracted images**: Array of `{src, alt, width, height}` for each `<img>` tag
    - **Comparison** (optional): When `compareWithPreviousRun` is provided, shows score diff, new issues, and resolved issues

2. **Key-Value Store**: Visual HTML report that can be opened directly in a browser, with large score display, severity counts, and color-coded compatibility table.

### Example Output

```json
{
    "summary": {
        "overallScore": 91,
        "overallGrade": "A",
        "criticalCount": 1,
        "warningCount": 0,
        "infoCount": 1
    },
    "extractedContent": {
        "links": [
            { "url": "https://example.com", "text": "Visit our site", "anchor": null },
            { "url": "https://example.com/contact", "text": "Contact Us", "anchor": "contact-link" }
        ],
        "images": [{ "src": "https://example.com/logo.png", "alt": "Logo", "width": 200, "height": 100 }]
    },
    "comparison": {
        "previousScore": 85,
        "scoreDiff": 6,
        "issueChanges": [{ "type": "resolved", "issue": { "id": "iss-001", "property": "margin" } }]
    }
}
````

### Use Cases

1. **Marketing agencies**: Validate dozens of emails per month before sending
2. **Frontend developers**: Ensure templates work across all clients
3. **Product teams**: Improve email view rates for communications
4. **Consultants**: Deliver professional email audits automatically
5. **E-commerce**: Integrate with CI/CD to validate transactional templates

### Pricing

Each analysis costs approximately **$0.02 per 1000 results** (Apify's pay-per-result pricing). The Actor generates one result per email analyzed.

Compare: Litmus and Email on Acid charge $99+/month for similar functionality.

### Known Limitations

- Does not perform visual rendering (code analysis only)
- Does not check specific spam content
- Does not test link functionality (only validates they are present)
- Compatibility data is updated periodically

### Roadmap

**Coming soon**:

- Auto-fix suggestion (generates corrected HTML)
- Mailchimp/Klaviyo integration to analyze templates directly
- Webhook notifications when analysis completes

### License

This Actor uses data from [Can I Email](https://www.caniemail.com) (MIT license).

# Actor input Schema

## `htmlContent` (type: `string`):

The complete HTML code of the email to analyze. Can be a full email (with <html>, <head>, <body>) or just a fragment. Max recommended size: 500KB.

## `inputUrl` (type: `string`):

Public URL of an HTML page for the Actor to fetch and analyze. Useful for pointing to a hosted template. Mutually exclusive with htmlContent.

## `emailClients` (type: `array`):

Which email clients to include in the report. If not provided, checks all 10 priority clients.

## `severityFilter` (type: `string`):

Filter report by minimum severity level.

## `includePassingChecks` (type: `boolean`):

If true, also includes properties that passed (supported in all selected clients).

## `outputFormat` (type: `string`):

Format of the output report.

## `compareWithPreviousRun` (type: `string`):

Run ID of a previous analysis to compare with. Get this from the Apify Console URL of a previous run (the part after /runs/). If provided, the output will include a comparison with the previous results.

## Actor input object example

```json
{
  "htmlContent": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n  <meta charset=\"UTF-8\">\n  <title>Test Email</title>\n</head>\n<body style=\"margin:0;padding:0;font-family:Arial,sans-serif;\">\n  <table width=\"600\" border=\"0\" cellpadding=\"0\" cellspacing=\"0\">\n    <tr>\n      <td style=\"padding:20px;\">\n        <h1>Hello!</h1>\n        <p>This is a test email.</p>\n      </td>\n    </tr>\n  </table>\n</body>\n</html>",
  "emailClients": [
    "gmail-webmail",
    "gmail-ios",
    "gmail-android",
    "outlook-2016-windows",
    "outlook-2019-windows",
    "outlook-365-windows",
    "outlook-365-mac",
    "apple-mail-macos",
    "apple-mail-ios",
    "yahoo-mail"
  ],
  "severityFilter": "all",
  "includePassingChecks": false,
  "outputFormat": "detailed"
}
```

# Actor output Schema

## `analysisResults` (type: `string`):

Complete analysis report with issues, scores, compatibility matrix, extracted links and images

## `visualReport` (type: `string`):

HTML visual report that can be opened in browser

# 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 = {
    "htmlContent": `<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Test Email</title>
</head>
<body style="margin:0;padding:0;font-family:Arial,sans-serif;">
  <table width="600" border="0" cellpadding="0" cellspacing="0">
    <tr>
      <td style="padding:20px;">
        <h1>Hello!</h1>
        <p>This is a test email.</p>
      </td>
    </tr>
  </table>
</body>
</html>`
};

// Run the Actor and wait for it to finish
const run = await client.actor("enosgb/html-email-debugger").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 = { "htmlContent": """<!DOCTYPE html>
<html lang=\"en\">
<head>
  <meta charset=\"UTF-8\">
  <title>Test Email</title>
</head>
<body style=\"margin:0;padding:0;font-family:Arial,sans-serif;\">
  <table width=\"600\" border=\"0\" cellpadding=\"0\" cellspacing=\"0\">
    <tr>
      <td style=\"padding:20px;\">
        <h1>Hello!</h1>
        <p>This is a test email.</p>
      </td>
    </tr>
  </table>
</body>
</html>""" }

# Run the Actor and wait for it to finish
run = client.actor("enosgb/html-email-debugger").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "htmlContent": "<!DOCTYPE html>\\n<html lang=\\"en\\">\\n<head>\\n  <meta charset=\\"UTF-8\\">\\n  <title>Test Email</title>\\n</head>\\n<body style=\\"margin:0;padding:0;font-family:Arial,sans-serif;\\">\\n  <table width=\\"600\\" border=\\"0\\" cellpadding=\\"0\\" cellspacing=\\"0\\">\\n    <tr>\\n      <td style=\\"padding:20px;\\">\\n        <h1>Hello!</h1>\\n        <p>This is a test email.</p>\\n      </td>\\n    </tr>\\n  </table>\\n</body>\\n</html>"
}' |
apify call enosgb/html-email-debugger --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=enosgb/html-email-debugger",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "HTML Email Debugger",
        "description": "Analyze CSS in emails and identify compatibility issues with major email clients like Gmail, Outlook, and Apple Mail. Includes link and image extraction with historical comparison to track improvements over time.",
        "version": "1.1",
        "x-build-id": "bNFqJ6xgAE72GNShe"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/enosgb~html-email-debugger/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-enosgb-html-email-debugger",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        },
        "/acts/enosgb~html-email-debugger/runs": {
            "post": {
                "operationId": "runs-sync-enosgb-html-email-debugger",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor and returns information about the initiated run in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/runsResponseSchema"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/acts/enosgb~html-email-debugger/run-sync": {
            "post": {
                "operationId": "run-sync-enosgb-html-email-debugger",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "inputSchema": {
                "type": "object",
                "required": [
                    "htmlContent"
                ],
                "properties": {
                    "htmlContent": {
                        "title": "HTML Content",
                        "type": "string",
                        "description": "The complete HTML code of the email to analyze. Can be a full email (with <html>, <head>, <body>) or just a fragment. Max recommended size: 500KB."
                    },
                    "inputUrl": {
                        "title": "URL to Analyze",
                        "pattern": "^https?://.*",
                        "type": "string",
                        "description": "Public URL of an HTML page for the Actor to fetch and analyze. Useful for pointing to a hosted template. Mutually exclusive with htmlContent."
                    },
                    "emailClients": {
                        "title": "Email Clients",
                        "minItems": 1,
                        "uniqueItems": true,
                        "type": "array",
                        "description": "Which email clients to include in the report. If not provided, checks all 10 priority clients.",
                        "items": {
                            "type": "string",
                            "enum": [
                                "gmail-webmail",
                                "gmail-ios",
                                "gmail-android",
                                "outlook-2016-windows",
                                "outlook-2019-windows",
                                "outlook-365-windows",
                                "outlook-365-mac",
                                "apple-mail-macos",
                                "apple-mail-ios",
                                "yahoo-mail"
                            ]
                        },
                        "default": [
                            "gmail-webmail",
                            "gmail-ios",
                            "gmail-android",
                            "outlook-2016-windows",
                            "outlook-2019-windows",
                            "outlook-365-windows",
                            "outlook-365-mac",
                            "apple-mail-macos",
                            "apple-mail-ios",
                            "yahoo-mail"
                        ]
                    },
                    "severityFilter": {
                        "title": "Severity Filter",
                        "enum": [
                            "all",
                            "warning",
                            "critical"
                        ],
                        "type": "string",
                        "description": "Filter report by minimum severity level.",
                        "default": "all"
                    },
                    "includePassingChecks": {
                        "title": "Include Passing Checks",
                        "type": "boolean",
                        "description": "If true, also includes properties that passed (supported in all selected clients).",
                        "default": false
                    },
                    "outputFormat": {
                        "title": "Output Format",
                        "enum": [
                            "detailed",
                            "summary",
                            "matrix"
                        ],
                        "type": "string",
                        "description": "Format of the output report.",
                        "default": "detailed"
                    },
                    "compareWithPreviousRun": {
                        "title": "Compare with Previous Run",
                        "type": "string",
                        "description": "Run ID of a previous analysis to compare with. Get this from the Apify Console URL of a previous run (the part after /runs/). If provided, the output will include a comparison with the previous results."
                    }
                }
            },
            "runsResponseSchema": {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "string"
                            },
                            "actId": {
                                "type": "string"
                            },
                            "userId": {
                                "type": "string"
                            },
                            "startedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "finishedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "status": {
                                "type": "string",
                                "example": "READY"
                            },
                            "meta": {
                                "type": "object",
                                "properties": {
                                    "origin": {
                                        "type": "string",
                                        "example": "API"
                                    },
                                    "userAgent": {
                                        "type": "string"
                                    }
                                }
                            },
                            "stats": {
                                "type": "object",
                                "properties": {
                                    "inputBodyLen": {
                                        "type": "integer",
                                        "example": 2000
                                    },
                                    "rebootCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "restartCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "resurrectCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "computeUnits": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "options": {
                                "type": "object",
                                "properties": {
                                    "build": {
                                        "type": "string",
                                        "example": "latest"
                                    },
                                    "timeoutSecs": {
                                        "type": "integer",
                                        "example": 300
                                    },
                                    "memoryMbytes": {
                                        "type": "integer",
                                        "example": 1024
                                    },
                                    "diskMbytes": {
                                        "type": "integer",
                                        "example": 2048
                                    }
                                }
                            },
                            "buildId": {
                                "type": "string"
                            },
                            "defaultKeyValueStoreId": {
                                "type": "string"
                            },
                            "defaultDatasetId": {
                                "type": "string"
                            },
                            "defaultRequestQueueId": {
                                "type": "string"
                            },
                            "buildNumber": {
                                "type": "string",
                                "example": "1.0.0"
                            },
                            "containerUrl": {
                                "type": "string"
                            },
                            "usage": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "integer",
                                        "example": 1
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "usageTotalUsd": {
                                "type": "number",
                                "example": 0.00005
                            },
                            "usageUsd": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "number",
                                        "example": 0.00005
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
