# Email Deliverability & DNS Health Checker (`zaden/my-actor-5`) Actor

Checks SPF, DKIM, DMARC, and MX DNS records for any domain to flag email deliverability and spoofing-protection gaps. Fast, no browser needed. Need every check? See Full Site Health Suite for all 9 checks in one job.

- **URL**: https://apify.com/zaden/my-actor-5.md
- **Developed by:** [Zaden](https://apify.com/zaden) (community)
- **Categories:** Developer tools, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $3.60 / 1,000 domain checkeds

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#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

## Email Deliverability & DNS Health Checker

A fast, no-browser check of the DNS records that control email deliverability and anti-spoofing protection. Point it at one or more domains and get back SPF, DKIM, DMARC, and MX record status -- plus a **letter grade**, a 0-100 score, a severity tag, and a plain-English issue list.

### What you get, per domain

- A **letter grade (A+ to F)** and 0-100 score summarizing email/DNS health at a glance
- A one-line **executive summary** ("4 issue(s) found -- review recommended")
- A **severity** tag -- `critical` (no MX, or SPF wide open with `+all`), `warning` (missing DKIM/DMARC or other issues), or `ok` -- for instant triage
- **MX records** -- confirms the domain can actually receive email, and lists mail servers by priority
- **SPF** -- whether a Sender Policy Framework record exists, whether there's more than one (invalid), and how strict its `all` mechanism is
- **DMARC** -- whether a policy exists at `_dmarc.[domain]`, and whether it's set to monitor-only (`p=none`), quarantine, or reject
- **DKIM** -- checks a configurable list of common selectors (Google Workspace, generic `default`/`selector1`/`selector2`, etc.) for a published key. Add your provider's selector for a fully accurate result
- Domains are checked **in parallel** (configurable, up to 20 at once), and each domain's own MX/SPF/DMARC/DKIM lookups also run concurrently, so a batch of 50 domains finishes in a fraction of the time a one-by-one check would take

### Why this instead of checking manually

| | Manual spot-checks | Email Deliverability & DNS Checker |
|---|---|---|
| Coverage | One domain at a time, in a DNS lookup tool | Every domain you list, automatically |
| Speed | Minutes per domain across multiple tools | Seconds, via parallel checking |
| Triage | You interpret raw TXT records yourself | Pre-classified severity + letter grade |
| Repeatability | Forgotten until mail starts landing in spam | One click, or schedule it |
| Output | Notes across several browser tabs | Structured dataset, exportable to CSV/JSON/BI tools |

### Who this is for

- Developers and marketers setting up a new sending domain who want to confirm SPF/DKIM/DMARC are live before sending
- Teams debugging why their email is landing in spam
- Agencies auditing a client's domains for spoofing protection
- Anyone wiring a periodic DNS-drift check into a scheduled monitor (DNS records get misconfigured more often than you'd think)

### How to use it

1. Add one or more **domains to check** (e.g. `example.com`).
2. If you know your mail provider's DKIM selector, add it to **DKIM selectors to check** for a more accurate result -- otherwise the common defaults are checked.
3. Tune **concurrency** (default 5) to trade speed for gentleness on slow DNS resolvers.
4. Run it once for a snapshot, or put it on an Apify **Schedule** to catch a dropped SPF/DMARC record before it hurts deliverability.

### Example output (one item)

```json
{
  "domain": "example.com",
  "score": 45,
  "grade": "F",
  "severity": "warning",
  "summary": "3 issue(s) found -- review recommended.",
  "issueCount": 3,
  "issues": [
    "No SPF record found -- other mail servers can't verify mail claiming to be from this domain.",
    "No DMARC record found -- no policy exists for handling spoofed mail from this domain.",
    "No DKIM record found for the checked selectors (default, google, selector1, selector2, k1, mail, dkim). DKIM may still be active under a different, unchecked selector."
  ],
  "hasMx": true,
  "mxRecords": ["mail.example.com (priority 10)"],
  "hasSpf": false,
  "hasDmarc": false,
  "dkimSelectorsFound": [],
  "checkedAt": "2026-08-22T00:00:00.000Z"
}
```

### Pricing

This Actor uses pay-per-event pricing:

- **Domain checked** -- charged once per domain processed, covering the MX, SPF, DMARC, and DKIM-selector lookups for that domain.

Parallel checking doesn't cost more -- it just finishes faster.

### FAQ

**Why can't it find my DKIM record even though DKIM is set up?**
DKIM records are published under a selector chosen by your mail provider (e.g. `google._domainkey.example.com`), and there's no DNS way to discover that selector automatically. This Actor checks a list of common selectors -- add your specific one in the input for a reliable result.

**Does a low score mean my domain is broken?**
Not necessarily. Domains that don't send email at all (parked domains, for example) don't need SPF/DKIM/DMARC. The score is most meaningful for domains that actively send mail.

**What makes something "critical" vs. a "warning"?**
`critical` covers active exposure: no MX records (mail can't be received) or an SPF record ending in `+all` (anyone can send mail as your domain). `warning` covers everything else that lowers the score, most commonly a missing DKIM selector or DMARC record -- worth fixing, but not an active spoofing free-for-all.

**Will higher concurrency get me rate-limited?**
DNS resolvers can rate-limit aggressive querying. Start at the default (5) and lower it if you see lookups start failing for a particular batch.

**Does this send any data anywhere besides your own Apify account?**
No. It only performs standard DNS lookups (TXT and MX records) for the domains you provide and returns what it finds -- no login, no third-party analytics calls.

# Actor input Schema

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

One or more domains (e.g. example.com). SPF, DKIM, DMARC, and MX records are checked once per domain.

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

DKIM records are published at \[selector].\_domainkey.\[domain], and the selector is chosen by the sender's mail provider. These common selectors are checked; add your provider's selector if you know it for a more accurate result.

## `requestTimeoutSecs` (type: `integer`):

How long to wait for each DNS query before giving up.

## `concurrency` (type: `integer`):

How many domains to check in parallel. Higher values finish faster at the same cost; lower values are gentler on slow DNS resolvers.

## Actor input object example

```json
{
  "domains": [
    "example.com"
  ],
  "dkimSelectors": [
    "default",
    "google",
    "selector1",
    "selector2",
    "k1",
    "mail",
    "dkim"
  ],
  "requestTimeoutSecs": 10,
  "concurrency": 5
}
```

# Actor output Schema

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

SPF, DKIM, DMARC, and MX record status for each checked domain.

# 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": [
        "example.com"
    ],
    "dkimSelectors": [
        "default",
        "google",
        "selector1",
        "selector2",
        "k1",
        "mail",
        "dkim"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("zaden/my-actor-5").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": ["example.com"],
    "dkimSelectors": [
        "default",
        "google",
        "selector1",
        "selector2",
        "k1",
        "mail",
        "dkim",
    ],
}

# Run the Actor and wait for it to finish
run = client.actor("zaden/my-actor-5").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": [
    "example.com"
  ],
  "dkimSelectors": [
    "default",
    "google",
    "selector1",
    "selector2",
    "k1",
    "mail",
    "dkim"
  ]
}' |
apify call zaden/my-actor-5 --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,zaden/my-actor-5"
        }
    }
}

```

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/yezlLF7JkKoOnrjlT/builds/2ky6XQOmJj9kxKYhR/openapi.json
