Bounce Rates and Spam Traps When Validating an Email List
A verifier returned twelve fields for three addresses. None of them was spam_trap, and none could be. Here is what verification fixes and what it cannot.

Copy this line to your agent to verify a list before it hits your sender.
set up https://monid.ai/SKILL.md and use hunterio /email-verifier on every address before sending
The two problems in this question are not the same problem, and almost every answer treats them as one. Verification fixes bounces well: on 2026-09-03 a verifier separated a real mailbox from an invented one at the same domain, correctly, in one call. It cannot fix spam traps at all, and the field list explains why in about ten seconds. This guide runs through Monid, the OpenRouter for agent tools.
What does an email verifier actually check?
Twelve fields, and they are checking four different things at four different levels.
The measurement
Three addresses through hunterio/email-verifier on 2026-09-03:
support@stripe.com | invented mailbox, same domain | hello@monid.ai | |
|---|---|---|---|
status | valid | invalid | valid |
result | deliverable | undeliverable | deliverable |
score | 100 | 0 | 92 |
gibberish | false | true | false |
mx_records | true | true | true |
smtp_server | true | true | true |
smtp_check | true | false | true |
accept_all | false | false | false |
The four levels
Syntax. regexp and gibberish. Free, instant, and catches typos and random strings before you spend anything.
Domain. mx_records and smtp_server. Does the domain accept mail at all. Note that the invented address passed both: the domain is perfectly healthy, which is exactly why domain-level checks are not enough.
Mailbox. smtp_check. This is the field that did the work. It asks the receiving server whether that specific mailbox exists, and it is the only one that separated the real address from the fake at an identical domain.
Reputation. disposable, webmail, block. Is this a throwaway provider, a personal address, or a domain that blocks verification.
The field that voids everything
accept_all. When a domain is configured to accept mail at every address, the mailbox check cannot fail, so deliverable means only "the domain said yes to everything". All three of our addresses returned false, which is why their results are meaningful. On a catch-all domain the same result would be worthless.
And the field that is not there
Look at the full list: status, score, email, regexp, gibberish, disposable, webmail, mx_records, smtp_server, smtp_check, accept_all, block. No spam_trap. The next section is about why that is not an omission.
📖 See also The Best Email Verification API in 2026
Why can no verifier detect a spam trap?
Because a spam trap is a working mailbox. Every signal verification measures, it passes.
What a trap actually is
An address operated by a mailbox provider or a blocklist to catch senders who are not managing their lists. It has valid syntax. Its domain has MX records. The SMTP check succeeds, because the mailbox genuinely exists and genuinely accepts mail. It would score 100 on the table above, sitting in the same column as support@stripe.com.
That is the entire design. A trap that bounced would catch nobody.
The three kinds, and why only one is even theoretically visible
Pristine traps are addresses never owned by a person, published where only a scraper would find them. If a scraped address is in your list, you cannot distinguish it from a real one by inspecting it.
Recycled traps are real addresses, abandoned, later repurposed by the provider. They were valid when you collected them and are valid now. The only signal is time and silence, which is a property of your relationship with the address rather than of the address.
Typo traps are the one class verification helps with. @gmial.com and similar are caught by syntax and domain checks, and this is a genuine and useful part of what a verifier does. Gating a signup form on verification is where that catch pays off earliest.
So what the verifier is for
Bounces. And it is good at that: it correctly rejected an address at a domain whose MX and SMTP server were both healthy, which is precisely the case that syntax and domain checks miss and that drives hard-bounce rates. The same assert-on-the-value discipline runs through the Amazon ASIN guide.
Treating a clean verification result as protection against traps is the mistake, and it is easy to make because the result looks like a clean bill of health.
The other thing the score is telling you
Both deliverable addresses verified, but one scored 100 and the other 92, with identical booleans across the whole field set. The score is carrying something the flags do not expose, most likely source and confidence signals. The practical reading: treat the score as a ranking within your list rather than a threshold, and if you must set a cut, set it on your own bounce data rather than on a number that felt right.
How do you actually protect a sending domain?
Three steps. Only one of them is verification, and it is not the most important.
For agents
Grab an API key at app.monid.ai, then paste this to your agent and hand it the key:
set up https://monid.ai/SKILL.md
It learns the whole discover, inspect, run workflow itself. More in the agent quickstart.
For humans
npm install -g @monid-ai/cli
monid keys add -k <your-api-key> -l main
Step 1. Verify, and act on the whole response
What it does. Removes the addresses that would hard bounce.
The endpoints. hunterio/email-verifier, billed per result.
The call.
monid run -p hunterio -e /email-verifier --query '{"email": "support@stripe.com"}'
What comes back. The twelve fields above. Route on three of them rather than on result alone:
if not v["smtp_check"] and not v["accept_all"]:
drop(addr) # confirmed undeliverable
elif v["accept_all"]:
hold(addr) # unknowable; send only with a real reason
elif v["disposable"]:
drop(addr) # a throwaway is not a prospect
The middle branch is the one people skip. Catch-all addresses are neither verified nor refuted, and silently treating them as deliverable is how a "verified" list still bounces.
What it costs. About a cent per result. Current figures at monid.ai/tools.
Step 2. Never send to an address you did not collect yourself
What it does. Removes the only realistic source of pristine traps.
The call. No endpoint. Pristine traps arrive in bought and scraped lists, because that is exactly what they are placed to catch. No verification step undoes that, and this single rule prevents more damage than any tooling. If you need contacts, source them so you know what they are, the approach in surveying leadership contacts before revealing addresses.
Step 3. Sunset the silent ones
What it does. Removes recycled traps, which are otherwise undetectable.
The call. No endpoint, just a rule:
if last_engaged(addr) < today - timedelta(days=180):
stop_sending(addr)
An address that has not opened or clicked in six months is either uninterested or no longer a person, and both cases argue for stopping. This is the only defence against recycled traps that exists, because a repurposed mailbox looks identical to a real one from the outside.
Give this to your agent![]()
Set up https://monid.ai/SKILL.md, and then use Monid to verify these 500 addresses, split them into deliverable, undeliverable and catch-all, and flag anyone who has not engaged in six months.📖 See also Enrich a List From Email Addresses
What is a bounce rate telling you?
Less than people assume, and the shape matters more than the number.
Hard versus soft
A hard bounce is a permanent refusal: the mailbox does not exist. This is what verification prevents and what mailbox providers judge you on. A soft bounce is temporary, a full mailbox or a busy server, and it is mostly noise unless it persists.
Why the trend matters more than the level
A stable 1% is a list with normal churn. A rate climbing from 1% to 4% over three sends is a list going stale, and it is a better early warning than any single reading. Track the rate over time, the same reasoning as watching a block rate rather than an error rate in the proxy guide, and classify what comes back rather than retrying it blindly, as in rate limiting a third party API.
What a very low bounce rate does not prove
Nothing about traps. A list of scraped addresses can verify at 99% deliverable and still contain pristine traps, and the clean bounce rate is exactly what makes people confident enough to keep sending. The metric that would tell you is complaint rate and blocklist status, not bounces.
The number that actually predicts trouble
Complaints. Mailbox providers weigh spam complaints far more heavily than bounces, and the commonly cited danger line is around 0.1%, which is one complaint per thousand delivered. If you watch one number, watch that one.
Which endpoint should I use for which job?
| Endpoint | What it does | Input | Output | Best for | Billing |
|---|---|---|---|---|---|
hunterio/email-verifier | Verifies one address | An email | Twelve fields including smtp_check and accept_all | Removing hard bounces | Per result |
hunterio/email-count | Sizes a domain | A domain | Totals by department and seniority | Deciding whether a domain is worth working | Free per call |
hunterio/email-finder | Finds a likely address | Name and domain | Address with confidence | Building an address you can verify | Per result |
hunterio/multi-domain-search | Surveys people, masked | Filters | Masked rows with verification.status | Sourcing you did yourself | Free per call |
Every row was verified with monid inspect on 2026-09-03. The table gives billing shape rather than figures; shape drives design and current numbers live on monid.ai/tools.
The last row is the one that addresses the trap problem, and it does so by changing where the list comes from rather than by cleaning it afterwards. Its rows carry verification.status before you pay to reveal anything, so the list is verified at the point of sourcing rather than rescued at the point of sending. That is the same buy-versus-build split worked through in the firmographics cost comparison.
When is verification not the answer?
Three cases.
Your list is bought or scraped. Verification will make it look clean and will not make it safe. The problem is provenance and no per-address check reaches it.
Your complaint rate is the issue. If people are marking you as spam, every address is real and every one is deliverable. That is a targeting and consent problem, and cleaning the list changes nothing. Turning cold emails into real people is about fixing the relevance rather than the addresses.
You are sending to catch-all domains at volume. Verification returns accept_all: true and nothing else, so you are flying blind by definition. Small volumes to catch-all domains are a normal risk; large ones are a decision to send unverified mail.
And the disclosure: this is Monid's blog and we sell per-call access to the verifier described here. The central claim of this article is that the thing you are most worried about is the thing it cannot detect, and the two steps that actually defend against traps, sourcing your own contacts and sunsetting silent ones, are policies rather than purchases.
Conclusion
Verification and spam traps are two problems wearing one name. The verifier did its job on 2026-09-03: it passed a real mailbox and rejected an invented one at the same healthy domain, using smtp_check, which is the only field that could tell them apart.
But the response carried twelve fields and none of them was spam_trap, because a trap is a working mailbox that would score 100 alongside a genuine address. Nothing inspectable distinguishes them. So the defence is not a better check, it is not sending to addresses you did not source and not sending to addresses that stopped responding six months ago.
And watch accept_all before you trust any result, because on a catch-all domain "deliverable" means the server says yes to everything, including addresses that do not exist.
Free next step: run monid run -p hunterio -e /email-count --query '{"domain": "yourtarget.com"}' on a domain from your list. It costs nothing and tells you whether the addresses you hold look anything like what is actually there. Start at monid.ai.
FAQ
What is the difference between pristine, recycled and typo spam traps?
A pristine trap was never a person's address; it is seeded on web pages specifically so that anyone harvesting addresses picks it up, which makes its presence in your list direct evidence of scraping. A recycled trap was a genuine mailbox, abandoned by its owner, then reactivated by the provider as a trap after a long dormancy, so it was legitimately collected and has simply gone quiet. A typo trap is a misspelled version of a common domain registered to catch careless senders, and it is the only one of the three that verification reliably catches, through syntax and domain checks.
What should you do with catch-all domains?
Decide deliberately rather than by default. A catch-all domain returns accept_all: true and the mailbox check becomes meaningless, so you genuinely do not know whether the address exists. For a small number of high-value targets, sending is a reasonable risk. For a large share of a list it is not, because you are choosing to send unverified mail at volume. Many teams hold catch-all addresses in a separate segment and send to them only when there is an independent reason to believe the person is real, such as a LinkedIn profile or a recent role confirmation.
What bounce rate is acceptable?
Under 2% is generally treated as healthy and above 5% draws attention from mailbox providers, but the level matters less than the direction. A steady 2% on a large list is normal churn; a rise from 1% to 4% across three consecutive sends means the list is decaying faster than you are cleaning it. Watch complaint rate alongside it, because the widely cited threshold there is roughly 0.1%, and complaints damage sender reputation considerably faster than bounces do.
How often should you re-verify a list?
Before every campaign for anything older than about ninety days, and always before a first send to a list you have not used. Business addresses decay at roughly two to three percent a month through job changes alone, so a list verified six months ago is materially different from the one you hold today. The cheaper habit is verifying at the point of collection and then re-verifying only the segment you are about to send to, which keeps the per-campaign cost proportional to what you actually use.
Last updated September 2026.

