FairqueryBlogToolsAboutSecurityllms.txt

How to validate email addresses via API: MX, disposable and typo checks

Fairquery ·

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:

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:

3. Disposable, role and free-provider flags

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

API option: Fairquery Email Validator

Inputs (all optional except emails):

FieldDefaultMeaning
emails–Addresses; entries can be comma/semicolon/newline lists or Name <addr>
checkDnstrueMX/A lookups (off = syntax only)
checkSpfDmarctrueReport SPF/DMARC and DMARC policy
allowRoleAccountstrueIf false, role addresses become risky
allowDisposablefalseIf true, disposable domains are not risky
allowFreeProviderstrueIf false, free webmail becomes risky
maxEmails10000Safety 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

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