How to validate email addresses via API: MX, disposable and typo checks
Short answer: to validate an email address via API without sending mail, run four checks: (1) syntax, (2) DNS: does the domain exist and publish MX records (and not a "null MX"), (3) risk flags: disposable domain, role account (info@, sales@), free webmail, and (4) typo detection on the domain (gmial.com → gmail.com). The Fairquery Email Validator does all of this in one call for $0.00079 per email on Apify, and is also available on RapidAPI. It returns a valid / risky / invalid / unknown verdict with reason codes.
What "email validation" can and cannot tell you
Email validation is about answering one practical question before you store or email an address: can this address plausibly receive mail, and is it worth keeping? There are two families of techniques:
- DNS-based checks (what this post covers): look at the address and its domain. Is it well-formed? Does the domain exist? Does it publish mail servers? Is it a known throwaway domain? These checks are fast, cheap, and never touch the recipient's mailbox.
- SMTP probing: connecting to the recipient's mail server and asking whether a mailbox exists without delivering a message. It can confirm more, but many providers deliberately give ambiguous answers ("catch-all" domains accept everything), and probing at volume can damage your IP reputation and conflict with provider terms.
The Fairquery validator deliberately does not probe SMTP. So valid means "well-formed, deliverable domain, no risk flags", not "mailbox confirmed". That is an honest limit of every DNS-only validator, and you should design your workflow around it (for example, combine it with a double opt-in confirmation email for signups).
The checks, one by one
1. Syntax
The full RFC 5322 grammar allows strange things (quoted local parts, comments) that almost no real mailbox uses. A pragmatic validator accepts the RFC 5321/5322 subset people actually use and converts internationalised domains (IDN) to punycode before looking them up. Regex-only validation stops here, which is why it lets jane@acme.con through.
2. Domain and MX records
Mail is delivered to the hosts listed in the domain's MX records. If the domain doesn't exist (DOMAIN_NOT_FOUND) or has no mail server at all (NO_MAIL_SERVER), mail will bounce. Two subtleties:
- Null MX (RFC 7505): a domain can publish an MX record of
.to say "I never accept mail". That is a definiteinvalid(NULL_MX). - Implicit MX: with no MX record, senders fall back to the domain's A/AAAA record. Mail may work, but it is unusual for real mail domains, so it is flagged
IMPLICIT_MX_ONLY(risky) rather than passed silently.
3. Disposable, role and free-provider flags
- Disposable domains (temporary inboxes) are a common source of fake signups and trial abuse. The validator uses a bundled CC0 list from the open-source
disposable-email-domainsproject (9,800+ domains, subdomains matched). No list is complete; new throwaway domains appear constantly. - Role accounts like
info@,sales@,support@reach a team or a shared inbox, not a person. Fine for some uses, undesirable for others; setallowRoleAccounts: falseto mark them risky. - Free webmail (Gmail, Outlook.com, Yahoo and so on) is normal for consumers but often a signal on B2B lead forms. Set
allowFreeProviders: falsefor B2B lists.
4. Typo suggestions
A surprising number of bad addresses are simple domain typos: gmial.com, hotmial.com, outlok.com. The validator compares the domain against popular providers by edit distance and returns a did_you_mean suggestion. The best place to use this is on the signup form itself ("Did you mean jane@gmail.com?"), before the bad address ever reaches your database.
Bonus: mail provider, SPF and DMARC
The response also reports the detected mail provider (for example Google Workspace or Microsoft 365) and whether the domain publishes SPF and DMARC, including the DMARC policy. That's useful context for lead qualification and for spotting domains that are set up for real business mail.
Free options
- Do it yourself. A syntax check plus a DNS MX lookup is a few lines in most languages (for example
dig MX example.com, Node'sdns.resolveMx, or Python'sdnspython). Add the freedisposable-email-domainslist and you have a basic validator. You'll maintain the typo logic, role list, caching and edge cases (null MX, IDN) yourself. - Fairquery's free offline tool. The open-source repo (MIT) ships a local MCP server with a free
check_email_syntaxtool that runs offline without a token.
API option: Fairquery Email Validator
Inputs (all optional except emails):
| Field | Default | Meaning |
|---|---|---|
emails | – | Addresses; entries can be comma/semicolon/newline lists or Name <addr> |
checkDns | true | MX/A lookups (off = syntax only) |
checkSpfDmarc | true | Report SPF/DMARC and DMARC policy |
allowRoleAccounts | true | If false, role addresses become risky |
allowDisposable | false | If true, disposable domains are not risky |
allowFreeProviders | true | If false, free webmail becomes risky |
maxEmails | 10000 | Safety cap per run |
curl
Run the Actor synchronously and get results back in one request (replace $APIFY_TOKEN with your Apify API token):
curl -X POST \
"https://api.apify.com/v2/acts/fairquery~email-validator-mx-disposable/run-sync-get-dataset-items?token=$APIFY_TOKEN" \
-H "Content-Type: application/json" \
-d '{"emails": ["jane@acme.com", "info@apify.com", "bob@gmial.com"], "allowFreeProviders": false}'
JavaScript (Node.js)
import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('fairquery/email-validator-mx-disposable').call({
emails: ['jane@acme.com', 'bob@gmial.com'],
allowRoleAccounts: false,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
for (const r of items.filter((i) => i.type === 'email')) {
console.log(r.email, r.verdict, r.reasons, r.did_you_mean ?? '');
}
Python
import os
from apify_client import ApifyClient
client = ApifyClient(os.environ["APIFY_TOKEN"])
run = client.actor("fairquery/email-validator-mx-disposable").call(
run_input={"emails": ["jane@acme.com", "bob@gmial.com"], "allowFreeProviders": False}
)
for r in client.dataset(run["defaultDatasetId"]).iterate_items():
if r["type"] == "email":
print(r["email"], r["verdict"], r["reasons"], r.get("did_you_mean"))
Prefer RapidAPI's key-based billing and code snippets? Use the RapidAPI listing; its endpoint docs and playground show request formats for many languages.
What comes back
Each address gets one row. Abridged shape (field names are real; values depend on live DNS at check time):
{
"type": "email", "email": "bob@gmial.com", "domain": "gmial.com",
"verdict": "risky", "reasons": ["POSSIBLE_TYPO", "..."],
"syntax_valid": true, "is_disposable": false, "is_role_account": false,
"is_free_provider": false, "did_you_mean": "bob@gmail.com",
"domain_exists": true, "has_mx": false, "null_mx": false, "implicit_mx": true,
"mx_records": [], "mail_provider": null,
"has_spf": false, "has_dmarc": false, "dmarc_policy": null,
"source_url": "https://cloudflare-dns.com/dns-query?name=gmial.com&type=MX",
"checked_at": "..."
}
Reason codes: INVALID_SYNTAX, DOMAIN_NOT_FOUND, NULL_MX, NO_MAIL_SERVER (→ invalid); DISPOSABLE_DOMAIN, ROLE_ACCOUNT, FREE_PROVIDER, POSSIBLE_TYPO, IMPLICIT_MX_ONLY (→ risky, depending on the allow flags); DNS_NOT_CHECKED (→ unknown). If a DNS lookup fails you get an error row (DNS_LOOKUP_FAILED, with retryable), and error rows are never charged. Duplicates (case-insensitive) are skipped.
Using it from an AI agent
Agents can call the Actor through Apify MCP with {"actor": "fairquery/email-validator-mx-disposable", "input": {"emails": ["jane@acme.com"]}}, or run the stdio MCP server from the GitHub repo (validate_emails, plus the free check_email_syntax).
Pricing
$0.00079 per email checked on Apify (pay per event; error rows are free). DNS lookups are cached per domain, so lists with many addresses at the same company are efficient. RapidAPI pricing is shown on the listing.
Practical recommendations
- Signup forms: reject
invalid, showdid_you_meaninline, and block or challenge disposable domains. Still send a confirmation email. - B2B lead lists: set
allowFreeProviders: falseandallowRoleAccounts: false; reviewriskyrows rather than deleting them blindly. - Old CRM data: re-check periodically; domains expire and companies change mail setups.
- Compliance: validation is not consent. Follow CAN-SPAM, GDPR/ePrivacy and similar rules when emailing.
FAQ
How do I check if an email address is valid without sending an email?
Check the syntax, then look up the domain's DNS: it must exist and publish MX records (and not a null MX). Add disposable-domain, role-account and typo checks. The Fairquery Email Validator does all of this via API without sending mail or probing SMTP.
Can an API confirm that a mailbox really exists?
Not reliably without SMTP probing, and even then catch-all domains accept everything. The Fairquery validator does not probe SMTP; 'valid' means well-formed, deliverable domain and no risk flags, not mailbox confirmed.
How do I detect disposable email addresses?
Match the domain (including subdomains) against a maintained disposable-domain list. Fairquery uses the CC0 disposable-email-domains list (9,800+ domains) and returns is_disposable plus a DISPOSABLE_DOMAIN reason code.
What is a null MX record?
An MX record pointing to '.' (RFC 7505) that says the domain never accepts email. Addresses at such domains are invalid.
How much does the Fairquery Email Validator cost?
$0.00079 per email checked on Apify, pay per event. Error rows are never charged. It is also listed on RapidAPI.
Can AI agents use it?
Yes. Call Actor fairquery/email-validator-mx-disposable through Apify MCP, or run the stdio MCP server from the GitHub repo, which exposes validate_emails and a free offline check_email_syntax tool.
Honest limits: DNS-based validation cannot guarantee a mailbox exists or accepts mail. Use results to reduce bounces and filter obvious junk, not as proof of deliverability.
Source and docs: github.com/fairquery/email-validator-mx-disposable · Apify Store · RapidAPI · all Fairquery tools