# Email Header Analyzer - Delays, SPF/DKIM/DMARC & Gmail Rules (`that_red_bird/email-header-analyzer`) Actor

Paste raw email headers (or an .eml) and see every hop with its delay, SPF/DKIM/DMARC results and alignment, and a Gmail/Yahoo bulk-sender rule check with spoofing flags. Bulk-friendly for support desks and deliverability work. Live DNS checks included.

- **URL**: https://apify.com/that_red_bird/email-header-analyzer.md
- **Developed by:** [mohamed alaya](https://apify.com/that_red_bird) (community)
- **Categories:** Developer tools, Automation, Business
- **Security:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$2.00 / 1,000 message analyzeds

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

## Email Header Analyzer - Delays, SPF/DKIM/DMARC & Gmail Rules

Paste the raw headers of an email (or its full source) and see every hop with its delay, the SPF, DKIM and DMARC results with alignment, and a checklist against the Gmail and Yahoo bulk-sender rules, plus spoofing flags. Works in bulk and as an API for support desks, deliverability consultants and security analysts.

Live DNS checks (DMARC policy, SPF lookup count, DKIM keys, reverse DNS of the sending IP) run during the analysis, and with a full message it re-verifies SPF and DKIM using mailauth.

### Input examples

```json
{ "headers": ["Received: from mail.example.com ...\nAuthentication-Results: mx.google.com; spf=pass ...\nFrom: News <news@example.com>\nSubject: Hi\n\n"] }
```

```json
{ "emlUrls": ["https://example.com/samples/bounce.eml"], "treatAsBulk": "yes" }
```

```json
{ "headers": ["<headers of a message>"], "doDnsChecks": false }
```

Empty input `{}` analyzes a built-in sample message.

### Input guide

| Field | What it does |
|---|---|
| `headers` | One string per message: a header block or a full raw source. |
| `emlUrls` | Links to .eml files. |
| `doDnsChecks` | Live DMARC/SPF/DKIM-key/PTR lookups (default on). Off = pure offline parse. |
| `verifyLive` | When the source includes the body, re-verify SPF, DKIM, DMARC and ARC now. |
| `treatAsBulk` | `auto` (from List-Unsubscribe, List-Id, Precedence), `yes` or `no`. |
| `maxMessages` | Cap per run. |

### Output

| Field | Meaning |
|---|---|
| `from`, `subject`, `date`, `messageId`, `returnPath`, `replyTo` | Parsed identity fields |
| `hopCount`, `totalDelaySeconds`, `slowestHop`, `hops[]` | Received chain oldest first: from, by, protocol, IPs, TLS, per-hop delay |
| `spf`, `dkim[]`, `dmarc` | Recorded results, alignment with the From domain, live DMARC policy (`p`, `pct`, `adkim`, `aspf`) |
| `alignmentOk` | DMARC would pass (aligned SPF or DKIM pass) |
| `live` | SPF lookup count, DKIM key sizes, PTR of the sending IP |
| `verification` | Fresh SPF/DKIM/DMARC/ARC verification of the full message |
| `bulkSenderChecks[]`, `bulkSenderPass` | pass/warn/fail/na per rule (SPF, DKIM, DMARC, alignment, TLS, one-click unsubscribe, Message-ID, PTR, key strength ...) |
| `flags[]` | Findings with severity, such as `display-name-spoof`, `reply-to-differs`, `dmarc-fail`, `slow-hop`, `clock-skew` |

Sample row (abridged):

```json
{"type":"message","from":{"address":"news@example.com"},"hopCount":4,"totalDelaySeconds":370,"slowestHop":{"hop":2,"delaySeconds":327},"spf":{"result":"pass","aligned":false},"dmarc":{"policy":"reject","adkim":"s","aspf":"s"},"bulkSenderPass":false,"flags":[{"severity":"medium","code":"reply-to-differs"}]}
```

### Use it with

- Zendesk/Helpdesk exports of "did not receive my email" tickets -> this Actor.
- `eml-mbox-to-json` extracts messages; paste their `headers` here for authentication analysis.

### FAQ

**Does it prove authentication?** Without the body it reads the results the receiving server recorded in Authentication-Results, then adds live DNS facts. With the full source it also verifies SPF and DKIM itself; DKIM can fail on stored copies that were re-encoded.

**Which rules are checked?** The Gmail/Yahoo sender requirements (SPF/DKIM, DMARC with alignment for bulk senders, one-click unsubscribe, TLS, valid Message-ID and Date), the SPF 10-lookup limit and DKIM key strength. Microsoft's 2025 rules are similar but not checked separately.

### Limits (honest)

- Recorded Authentication-Results can be forged by an attacker in a message that was never rewritten by a trusted server; check `authservId` and the live `verification` block.
- Hop delays depend on the Received timestamps, which servers may set with skewed clocks.
- Sender reputation, spam content scoring and blocklists are out of scope.

### Price

Pay per event: `message-analyzed` $0.002 per message analyzed. Example: 500 support-ticket headers cost $1.00. Messages that cannot be parsed are free.

# Actor input Schema

## `headers` (type: `array`):

One string per message: paste the full header block ("Received: ...", "From: ...", ...) or the complete raw source of an email. Include the body to also re-verify DKIM live. Leave empty to analyze a built-in sample message.

## `emlUrls` (type: `array`):

Direct download links to .eml (raw message) files. Each file is analyzed as one message.

## `doDnsChecks` (type: `boolean`):

Look up the sender domain DMARC policy, SPF record (and its 10-lookup limit), DKIM public keys and the reverse DNS of the sending IP right now. Turn off for a pure offline parse of what the headers already say.

## `verifyLive` (type: `boolean`):

When the pasted source includes the message body, run a full SPF, DKIM, DMARC and ARC verification with mailauth against live DNS. Stored copies that were re-encoded can fail DKIM even if the original passed.

## `treatAsBulk` (type: `string`):

Gmail and Yahoo add extra rules (DMARC, one-click unsubscribe) for senders of bulk mail. Auto decides from List-Unsubscribe, List-Id and Precedence headers.

## `maxMessages` (type: `integer`):

Upper bound on messages analyzed in one run.

## Actor input object example

```json
{
  "headers": [],
  "emlUrls": [],
  "doDnsChecks": true,
  "verifyLive": true,
  "treatAsBulk": "auto",
  "maxMessages": 500
}
```

# Actor output Schema

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

No description

## `downloadCsv` (type: `string`):

No description

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

No description

## `count` (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 = {
    "headers": [],
    "emlUrls": [],
    "doDnsChecks": true,
    "verifyLive": true,
    "treatAsBulk": "auto",
    "maxMessages": 500
};

// Run the Actor and wait for it to finish
const run = await client.actor("that_red_bird/email-header-analyzer").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 = {
    "headers": [],
    "emlUrls": [],
    "doDnsChecks": True,
    "verifyLive": True,
    "treatAsBulk": "auto",
    "maxMessages": 500,
}

# Run the Actor and wait for it to finish
run = client.actor("that_red_bird/email-header-analyzer").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 '{
  "headers": [],
  "emlUrls": [],
  "doDnsChecks": true,
  "verifyLive": true,
  "treatAsBulk": "auto",
  "maxMessages": 500
}' |
apify call that_red_bird/email-header-analyzer --silent --output-dataset

```

## MCP server setup

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

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/kWiS83NZeuUc5fpw8/builds/L0bPsXlVAOqbBzAIK/openapi.json
