MAILCRAFT
Home Features Pricing About Blog Contact Log in Get Started →
List management

Address verification without sending an email

Klawisze klawiatury ułożone w słowo EMAIL na łososiowym tle

Verifying an address without sending an email is not one call to one API. It is a sequence of tests: syntax, DNS, MX records, an SMTP dialog cut off before the DATA command. Each stage filters out a different class of errors and none of them replaces the others. We keep validation separate from sending, because a hard bounce costs sender reputation faster than a low open rate. The large filtering providers count rejections at the level of the IP and the whole domain, so one dirty list can wreck the deliverability of campaigns that have nothing to do with it. We write from the position of an operator running its own fleet of sending servers, not a reseller of someone else’s infrastructure. And let me be clear right away: there is no hundred percent certainty. Nobody honest will promise it.

What you really check before the first message goes out

Without sending anything you can establish a surprising amount. Whether the address is written correctly, whether the domain exists, whether it is ready to accept mail, how the recipient’s server reacts to a specific recipient, and what the quality signals of the address itself are. That is enough to cut off most of the junk from forms and imports.

And what you will not establish? Whether the mailbox is read. Whether the owner changed jobs. Whether the domain runs catch-all and will accept any string of characters before the at sign. Whether the address is a spam trap set up specifically to catch senders who buy lists.

That is why the verification result is not binary. We treat it as four states, not two. A valid address goes onto the list. A risky one goes to a separate segment, with cautious sending. An unresolved one gets flagged and waits for evidence from a real send. A rejected one drops out immediately.

Tip: if a tool returns only “valid” and “invalid”, it is hiding the unresolved state from you. Those addresses will end up in the send anyway, just without a warning.

Syntax and normalisation: the cheapest filter in the whole chain

Start with validating the way the address is written, because it costs a fraction of a millisecond and needs no network. Check the address against real-world use, not against the full RFC 5322. The standard allows constructions that no mail server will handle in practice. Regexes copied from forums have the opposite flaw: they let obvious junk through and reject correct addresses with a hyphen or a long TLD.

Then normalisation. Always before comparison. Trim whitespace, lowercase the domain, remove invisible characters pasted in from a spreadsheet. Convert domains with national characters to punycode before you send any DNS query. Without that the resolver returns an error and you write off a correct address as dead.

Plus addressing and dots in the local part are a business decision, not a technical one. At some providers jan.kowalski+shop and jankowalski land in the same mailbox. Want to count unique recipients? Collapse those variants. Do you respect consent per address? Do not collapse them, because you will take away a person’s control over what they receive.

Deduplicate on the normalised form, never on the raw string. Otherwise the same person gets three copies of the mailing and files a complaint.

The typical CSV import traps we see most often, most of which disappear once you map the columns properly before the import:

  • a semicolon instead of a comma as the separator, so the whole row lands in one column,
  • two addresses in one cell, split by a comma or a slash,
  • quotes and angle brackets from a mail client in the Jan Kowalski <jan@…> format,
  • a space at the end of the address, invisible in the spreadsheet.

DNS and MX records: does the domain accept mail at all

The second step is a query for MX records. No MX and no A record means the address is undeliverable. End of story. Checking such an address any further wastes time and connections.

A domain visible in WHOIS does not mean it handles mail. Parked domains, one-page sites and domains bought for a future project usually have no MX configured. The owner has a website, not a mailbox.

The SMTP standard allows a fallback to the A record when no MX exists. Formally such an address can be deliverable. We mark it as risky, not valid, because in practice it is most often an unfinished configuration rather than a deliberate decision by an administrator.

Keep DNS results in a cache together with the date of the check. Querying the same domains on every import drags out the process and loads resolvers for no reason. Respect the TTL, but do not treat a result from six months ago as current.

Two categories deserve a separate flag: domains registered a few days ago, and typos in the addresses of popular providers. The first are sometimes throwaways used for sign-ups. The second are an ordinary human error, worth fixing rather than discarding.

The checklist at this stage: MX records, an A record as fallback, correct punycode conversion, the age of the cache entry.

An SMTP dialog without sending: how far it reaches and where it ends

The most informative test is a conversation with the recipient’s server, broken off before anything is transmitted. You open the connection, introduce yourself with EHLO, give MAIL FROM, then RCPT TO with the address being verified. You read the response, send RSET and QUIT. The DATA command is never issued, so there is no content and no message in the mailbox.

How to read the response codes

A 250 response to RCPT TO means the server accepts the recipient. Code 550 is an explicit rejection, most often a non-existent account. And codes from the 4xx family are not a rejection, only a request to come back later. Greylisting and tarpitting work exactly like that: the first attempt gets a temporary refusal, the next one after a reasonable interval goes through.

Where the test stops working

Catch-all answers 250 to every address in the domain, including a random string of characters. The result is then unresolved and that is how it has to be recorded, instead of pretending success. Large mailbox providers often do not reveal whether an account exists at this stage, and some block probing by IP address.

The probe also demands order on your side. A correct PTR record, a consistent Return-Path, an IP with history. Without that the conversation ends in a block, and you interpret it as an address error.

Tip: do not probe an entire database from one IP in a single run. Spread it over time and keep your verification addressing away from production IPs, so that a possible block does not touch real sending.

Address quality signals beyond the existence of the account

An address can work and still do harm. Role addresses (office, contact, info, sales) technically accept mail, but several people read them, nobody feels like the recipient and complaints show up faster than clicks.

Disposable domains require an updated list, not a file from years ago. New ones appear every day, and a static dictionary ages in weeks.

The worst category is spam traps. Recycled ones, meaning old mailboxes reactivated after years of silence, can sometimes be detected by the lack of activity. Pristine ones, created purely as bait, cannot be told apart by any SMTP probe. They will answer 250 like any valid address.

Typos in the domains of large providers are better fixed than quietly rejected. Show the user a suggested correction in the form and let them confirm it.

It also happens that the problem is visible in the structure of the file, not in the server’s response. A list sorted alphabetically, nothing but role addresses from one industry, no sign-up dates whatsoever – that is not a list collected with consent.

The result categories we use in practice:

  1. Valid – syntax in order, MX present, the server accepts the recipient.
  2. Risky – role address, fallback to an A record, fresh domain, suspected typo.
  3. Unresolved – catch-all, a blocked probe, persistent 4xx.
  4. Rejected – bad syntax, no MX and no A, an explicit 550.

Validation at sign-up instead of cleaning the database after the fact

The cheapest verification happens at the moment of sign-up. Checking syntax and the presence of MX in the form takes a fraction of a second and removes most of the problem before the address even enters the database. Cleaning a list of a hundred thousand a year later costs many times more.

Confirming a sign-up with double opt-in looks contradictory to the title of this text, but the contradiction is only apparent. A confirmation message does not check whether the mailbox exists, only the intent of the person. Two different things. Both needed, and it is worth weighing separately what confirmation costs you and when it really is necessary.

Against bots flooding the form, a hidden honeypot field and a minimum fill-in time both work. An automated script fills in everything, including invisible fields, and does it in a fraction of a second. Without that barrier, trap addresses deliberately injected by scripts end up on the list.

A sign-up form rarely stands on its own – most often the data comes from a shop, a CRM or a landing page, so it is worth looking at the available integrations with external systems and moving validation to the very moment the contact is handed over.

Keep fresh contacts in a separate segment and watch the bounce rate on the first sends, instead of firing the whole database at once. Addresses collected years ago need rechecking before reactivation, even if they were once clean.

If you are planning to move a list, take a look at the MailCraft email marketing platform and see how the import and bounce handling work.

Tip: a bounce from the first real send is worth more than any preliminary test. Flag and disable such addresses immediately, automatically, without a manual decision.

Verification and the law: GDPR and PKE article 398

An email address is personal data. Checking it is processing and needs a legal basis, exactly like sending. An external verification provider means entrusting data, so a data processing agreement, and when processing happens outside the EEA, additional transfer safeguards.

Consent for commercial communication is required towards companies as well. An address published on a contact page is not consent, only a channel for contact in the matters it concerns. The Polish electronic communications law (PKE) in article 398 makes no exception for B2B here.

Technical verification does not replace consent. An address can exist, answer 250 and still be one you are not allowed to send an offer to. These are two independent conditions and both must be met.

Keep a consent register with the date, the source and the exact wording of the clause that was displayed at the time. In case of a complaint that is the only evidence that counts.

Our approach: we keep list data on our own infrastructure, without passing it to intermediaries in the background. About what we do not have ready yet, we say so plainly and show a plan instead of describing a feature you will not see in the panel.

Summary

Run the tests from the cheapest to the most expensive: syntax, DNS, MX, the SMTP dialog, quality signals. Each stage catches a different class of errors and none of them replaces the others. Skipping the first steps means firing probes at addresses that would have failed on a regex.

An unresolved result is a normal state with catch-all and at large providers. Report it honestly, instead of adding it to the pool of valid ones so the chart looks better.

Sender reputation stands on three things: a clean list, a sensible warmup and stable authentication records. SPF, DKIM and DMARC have to be consistent with the Return-Path, and the PTR has to match the host name. Make changes to those records carefully, because filters react to sudden differences.

Weave legal compliance into the process, do not bolt it on at the end. A consent register and processing agreements are easy when they grow together with the system, and painful when you have to reconstruct them after the fact.

We do not promise to get around filters and we know of no method that would. The goal is simpler: to send to people who want it, at addresses that exist. If you want to see how these pieces look in a finished system, take a look at the MailCraft platform features and compare them with what your process requires.