# Email Validator – MX & Disposable Check (`sfoln/email-validator`)

Validate email lists without sending mail: strict syntax, domain and MX records (incl. null MX), disposable and free-mail domains, role accounts, typo fixes, SPF and DMARC. $0.40 per 1,000 emails, no SMTP probing. Need mailbox-level checks? Use Email Verifier.

- Family: Company & lead intelligence
- Categories: Lead generation, Developer tools, Automation
- Store: https://apify.com/sfoln/email-validator (Markdown: https://apify.com/sfoln/email-validator.md)
- JSON: https://www.sfoln.com/actors/email-validator.json
- MCP: https://mcp.apify.com?tools=sfoln/email-validator
- REST (sync): POST https://api.apify.com/v2/actors/sfoln~email-validator/run-sync-get-dataset-items
- REST (async): POST https://api.apify.com/v2/actors/sfoln~email-validator/runs

Validate email addresses in bulk without sending any mail: each address gets a verdict (ok, role, disposable, no_mail_server, domain_not_found or invalid_syntax) from a strict syntax check, the domain's MX records (including RFC 7505 null MX), a list of about 9,900 disposable domains, free-mail and role-account lists, a typo suggestion (gmial.com → gmail.com) and, optionally, the domain's SPF and DMARC policy. Built for cleaning sign-up and lead lists, blocking throw-away addresses in forms, and AI agents that need a quick yes/no before they email someone. $0.40 per 1,000 emails.

## Price per delivered record

| Event | Price | Per 1,000 | Charged for |
| --- | --- | --- | --- |
| Checked email (`email`) | $0.0004 | $0.40 / 1,000 | Charged once per email address that received a verdict from the local checks: invalid syntax, domain not found, no mail server, disposable, role account or ok. Addresses whose domain could not be looked up (DNS failure) are not charged. |

Pay-per-event, USD, billed by Apify; no platform usage charge. Only records with status `ok` are charged. Cap a run with `maxTotalChargeUsd`. Apify free plan: up to 10 per run.

## Run

```bash
curl -X POST "https://api.apify.com/v2/actors/sfoln~email-validator/run-sync-get-dataset-items" \
  -H "Authorization: Bearer $APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"emails":["support@apify.com","jane.doe@gmial.com","info@example.com"]}'
```

MCP client configuration:

```json
{
  "mcpServers": {
    "apify": {
      "type": "http",
      "url": "https://mcp.apify.com?tools=sfoln/email-validator"
    }
  }
}
```

Example prompt: Validate these email addresses and tell me which ones to drop from my list and why: support@apify.com, jane.doe@gmial.com, info@example.com.

## Input

Paste email addresses (one per line) or pass an array. Each address produces one dataset record with a verdict, flags and a typo suggestion. Nothing is sent to the mailboxes.

| Field | Type | Default | Meaning |
| --- | --- | --- | --- |
| `emails` (required) | array | — | Emails: Email addresses to validate, one per line. Duplicates (also differently written forms of one address) are removed. Also accepts objects with an `email` field. Accounts on the Apify free plan can process up to 10 email addresses per run. |
| `checkSpfDmarc` | boolean | `true` | Check SPF and DMARC: Also read each domain's SPF record and DMARC policy (two extra DNS lookups per domain, cached for the run). Turn off for the fastest runs on very large lists. |
| `maxEmails` | integer | `10000` | Max emails: Safety cap on the number of addresses validated in this run; addresses beyond it are ignored and counted as inputItemsDropped in the OUTPUT record. |
| `concurrency` | integer | `10` | Concurrency: How many addresses are validated in parallel (1–20). |
| `includeRaw` | boolean | `false` | Include raw check result: Attach the unmodified pre-check result (every field of the local check, e.g. the local part and whether DNS was consulted) to each record. |

Example input:

```json
{
  "emails": [
    "support@apify.com",
    "jane.doe@gmial.com",
    "info@example.com"
  ]
}
```

## Output

One record per input item with `status` (`ok` is charged; `not_found`, `error`, `skipped_*` are free) and `charged`. The run stores an `OUTPUT` summary record.

| Field | Type | Meaning |
| --- | --- | --- |
| `input` | string | object | Input: The address as you sent it. |
| `email` | string | null | Email: Normalized address: lower case, ASCII (punycode) domain, without spaces, <…> or mailto:. Null when the syntax is invalid. |
| `verdict` | string | Verdict: invalid_syntax \| domain_not_found \| no_mail_server \| disposable \| role \| ok \| unknown (DNS failed: not charged). |
| `quality` | string | Quality: good (passed every check) \| risky (role account, likely typo, or not checkable) \| bad (cannot or should not receive mail). |
| `reason` | string | Reason: Short explanation of the verdict. |
| `deliverable` | string | Deliverable: no = cannot receive mail; unknown = only a mailbox-level (SMTP) check could tell. This Actor never answers yes. |
| `domain` | string | null | Domain: Lower-case ASCII domain of the address. |
| `canonicalEmail` | string | null | Canonical email: Provider-aware form for de-duplication (Gmail ignores dots and +tags; Outlook, iCloud, Proton, Fastmail ignore +tags). |
| `syntaxValid` | boolean | Syntax valid: Strict RFC 5321/5322 dot-atom syntax as mailbox providers accept it. |
| `syntaxError` | string | null | Syntax error: Why the syntax is invalid, e.g. missing_at, multiple_at, local_invalid, domain_invalid, tld_invalid. |
| `domainExists` | boolean | null | Domain exists: false: NXDOMAIN or an unknown top-level domain; null: not checked. |
| `mx` | array | MX hosts: Mail exchangers by preference (a null MX is reported in nullMx). |
| `nullMx` | boolean | Null MX: The domain publishes an RFC 7505 null MX: it accepts no email. |
| `hasMailServer` | boolean | null | Has mail server: MX hosts, or the A/AAAA fallback of RFC 5321; null when not checked. |
| `mailProvider` | string | null | Mail provider: google \| microsoft \| zoho \| proton \| … \| other, guessed from the MX hosts. |
| `disposable` | boolean | Disposable: Throw-away mailbox domain (CC0 list of about 9,900 domains, including common typo domains). |
| `freeProvider` | boolean | Free provider: Free webmail such as Gmail, Outlook or Yahoo. |
| `role` | boolean | Role account: Shared functional mailbox such as info@, sales@ or support@. |
| `typoSuggestion` | string | null | Did you mean: The address with a likely mistyped domain corrected (jane@gmial.com → jane@gmail.com). |
| `domainSpf` | object | null | Domain SPF: { record, allQualifier, includes, multipleRecords } of the domain's SPF record; null when absent or not checked. |
| `domainDmarc` | object | null | Domain DMARC: { policy, subdomainPolicy, pct, rua, record } of _dmarc.<domain>; null when absent or not checked. |
| `spfDmarcLookup` | string | null | SPF/DMARC lookup: ok \| failed: failed means the TXT lookups failed, so a null domainSpf / domainDmarc is unknown rather than absent; null when not checked. |
| `status` | string | Status: ok \| error \| skipped_budget \| skipped_free_plan \| skipped_unmetered |
| `charged` | boolean | Charged: Whether this record incurred a pay-per-event charge. |
| `chargedEvent` | string | Charged event: Pay-per-event event charged for this record (present only when charged). |
| `chargedCount` | integer | Events charged: Events actually charged when the charge came back short (present only then; a warning explains it). |
| `source` | string | Source: dns: the checks ran on DNS lookups and bundled lists. |
| `fetchedAt` | string | Checked at: ISO timestamp. |
| `error` | object | Error: { code, message, provider?, status? } when status is not ok: dns_lookup_failed, timeout; codes set by the runtime: budget_exhausted, free_plan_limit, unmetered, aborted, charge_failed, record_too_large, invalid_record, dataset_push_failed. |
| `warnings` | array | Warnings: Notes about this record, e.g. a charge that came back short. |
| `raw` | object | Raw check result: The unmodified pre-check result (only with includeRaw). |

Example record:

```json
{
  "input": "support@apify.com",
  "email": "support@apify.com",
  "verdict": "role",
  "quality": "risky",
  "reason": "Role account (a shared mailbox such as info@ or sales@), not a person",
  "deliverable": "unknown",
  "domain": "apify.com",
  "canonicalEmail": "support@apify.com",
  "syntaxValid": true,
  "syntaxError": null,
  "domainExists": true,
  "mx": [
    "aspmx.l.google.com",
    "alt1.aspmx.l.google.com",
    "alt2.aspmx.l.google.com",
    "aspmx2.googlemail.com",
    "aspmx3.googlemail.com"
  ],
  "nullMx": false,
  "hasMailServer": true,
  "mailProvider": "google",
  "disposable": false,
  "freeProvider": false,
  "role": true,
  "typoSuggestion": null,
  "domainSpf": {
    "record": "v=spf1 a mx include:_spf.google.com include:mailgun.org -all",
    "multipleRecords": false,
    "allQualifier": "-all",
    "includes": [
      "_spf.google.com",
      "mailgun.org"
    ]
  },
  "domainDmarc": {
    "record": "v=DMARC1; p=reject; sp=reject; pct=100",
    "policy": "reject",
    "subdomainPolicy": "reject",
    "pct": 100,
    "rua": []
  },
  "status": "ok",
  "charged": true,
  "chargedEvent": "email",
  "source": "dns",
  "fetchedAt": "2026-10-14T10:00:00.000Z"
}
```

## FAQ

**Does it check whether the mailbox exists?**

No. It never connects to the mail server (SMTP probing from cloud IPs is unreliable and gets blocked). It settles what DNS and the bundled lists can settle: invalid syntax, domains that do not exist or accept no mail, and disposable domains. For a mailbox-level verdict (valid, invalid, catch-all) run the addresses that pass through Email Verifier.

**Which addresses are charged?**

Every address that gets a verdict, including invalid syntax, is charged one email event ($0.0004). An address whose domain could not be looked up because DNS failed comes back with status error and verdict unknown and is not charged; run it again later.


## Related

- [Website Contact Details Scraper](https://www.sfoln.com/actors/company-contacts-finder.md) (`sfoln/company-contacts-finder`)
- [Google Maps Leads Scraper + Emails](https://www.sfoln.com/actors/google-maps-business-leads.md) (`sfoln/google-maps-business-leads`)
- [Phone Number Validator](https://www.sfoln.com/actors/phone-validator.md) (`sfoln/phone-validator`)

Publisher: SFOLN LLC, contact@sfoln.com. Catalogue: https://www.sfoln.com/catalog.json. Agent guide: https://www.sfoln.com/agents.md.
