A verification result can be wrong in two directions
Every verification method has two ways to be wrong, and they are not equally visible. One sends a message to a mailbox that no longer exists and returns a bounce. The other filters out a mailbox that works, and never returns anything at all.
Two errors, one of them silent
| Error | What happened | How you find out |
|---|---|---|
| False positive | Marked deliverable, the mailbox refuses mail | A bounce, a complaint, a rising spam rate. Loud, immediate, measurable. |
| False negative | Marked undeliverable, the mailbox was fine | Nothing. The contact is gone from every list that uses the file, and no event reports the loss. |
False unknown | Marked unknown, the mailbox was answerable | Nothing, unless you count the unknown column - which most reports do not. |
This asymmetry is why a bounce-rate number can improve while a list gets worse: the second error removes future sends instead of producing failures, so it pushes the visible metric down.
What produces each direction
- False positives come from checking too little. Syntax-only and domain-level checks pass addresses that were never created. Catch-all domains answer
2xxfor every local part, so a mailbox-level check reports a green result for a mailbox that may not exist. Stale verdicts do the same thing more slowly: a probe taken a year ago describes a mailbox that may have changed hands since. - False negatives come from reacting to noise. Timeouts, holds and greylisting treated as refusals; a rate-limited probe host marked as bad data; a server that was briefly unreachable taken as a permanent answer. None of these are refusals, and all of them end up in the rejection column when a pipeline only has two states.
- Both come from a missing date. Without the probe time on the row, a verdict from three years ago and one from this morning are the same string, and neither can be ranked or refreshed.
How to size the invisible error
- Sample the rejects. Take a random block of addresses your list marked undeliverable and probe them again, slowly, at low rate. Anything that answers deliverable is a false negative you were about to ship as a permanent decision.
- Keep a suppressed-but-recoverable group. Instead of deleting rejects, park them with their reason and date. The cost of keeping a row is a database row; the cost of deleting a good contact is a lost account.
- Report both columns. A verification report that shows only the bounce rate is a report about one of two errors. Add the unknown count and the age distribution of your verdicts next to it.
- Probe at the moment of use for the high-value rows. If a segment is expensive to get wrong, the check that matters is the one taken while the message goes out, not the one taken when the list was built.
The visible half still matters. Gmail's sender guidelines ask senders to keep the user-reported spam rate under 0.10% and never let it reach 0.30%, and since June 2024 senders who exceed 0.30% lose access to mitigation - so the loud error has a hard ceiling. The quiet one has no ceiling at all, which is why it deserves a column in the report.
What TAPAC returns
TAPAC probes the mailbox inside the search that found the contact and returns three states rather than two - deliverable, undeliverable, and unknown for catch-all domains and unanswered probes - with the probe time and the source page or profile on every row. Silence is never written as a rejection, and every verdict carries the date it was taken. 100 free searches, then $0.10-0.50 per contact.
npx -y @tapacapi/mcp # tools: tapac_find_contacts, tapac_status # or hosted: https://tapacapi.com/mcp # or REST: POST https://tapacapi.com/v1/contacts/search
Related: a timeout is not a no, a verdict without a date is an opinion, and what catch-all domains do to a green result.
← Back to TAPAC