# Bulk DMARC Checker & MX Checker - SPF, DKIM Audit (`batreek/email-deliverability-auditor`) Actor

Bulk DMARC checker and MX record checker for thousands of domains: SPF (with 10-lookup limit check), DMARC policy, DKIM selectors, MX provider, MTA-STS, TLS-RPT and BIMI. Get a 0-100 score, A-F grade and plain-English fixes per domain.

- **URL**: https://apify.com/batreek/email-deliverability-auditor.md
- **Developed by:** [Adam Abdou-Gustavson](https://apify.com/batreek) (community)
- **Categories:** Developer tools, Lead generation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.00 / 1,000 domain auditeds

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

## Bulk DMARC Checker & MX Checker — SPF, DKIM and Email Deliverability Audit for Any Number of Domains

Paste a list of domains (or websites, or email addresses) and get a **complete email-authentication audit for each one**: SPF validity and **10-DNS-lookup limit**, DMARC policy and reporting, DKIM keys on 40 common selectors, MX / email provider detection, MTA-STS, TLS-RPT and BIMI — plus a **0–100 score, an A–F grade and plain-English fixes**.

Perfect for **cold-email and outbound teams, deliverability consultants, MSPs, agencies, security reviewers and sales teams** qualifying prospects.

### What you get per domain

- **Email provider** from MX records (Google Workspace, Microsoft 365, Zoho, Proofpoint, Mimecast, Fastmail, GoDaddy, Amazon SES, 25+ more) — great for B2B lead segmentation.
- **SPF**: record, valid/invalid, multiple-record errors, recursive **DNS lookup count** (permerror over 10), `all` qualifier, void includes, deprecated `ptr`.
- **DMARC**: policy (`none` / `quarantine` / `reject`), subdomain policy, `pct`, `rua`/`ruf` reporting addresses.
- **DKIM**: active selectors found, revoked keys, wildcard detection. Add your own selectors.
- **MTA-STS** mode (`enforce` / `testing` / `none`), **TLS-RPT** and **BIMI** records.
- **Gmail & Yahoo bulk-sender readiness** flag (SPF + DKIM + DMARC).
- **Score, grade, top issue and a prioritized list of fixes.**

### Why this checker?

- ⚡ **Fast & bulk** — thousands of domains per run, de-duplicated automatically; accepts `example.com`, `https://www.example.com/page` or `jane@example.com`.
- 🔒 **100% passive** — only reads public DNS (via DNS-over-HTTPS). No emails sent, no SMTP probing, no mailbox checks.
- 💸 **One flat price per domain** — not per DNS query.
- 🔁 **Schedule it** to monitor your own domains or clients' domains and get alerted when a record breaks.

### Input

```json
{
  "domains": ["acme.com", "https://www.example.org", "sales@contoso.com"],
  "dkimSelectors": ["mycustomselector"],
  "fetchMtaStsPolicy": true
}
```

### Output example

```json
{
  "domain": "acme.com",
  "grade": "C",
  "score": 68,
  "mailProvider": "Google Workspace",
  "mxRecords": ["1 smtp.google.com"],
  "spfRecord": "v=spf1 include:_spf.google.com include:sendgrid.net ~all",
  "spfStatus": "valid",
  "spfLookupCount": 4,
  "spfAll": "~all (softfail)",
  "dmarcRecord": "v=DMARC1; p=none",
  "dmarcPolicy": "none",
  "dmarcRua": null,
  "dkimSelectorsFound": ["google", "s1"],
  "mtaStsMode": null,
  "tlsRpt": null,
  "bimi": null,
  "gmailYahooBulkSenderReady": true,
  "topIssue": "DMARC policy is p=none (monitoring only)",
  "issues": [
    { "severity": "medium", "issue": "DMARC policy is p=none (monitoring only)", "recommendation": "Move to p=quarantine, then p=reject, after reviewing reports." },
    { "severity": "low", "issue": "DMARC has no rua reporting address", "recommendation": "Add rua=mailto:... to receive aggregate reports." }
  ]
}
```

### Use it as a bulk DMARC checker or MX checker

- **DMARC checker:** `dmarcPolicy` (`none` / `quarantine` / `reject`), subdomain policy, `pct` and `rua`/`ruf` reporting addresses for every domain in your list. Filter on `dmarcPolicy` to find domains that can still be spoofed.
- **MX checker / MX record lookup:** the MX hosts and the detected email provider (`mailProvider`, e.g. Google Workspace or Microsoft 365) for every domain, which is useful for B2B lead segmentation or migration planning.

### Scoring

MX 10 · SPF 25 · DMARC 40 (policy + reporting) · DKIM 15 · MTA-STS/TLS-RPT/BIMI 10. A ≥ 90, B ≥ 80, C ≥ 65, D ≥ 50, F < 50. Domains that correctly lock down a non-mail domain (null MX + `-all` + `p=reject`) score A.

### Pricing

**$2.00 per 1,000 domains** (pay-per-event, `domain-audited`). Every check above is included.

#### What will it cost?

| Domains | Cost |
|---|---|
| 3 domains (the pre-filled form) | $0.006 |
| 1,000 domains | $2.00 |
| 10,000 domains | $20.00 |
| 100,000 domains | $200.00 |

Duplicate domains are removed before auditing, so you pay once per unique domain. Each run also has a $0.00005 start fee (one per GB of memory; the default memory needs one), which is too small to change these numbers. You pay only for these events: no rental fee and no separate compute charge. Set a **maximum cost per run** in the run options (or `maxTotalChargeUsd` in the API) and the Actor stops cleanly when it reaches it.

### Use it via API, code or AI agents

Everything in the Console also works over the API, so you can run it from code, a scheduler or an AI agent. Replace `<YOUR_APIFY_TOKEN>` with your token from **Apify Console → Settings → API & Integrations**.

**REST: run and get the results in one call** (waits up to 5 minutes; `maxTotalChargeUsd` caps what the run can cost):

```bash
curl -X POST "https://api.apify.com/v2/acts/batreek~email-deliverability-auditor/run-sync-get-dataset-items?maxTotalChargeUsd=1" \
  -H "Authorization: Bearer <YOUR_APIFY_TOKEN>" \
  -H "Content-Type: application/json" \
  -d '{"domains": ["example.com", "github.com"]}'
```

**Python** (`pip install apify-client`):

```python
from apify_client import ApifyClient

client = ApifyClient("<YOUR_APIFY_TOKEN>")
run = client.actor("batreek/email-deliverability-auditor").call(run_input={
    "domains": [
        "example.com",
        "github.com"
    ]
})
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)
```

**JavaScript / Node.js** (`npm install apify-client`):

```javascript
import { ApifyClient } from 'apify-client';

const client = new ApifyClient({ token: '<YOUR_APIFY_TOKEN>' });
const run = await client.actor('batreek/email-deliverability-auditor').call({"domains": ["example.com", "github.com"]});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);
```

**AI agents (MCP):** add this Actor as a tool in Claude, ChatGPT, Cursor or any MCP client through Apify's hosted MCP server at `https://mcp.apify.com?tools=batreek/email-deliverability-auditor`. The agent can then check SPF, DKIM, DMARC and MX records for any list of domains and read the structured results. Runs are billed to your Apify account like any other run.

**No-code:** use Apify's integrations (Zapier, Make, n8n, Google Sheets, Slack, webhooks) or put it on an Apify **Schedule**.

### FAQ

**Why does DKIM say "not found" for a domain that signs mail?** DKIM keys can't be listed; they must be guessed by selector name. We try 40 common selectors. Some providers use rotating/custom selectors (Google often uses dated ones). Add yours in *Extra DKIM selectors*.
**Is this legal?** Yes — DNS records are public by design. The Actor never contacts mail servers.
**Does it verify email addresses?** No. It audits the domain's configuration, not individual mailboxes.

# Actor input Schema

## `domains` (type: `array`):

One per line. Domains (example.com), website URLs or email addresses are all accepted; the domain is extracted and de-duplicated.

## `dkimSelectors` (type: `array`):

DKIM records cannot be listed, only guessed. We try ~30 common selectors (google, selector1, k1, s1, mandrill, ...). Add your own here.

## `fetchMtaStsPolicy` (type: `boolean`):

Download https://mta-sts.<domain>/.well-known/mta-sts.txt to read the enforcement mode.

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

Domains audited in parallel.

## Actor input object example

```json
{
  "domains": [
    "google.com",
    "github.com",
    "example.com"
  ],
  "fetchMtaStsPolicy": true,
  "maxConcurrency": 10
}
```

# Actor output Schema

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

One audit per domain: SPF, DKIM, DMARC, MX, MTA-STS, TLS-RPT, BIMI, score, grade and fixes.

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

Grade counts and any invalid inputs.

# 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 = {
    "domains": [
        "google.com",
        "github.com",
        "example.com"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("batreek/email-deliverability-auditor").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 = { "domains": [
        "google.com",
        "github.com",
        "example.com",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("batreek/email-deliverability-auditor").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 '{
  "domains": [
    "google.com",
    "github.com",
    "example.com"
  ]
}' |
apify call batreek/email-deliverability-auditor --silent --output-dataset

```

## MCP server setup

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

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/Rn7kqF6xQSjbubymV/builds/EwcUJjbpmFc8BaSkA/openapi.json
