# Email Provider & DMARC Checker - SPF, DKIM, DMARC Audit (`plainsight/email-security-audit`) Actor

Bulk-check which email provider a domain uses (Google Workspace, Microsoft 365, Zoho, Proofpoint, Mimecast...) and grade its email security: SPF, DKIM, DMARC policy, MTA-STS, BIMI. Finds spoofable domains and sending tools (HubSpot, SendGrid, Mailchimp...). $2 per 1,000 domains.

- **URL**: https://apify.com/plainsight/email-security-audit.md
- **Developed by:** [kaleb ashton](https://apify.com/plainsight) (community)
- **Categories:** Lead generation, Developer tools, Business
- **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

## Email Provider & DMARC Checker: bulk SPF, DKIM, DMARC audit

For any list of domains (or email addresses), find out **who hosts their email** (Google Workspace, Microsoft 365, Zoho, Proton, GoDaddy and 60+ more, including security gateways like Proofpoint, Mimecast and Barracuda) and **how well the domain is protected against spoofing**: SPF, DKIM, DMARC, MTA-STS, TLS-RPT and BIMI, summarised as an **A-F grade** with plain-English issues.

- 📮 **Email provider detection** with security-gateway awareness (a domain behind Proofpoint is still identified as Microsoft 365 or Google Workspace when the records show it)
- 🛡️ **Full authentication audit**: SPF syntax, `all` qualifier and recursive **10-DNS-lookup limit** check; DMARC policy, pct, reporting addresses and **reporting vendor**; 35 common DKIM selectors with key size; MTA-STS, TLS-RPT, BIMI
- 🚩 Flags **spoofable domains** (no DMARC or `p=none`) and **Google/Yahoo/Microsoft bulk-sender compliance**
- 📤 Lists the **services a domain sends email through** (HubSpot, Salesforce, SendGrid, Mailchimp, Zendesk, Klaviyo...)
- ⚡ DNS-only, so it's fast and cheap: **$2 per 1,000 domains**

### What can you use it for?

| You are... | Use it to... |
|---|---|
| **Cold email / lead gen agency** | Segment prospects by mailbox provider (send to Outlook leads from Outlook inboxes, Google leads from Google), and drop domains with no MX. |
| **MSP / security consultant** | Find prospects with no DMARC, `p=none` or broken SPF. Every row comes with a ready-made list of issues to pitch. |
| **DMARC / email security vendor** | Build target lists by provider, gateway, current DMARC vendor and policy maturity. |
| **IT / security team** | Audit all of your own brands' domains, including parked ones, in one run. |
| **Deliverability specialist** | Check clients' SPF lookup counts, DKIM keys and alignment basics before a migration. |

### What data do you get?

- `emailProvider`, `emailSecurityGateway`, `mxRecords` (each MX host classified)
- `grade` (A-F), `score` (0-100), `spoofable`, `bulkSenderCompliant`
- `spf`: record, validity, `allQualifier`, `lookupCount`, includes, senders, issues
- `dmarc`: record, `policy`, `subdomainPolicy`, `pct`, `rua`/`ruf`, `reportingVendor` (dmarcian, Valimail, EasyDMARC, Red Sift, Proofpoint, Mimecast, Cloudflare...), issues
- `dkim`: selectors found, key size, revoked keys
- `mtaSts`, `tlsRpt`, `bimi` (logo and VMC URLs)
- `emailSendingServices`: services authorised to send for the domain
- `issues`: human-readable list of problems, e.g. *"DMARC policy is p=none (monitoring only): spoofed mail is still delivered."*
- Flat columns (`dmarcPolicy`, `spfValid`, `dkimFound`, `mxHosts`, `sendingServices`) for easy spreadsheet filtering

#### Sample output (trimmed)

Real output for `basecamp.com` (trimmed):

```json
{
  "domain": "basecamp.com",
  "emailProvider": "Google Workspace",
  "emailSecurityGateway": null,
  "grade": "B",
  "score": 77,
  "spoofable": false,
  "dmarcPolicy": "quarantine",
  "spfValid": true,
  "spfLookupCount": 3,
  "dkimFound": true,
  "sendingServices": "Google Workspace, Mailchimp",
  "issues": [
    "DMARC has no rua= reporting address, so abuse goes unnoticed.",
    "No MTA-STS policy: inbound mail can be downgraded to unencrypted delivery."
  ]
}
```

A domain behind a security gateway, e.g. `gymshark.com`, comes back as `"emailProvider": "Microsoft 365"` with `"emailSecurityGateway": "Proofpoint"` and `"dmarcReportingVendor": "Proofpoint EFD"`.

### How to use it

1. Paste domains **or email addresses** (one per line). Emails are converted to their domain and duplicates removed.
2. Click **Start**.
3. Filter the **Overview** table by provider or grade, or export to CSV/Excel/JSON or your CRM.

```bash
curl -X POST "https://api.apify.com/v2/acts/plainsight~email-security-audit/run-sync-get-dataset-items?token=YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"domains": ["stripe.com", "jane@basecamp.com"]}'
```

### Pricing

**$0.002 per domain audited** ($2 per 1,000). Domains that don't exist (NXDOMAIN) are **free**.

**Try it free:** start a run with an empty input and it analyses 3 sample websites at no charge, so you can see the exact output format first.

### FAQ

**How accurate is DKIM detection?**
DKIM keys live under selector names that aren't published anywhere, so no tool can list them all. This Actor checks 35 selectors used by the most common providers (Google, Microsoft 365, Mailchimp, SendGrid, Proton, Fastmail, Zoho, Klaviyo and more). If none match, the report says *"not found on common selectors"* rather than claiming DKIM is missing.

**Does it send any email?**
No. It only performs public DNS lookups. Nothing is sent to the domains being checked.

**What counts as "spoofable"?**
A domain with no DMARC record, or with `p=none`, gives receivers no instruction to reject forged mail, so attackers can send email that appears to come from it.

### Related tools by the same developer

- [Company Enrichment](https://apify.com/plainsight/company-enrichment): email provider **plus** company profile, contacts, tech stack and domain age.
- [Tech Stack Detector](https://apify.com/plainsight/tech-stack-detector): 7,600+ website technologies plus internal SaaS tools from DNS.
- [Website Contact Extractor](https://apify.com/plainsight/website-contact-extractor): emails, phones and social profiles from websites.
- [SEO & AI Visibility Audit](https://apify.com/plainsight/seo-ai-visibility-audit): security headers, TLS, robots.txt and AI-crawler access per page.

# Actor input Schema

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

Domains, URLs or email addresses, one per line (e.g. acme.com or jane@acme.com). Duplicates are removed automatically.

## `checkAllDkimSelectors` (type: `boolean`):

Probe 35 common DKIM selectors (Google, Microsoft 365, Mailchimp, SendGrid, Proton, Fastmail, Zoho, Klaviyo...). Turn off to probe only the 10 most common and run faster.

## `includeRawTxtRecords` (type: `boolean`):

Add the domain's raw TXT records to each result.

## `maxDomains` (type: `integer`):

Only process the first N domains (useful for a quick test).

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

How many domains to audit in parallel.

## Actor input object example

```json
{
  "domains": [
    "stripe.com",
    "basecamp.com",
    "wordpress.org"
  ],
  "checkAllDkimSelectors": true,
  "includeRawTxtRecords": false,
  "maxConcurrency": 40
}
```

# Actor output Schema

## `results` (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 = {
    "domains": [
        "stripe.com",
        "basecamp.com",
        "wordpress.org"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("plainsight/email-security-audit").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": [
        "stripe.com",
        "basecamp.com",
        "wordpress.org",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("plainsight/email-security-audit").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": [
    "stripe.com",
    "basecamp.com",
    "wordpress.org"
  ]
}' |
apify call plainsight/email-security-audit --silent --output-dataset

```

## MCP server setup

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

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/bm1fFlMvRBKA7bL38/builds/v9r6mV52l5NitV766/openapi.json
