# Email List & Sender Domain Deliverability Auditor (`parviz_a/my-actor-1`) Actor

Ensure email deliverability and clean contact lists. Audits email address syntax, MX records, disposable/role domains, and evaluates sender SPF, DKIM, and DMARC authentication policies with deliverability scoring—100% DNS-based without SMTP probing.

- **URL**: https://apify.com/parviz\_a/my-actor-1.md
- **Developed by:** [Parviz Abbasov](https://apify.com/parviz_a) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.50 / 1,000 email auditeds

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.

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 List & Sender Domain Deliverability Auditor

Most email verifiers only check the list you're sending *to*. This one also checks the domain you're sending *from* — the part that's actually decided whether your last campaign landed in the inbox or the spam folder.

Two checks, one Actor, both using standard public DNS lookups only — **no SMTP probing of individual mailboxes**.

### 1. Recipient list hygiene

For each email address: syntax validity, whether the domain has a working mail server (MX record), and flags for disposable/temporary domains, free providers, and role-based addresses (`info@`, `sales@`, etc.).

### 2. Sender domain deliverability audit

For each domain you send *from*: SPF record (and whether it actually rejects unauthorized senders), DKIM signing (checked against common selector names used by major email platforms), and DMARC policy. This is the exact configuration Google and Yahoo have required for bulk senders since 2024 — and the part a recipient-only verifier can't tell you anything about.

### Why no SMTP probing?

Several email verifiers offer an "SMTP handshake" mode that connects to a mail server and asks whether a specific mailbox exists. In practice this is unreliable — Gmail and Outlook both return ambiguous responses specifically to prevent this kind of enumeration — and running it at volume against mail servers you don't own is the kind of traffic pattern that gets flagged as abuse. This Actor skips it entirely and relies only on DNS lookups: the same public, standard queries any mail server performs before it will even attempt to send a message.

### Input

| Field | Type | Default | Description |
|---|---|---|---|
| `emails` | array of strings | 4 example addresses | Recipient addresses to check. Leave empty to skip. |
| `senderDomains` | array of strings | `["gmail.com", "outlook.com"]` | Domains to audit for SPF/DKIM/DMARC. Leave empty to skip. |
| `dnsTimeoutMs` | integer | `8000` | Timeout per individual DNS query. |

Use either field alone, or both in the same run.

### Output

Email results (default dataset):

```json
{
  "email": "sales@example.com",
  "syntaxValid": true,
  "domain": "example.com",
  "mxFound": true,
  "mxRecords": ["mail.example.com"],
  "isDisposable": false,
  "isFreeProvider": false,
  "isRoleAccount": true,
  "status": "risky",
  "reasons": ["Role-based address (not a named individual)"],
  "checkedAt": "2026-09-14T10:00:00.000Z"
}
```

Domain audit results (`DOMAIN-AUDITS` dataset — open it from the run's **Storage** tab):

```json
{
  "domain": "example.com",
  "spf": { "found": true, "record": "v=spf1 include:_spf.google.com -all", "hasHardFail": true, "hasSoftFail": false },
  "dkim": { "found": true, "selectorsChecked": 15, "selectorsFound": ["google"] },
  "dmarc": { "found": true, "record": "v=DMARC1; p=quarantine; ...", "policy": "quarantine" },
  "deliverabilityScore": 90,
  "recommendations": [],
  "checkedAt": "2026-09-14T10:00:00.000Z"
}
```

### Pricing

Pay-per-event:

- A small flat fee per run.
- **Per email checked** — cheap, since it's a lightweight lookup.
- **Per domain audited** — priced higher, since it runs several DNS queries and produces an actionable compliance report.

### Limitations

- **Disposable-domain and free-provider lists are curated, not exhaustive.** New disposable-email services appear constantly; treat `isDisposable: false` as "not on our list," not a guarantee.
- **DKIM detection is best-effort.** The true DKIM selector a domain uses isn't discoverable from DNS alone unless you already know it. This Actor checks ~15 selector names commonly used by major email platforms (Google Workspace, Sendgrid, Mailgun, Mandrill, Zoho, etc.). A `dkim.found: false` result means none of those common selectors resolved — it does not prove DKIM isn't configured under a custom selector name.
- **No SMTP-level checks** (by design — see above). This means a syntactically valid address at a domain with a working mail server could still bounce if that specific mailbox doesn't exist; this Actor tells you the address is *plausible*, not that it's guaranteed to be live.

### API usage example

**Python**

```python
from apify_client import ApifyClient

client = ApifyClient("YOUR_API_TOKEN")
run = client.actor("YOUR_USERNAME/email-deliverability-auditor").call(run_input={
    "emails": ["prospect@example.com"],
    "senderDomains": ["yourcompany.com"],
})
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item["email"], "-", item["status"])
```

# Actor input Schema

## `emails` (type: `array`):

List of recipient email addresses to check syntax, MX records, and domain hygiene flags.

## `senderDomains` (type: `array`):

List of domains you send from to audit SPF, DKIM, and DMARC configurations.

## `dnsTimeoutMs` (type: `integer`):

Timeout in milliseconds for each individual DNS query.

## Actor input object example

```json
{
  "emails": [
    "test@gmail.com",
    "invalid-email",
    "someone@mailinator.com",
    "sales@example.com"
  ],
  "senderDomains": [
    "gmail.com",
    "outlook.com"
  ],
  "dnsTimeoutMs": 8000
}
```

# Actor output Schema

## `recordType` (type: `string`):

Distinguishes whether this row represents an email hygiene check or a domain audit.

## `email` (type: `string`):

Recipient email address checked.

## `syntaxValid` (type: `string`):

No description

## `domain` (type: `string`):

No description

## `mxFound` (type: `string`):

No description

## `mxRecords` (type: `string`):

No description

## `isDisposable` (type: `string`):

No description

## `isFreeProvider` (type: `string`):

No description

## `isRoleAccount` (type: `string`):

No description

## `status` (type: `string`):

No description

## `reasons` (type: `string`):

No description

## `spf` (type: `string`):

No description

## `dkim` (type: `string`):

No description

## `dmarc` (type: `string`):

No description

## `deliverabilityScore` (type: `string`):

No description

## `recommendations` (type: `string`):

No description

## `checkedAt` (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 = {};

// Run the Actor and wait for it to finish
const run = await client.actor("parviz_a/my-actor-1").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 = {}

# Run the Actor and wait for it to finish
run = client.actor("parviz_a/my-actor-1").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 '{}' |
apify call parviz_a/my-actor-1 --silent --output-dataset

```

## MCP server setup

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

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/jVzm2rKVAXz2TLmYj/builds/VuIKDiofOzNacYLSt/openapi.json
