DEV Community

shahil shaikh
shahil shaikh

Posted on

An Email Validation API That Only Runs the Checks You Actually Need

I want to start with a question.

When was the last time you needed to verify every single thing about an email address all at once?

Probably never. Most of the time maybe you just want to know one or two things. Is this a throwaway email? Is this a real domain? Does this address even look valid?

But if you have ever used an email validation API you already know the problem. Perhaps in most of the cases, you ask for one thing and it runs everything. You wait 2 seconds for a live SMTP probe that you never asked for. You get back a response with half the fields set to null. And you pay for all of it in latency whether you needed it or not.

That is where this API gives advantage.

The Idea Is Simple

You tell the API exactly which checks to run. Only those checks execute. Nothing else fires.

That is it. That is the whole idea.

It sounds obvious when you say it out loud. But almost no email validation API actually works this way. Most of them were all built around the assumption that you want everything. This one was built around the assumption that you know what you need.

How It Works in Practice

You pass a fields parameter with the checks you want.

Say you are building a signup form and you just want to block disposable emails. One field. One check.

GET /v1/validate?email=user@gmail.com&fields=disposable
Enter fullscreen mode Exit fullscreen mode

That comes back in under 10ms. It is checking against 769,000 known throwaway domains entirely in memory. No DNS. No network. Nothing. Just an instant lookup.

Now say you want to be a bit more thorough on that signup form. Block disposable emails, check the domain actually receives mail, filter out role-based addresses like admin@ or noreply@, and catch spam traps.

GET /v1/validate?email=user@gmail.com&fields=mx,disposable,role,spamtrap
Enter fullscreen mode Exit fullscreen mode

Four checks. About 200ms. Still no SMTP. Still fast enough that your users will not notice anything.

And if you are verifying a high value lead and you genuinely need the full picture including whether the mailbox actually exists:

GET /v1/validate?email=user@gmail.com
Enter fullscreen mode Exit fullscreen mode

Leave out the fields parameter entirely. All 11 checks run. Live SMTP included. Takes 1 to 3 seconds but you are getting everything.

The point is you are in control. You decide what runs. You decide how long you are willing to wait. The API just does what you ask.

The 11 Checks Available

Field What it checks Speed
syntax Is the format valid Instant
mx Does the domain receive email ~200ms
smtp Does the mailbox actually exist ~1-3s
disposable 769,000+ throwaway domains Instant
role admin@, noreply@, support@ variants Instant
provider Free vs corporate domain Instant
spamtrap Honeypot and trap patterns Instant
subaddress Plus tag like user+spam@gmail.com Instant
intelligence Risky TLDs and gibberish domains Instant
auth SPF, DMARC, DKIM records ~300ms
typo gmial→gmail, yahooo→yahoo Instant

Notice how most checks are instant. That is because they run entirely in memory with no network calls. The slow ones — mx, smtp, auth — are slow because they have to talk to the outside world. That is just how it works. But since you only run the ones you need, you only wait when you actually have to.

How the Detection Stays Accurate Automatically

Every feature in this API uses two layers of detection.

The first layer is hardcoded. A fast in-memory lookup against a set of known values. This is what runs when someone submits a form on your site. Instant. Zero network. Works even if everything else goes down.

The second layer is automatic. It fetches live data at server startup and fills in everything the hardcoded layer does not cover. New throwaway domains. New risky TLDs. New variants of known patterns. All caught automatically without anyone having to update a list manually.

Here is what that looks like for each feature:

Disposable email detection

The hardcoded layer has 769,000 known throwaway domains already in memory when the server starts. The live layer fetches a community maintained blocklist from GitHub at startup and adds anything new. If that fetch fails for any reason the API just keeps running on the hardcoded layer. You never get an error. You never even know the fetch failed.

Role-based address detection

The hardcoded layer knows 101 exact prefixes. Admin. Noreply. Support. Billing. Postmaster. And dozens more. The automatic layer uses fuzzy segment matching to catch variants that are not in the list. Noreply2. Admin123. Support.team. Billing_dept. Caught automatically without any manual updates.

Free provider detection

The hardcoded layer covers 64 known domains. Gmail. Yahoo. Hotmail. And all their regional variants. The automatic layer uses MX fingerprinting — it checks where the domain's mail actually routes. Any company using Google Workspace or Microsoft 365 gets caught here too even if their domain is not on any list. Because the mail routes through Google or Microsoft infrastructure and that fingerprint gives it away.

Risky TLD detection

53 hardcoded TLDs that are known for high abuse rates. .xyz, .tk, .cf, .top, .icu and more. Plus a live community list fetched at startup that keeps it current.

Typo correction

53 known common typos in a dictionary. Gmial. Yahooo. Hotmial. Outloo. And a Levenshtein fuzzy matching layer underneath that catches anything new. If someone types a domain that looks almost like a real one but is not quite right, the API suggests the correction automatically.

What Every Response Looks Like

No matter which fields you request, every response always comes back with these:

{
  "email": "user@gmail.com",
  "result": "VALID",
  "reason": "All checks passed",
  "score": 100,
  "score_label": "Excellent",
  "latency_ms": 312
}
Enter fullscreen mode Exit fullscreen mode

The result is one of four things:

  • VALID — looks good, safe to use
  • RISKY — something is off but not definitively bad. Role-based address, risky TLD, sub-address, catch-all server
  • REJECT — do not use this. Disposable domain, spam trap, invalid syntax, no mail infrastructure
  • UNKNOWN — SMTP probe was inconclusive. Server blocked it or greylisted it

The score starts at 100 and goes down based only on the checks that actually ran. So if you only asked for disposable and role, the score only reflects those two. Nothing you did not ask for will affect it.

A Few Real Scenarios

You are building a signup form

You do not need SMTP. You do not need auth. You need to block the obvious junk fast.

fields=mx,disposable,role,spamtrap
Enter fullscreen mode Exit fullscreen mode

About 200ms. Blocks throwaway emails, role addresses, spam traps, and domains with no mail server. That alone will stop the vast majority of fake signups.

You have a list of 50,000 emails and need to clean it

fields=disposable
Enter fullscreen mode Exit fullscreen mode

Under 10ms per email. Pure memory lookup. You can process that entire list in seconds.

You just got a high value lead and want to be sure

(no fields param — all 11 checks run)
Enter fullscreen mode Exit fullscreen mode

Everything runs. Live SMTP included. You will know within 1 to 3 seconds whether that mailbox actually exists.

You want to show typo suggestions as someone types

fields=syntax,typo&quick=true
Enter fullscreen mode Exit fullscreen mode

Under 50ms. If they type gmial.com it suggests gmail.com before they even finish the word.

Bulk Validation

You can also send multiple emails in one call.

POST /v1/validate/bulk
{
  "emails": [
    "user@gmail.com",
    "test@mailinator.com",
    "admin@company.com"
  ],
  "fields": "disposable,role"
}
Enter fullscreen mode Exit fullscreen mode

The response order always matches the input order. Every result has its own verdict, score, and latency. The fields parameter applies to the whole batch so you are not running checks you do not need on any of them.

Being Honest About What It Cannot Do

Perhaps no email validation API is perfect and this one is no different.

Gmail, Yahoo, Outlook, and most major providers block SMTP probing. So smtp_skipped=true on those domains is the correct response, not a failure. The API detects this automatically and skips SMTP rather than timing out or giving you a wrong answer.

Catch-all servers accept every email address regardless of whether the mailbox exists. There is no way around that. If a server accepts everything, individual mailbox verification is impossible for anyone.

Some valid emails will score lower than expected. Temporary DNS issues, server timeouts, conservative configurations. It happens. Always give your users a way to verify manually if they think their address is being wrongly flagged.

And a brand new throwaway domain registered today might slip through until the community blocklist catches up with it. The window is small but it exists.

None of these are unique to this API. They are just the honest reality of email validation.

Why Selective Execution Changes Everything

Most email validation APIs were built around the idea of running everything and returning everything. That made sense when validation was a background job nobody was waiting on.

It makes no sense when you are running it in real time on a signup form.

The selective execution approach flips that completely. You decide what matters for your use case. The API runs only that. The response only contains what you asked for. No nulls. No wasted time. No paying in latency for checks you did not need.

Try It Free

Free tier is available on RapidAPI. 200 requests per month. No credit card needed. Enough to properly test it against your own use case before deciding if it is right for you.

Try Email Validator→

If you do try it I would genuinely appreciate an honest review on the listing. Good or bad. I want to know what is working and what is not. And it helps other developers make a more informed decision.

If you have dealt with email validation problems in your own projects — fake signups, dirty lists, deliverability issues — I would love to hear what you ran into in the comments. What broke? What was too slow? What did you wish worked differently?

Top comments (0)