# Email Domain Setup Checker (MX, SPF, DMARC, DKIM) (`velveteen_driver/domain-email-check`) Actor

Check the email setup of many domains from public DNS: email provider (from MX), SPF, DMARC policy, DKIM, BIMI and the sending services allowed by SPF. For deliverability checks and email security reviews. DNS only, no SMTP probing.

- **URL**: https://apify.com/velveteen_driver/domain-email-check.md
- **Developed by:** [Elliott](https://apify.com/velveteen_driver) (community)
- **Categories:** Developer tools, Marketing
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$1.00 / 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.

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 Domain Setup Checker (MX, SPF, DMARC, DKIM)

Check how many domains are set up for email in one run, using public DNS only:

- **Email provider** from MX records. It recognises 22 providers: Google Workspace, Microsoft 365, Zoho Mail, Proofpoint, Mimecast, Barracuda, GoDaddy, IONOS, OVH, Yahoo, iCloud, Fastmail, Proton, Amazon WorkMail / SES, Rackspace, Namecheap, Hostinger, Bluehost, Yandex, Mailgun, Forward Email and Cloudflare Email Routing. Anything else shows as "Other / own server".
- **SPF**: the record, whether it's valid, and which sending services it allows (Google, Microsoft 365, Mailchimp, SendGrid, Mailgun, Amazon SES, HubSpot, Salesforce, Zendesk, Zoho, Klaviyo, Brevo, Postmark, Freshdesk, Intercom, Shopify, Constant Contact, Mailjet, SparkPost)
- **DMARC**: the record and its policy (`none`, `quarantine`, `reject`)
- **DKIM**: which common selectors have keys published
- **BIMI**: whether a brand logo record exists
- **Email auth score** (0 to 100) from SPF, DMARC and DKIM

You can paste domains, website addresses or email addresses. For an email address only the domain part is used; the address itself is never stored or shown in the output.

### Use it for

- **Deliverability checks**: check your own or your clients' sending domains; a missing or weak SPF, DKIM or DMARC record hurts inbox placement.
- **Email security reviews**: find domains in your estate with no DMARC protection against spoofing.
- **Migrations and audits**: see which email provider and sending services each domain uses before a change.

### Output fields

`input`, `domain`, `hasMx`, `mxRecords`, `emailProvider`, `spf`, `spfValid`, `spfSenders`, `dmarc`, `dmarcPolicy`, `dkimSelectorsFound`, `bimi`, `emailAuthScore`, `error`.

Each domain in the output is one charged event (`domain-checked`), including domains that return an `error` (for example "domain does not exist").

### Example output

Illustrative rows (example domains).

| domain | hasMx | emailProvider | spfValid | dmarcPolicy | dkimSelectorsFound | emailAuthScore |
|---|---|---|---|---|---|---|
| example-plumbing.co.uk | true | Google Workspace | true | reject | google | 100 |
| sampledental.example | true | Microsoft 365 | true | none | selector1 | 60 |
| demo-shop.example | false | (none) | false | (none) | (none) | 0 |

### Limits

- DKIM can only be checked for common selector names; a domain may use a selector this tool doesn't try.
- Provider detection is based on MX host names, so a domain behind a filtering service (such as Proofpoint) shows that service rather than the mailbox provider behind it.

### Data source and licence

Only public DNS lookups (MX and TXT records), made through the standard DNS resolver of the machine the actor runs on. DNS is a public system designed for automated lookups; the records are published by each domain's owner so that mail servers can read them. No registry (RDAP or WHOIS) lookups, no connections to the domains' mail servers, no SMTP probing and no email verification. The results are facts about domain configuration, not personal data.

### Responsible use

- Check domains you own or manage, or that you have a legitimate reason to review.
- Keep **Domains checked at the same time** modest (the maximum is 50).
- Don't use this tool to build mailing lists or to support unsolicited bulk email. Follow the laws that apply to you (for example UK GDPR, PECR and CAN-SPAM) and Apify's terms.

# Actor input Schema

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

One per line: example.com, https://www.example.com or name@example.com all work. For an email address only the domain is checked and output.

## `checkDkim` (type: `boolean`):

Checks the common DKIM selectors (Google, Microsoft, Mailchimp, SendGrid and more).

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

How many domains to look up in parallel. Only DNS lookups are made; lower is gentler on DNS servers.

## Actor input object example

```json
{
  "domains": [
    "apify.com",
    "hubspot.com"
  ],
  "checkDkim": true,
  "maxConcurrency": 20
}
```

# Actor output Schema

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

All results in the default dataset, shown in the overview table.

# 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": [
        "apify.com",
        "hubspot.com"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("velveteen_driver/domain-email-check").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": [
        "apify.com",
        "hubspot.com",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("velveteen_driver/domain-email-check").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": [
    "apify.com",
    "hubspot.com"
  ]
}' |
apify call velveteen_driver/domain-email-check --silent --output-dataset

```

## MCP server setup

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

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/0ChgnqfaI1HbLDvUr/builds/0hbC3HeNRTIK3acU7/openapi.json
