← All articles

GTM Engineering

Your Enrichment Vendor Is Wrong 30% of the Time

Vendors self-report 95 to 98 percent accuracy. Run an independent SMTP test and roughly half of what they found bounces, because B2B contact data decays about 30 percent a year. Here is the verify-before-trust build that measures today, not ingest day.

· 14 min read

B2B contact data decays about 30 percent a year (ZoomInfo’s own churn figures), which means a record your vendor scraped 12 months ago has a roughly one-in-three chance of being wrong today, and the accuracy slide never says so. For years the enrichment decision ended at the match rate: the vendor reported 95 to 98 percent accurate, you signed, and you routed deals and sent email on the strength of that number. The number was real. It answered a question you do not care about. Every time I have run my own SMTP verification against the emails a vendor returned, valid-of-found lands closer to half. Both numbers are true, they measure different things, and the gap between them is where your outbound quietly dies.

Nobody spot-audits their provider. You pay the invoice, you trust the accuracy claim on the deck, and you send on data that is wrong often enough to matter. I found this the hard way on a name-enrichment job: 464K corporate records missing usable names, and after building a real verification layer I recovered about 329K of them. The other 135K were not recoverable at any accuracy I would stand behind, so I left them empty rather than ship guesses. A vendor would have “filled” most of that 135K and reported high coverage. Coverage is not accuracy. Watch what happens to a contact’s validity as the record ages, because this curve is the reason the deck and your inbox disagree.

Contact validity by record ageEvery record is a decaying asset
0%25%50%75%100%0 mo3 mo6 mo12 mo18 mo24 moAge of the record since the vendor last verified it
92%0 mofresh at ingest, near the deck number
Validity falls about 30 percent a year (ZoomInfo). A record verified at ingest is near 92 percent valid; the same record at 18 months is barely half sendable. The vendor's accuracy math still counts it as correct, because it was correct once.
~50%
Valid-of-found on an independent SMTP test versus the 97% on the deck
~30% / yr
B2B contact data decay rate (ZoomInfo)
20-30%
Of enterprise domains are catch-all, invisible to a bounce check

Self-reported accuracy measures the wrong thing

When a vendor says 97 percent accurate, they mean: of the records where we returned an answer, 97 percent matched our reference set at the time we ingested it. That sentence hides two holes.

First, “of the records where we returned an answer” excludes everything they could not find. Coverage and accuracy are different axes, and vendors only ever advertise the flattering one. ZoomInfo’s US email find rate is about 65 percent and its global rate about 35 percent (ZoomInfo), so a third to two-thirds of your list never entered the accuracy denominator at all.

Second, “at the time we ingested it” ages badly, and the decay curve above is exactly how badly. People change jobs. An email that was valid when the vendor scraped it 14 months ago is a hard bounce today, and it still counts as a correct record in their accuracy math because it was correct once. The curve does not care about the deck. At 12 months it has already given back roughly 30 percent of what was true at ingest.

Your SMTP test measures the thing you care about: does this email accept mail right now. That is why an independent verification pass on a vendor’s own output routinely lands near half valid. You are measuring today’s deliverability; they measured historical match. The deck reports the y value at age zero. Your inbox lives somewhere out on the curve, wherever the record happens to sit.

The measurement gap Two numbers, two denominators
Vendor accuracymatched at ingest= 97% of what they returnedYour SMTP testvalid nowstale + missing= ~50% of what you sentthe gap is your dead outbound
The vendor's 97 percent is measured against found-and-fresh-at-ingest. Your 50 percent is measured against everything you sent, right now. Different denominators, both honest.

The verify-before-trust build

The fix is not a better vendor. It is a stage the vendor cannot sell you, because it grades their homework. Build it bottom to top, and note that every rung exists to move you off the deck number and onto the curve. Read the ladder, then I will show the code and the worked example under it.

Build it bottom to topThe verify-before-trust stack
  1. L5Refuse to fill what you cannot verifyleave empty

    When a chunk of records cannot be recovered at an accuracy you would stand behind (the unrecoverable 135K on that name job), leave them empty and say so. An empty field is honest; a guessed field routes a deal into the wrong queue and never tells you.

  2. L4Re-verify on a schedule, not once~30% / yr

    Validity decays about 30 percent a year (ZoomInfo), so a January verify is a January fact. Re-run the SMTP pass on the addresses you still send to, on a cadence, or the curve rots your list while the dashboard stays green.

  3. L3Break out catch-all per segment20-30%

    Catch-all runs under 10 percent overall but 20 to 30 percent at large enterprises. Report valid-of-found per segment or your enterprise deliverability hides behind a green SMB average.

  4. L2Classify into four buckets, not two4 buckets

    Valid, invalid, catch-all, and unverified. The two-way valid-or-invalid split is what inflates the number. Only one of the four buckets earns a send, and catch-all gets its own row so it cannot hide inside "valid."

  5. L1Own the SMTP check, not the provider scoreyou measure

    Run an SMTP validation you control against every address the waterfall produced, regardless of which provider found it. The provider grading its own homework is how you got here. This is the only accuracy number you should trust, because you measured it.

So the last stage of any waterfall is always independent verification. Take every email the chain produced and run it through an SMTP validation you control, not the provider’s own confidence score. What survives that pass is what you route and send on. What does not survive gets marked unverified and stays out of the send list. If you have not built the chain that feeds this stage yet, start with the enrichment waterfall and treat this as the rung that goes on the end.

# The verify stage: never trust the provider's own confidence flag.
# Classify into four buckets, not two. Only "valid" earns a send.
def classify(email, smtp_result, mx_is_catch_all):
    if smtp_result == "hard_bounce" or "@" not in email:
        return "invalid"           # drop from send list
    if mx_is_catch_all:
        return "catch_all"         # its OWN bucket, do not count as valid
    if smtp_result == "accepted":
        return "valid"             # the only bucket you send on
    return "unverified"            # provider said yes, SMTP could not confirm

The mistake almost everyone makes is the two-way split. The catch-all bucket is the one that lies, and it needs its own row. So does the unverified bucket: an address the provider returned that your SMTP check can neither confirm nor reject is not the same as a confirmed-good address, and folding it into “valid” is how the two-bucket world inflates its own numbers. Four buckets, and only one earns a send.

Run the verification on a schedule, not once. An email you confirmed valid in January is a data point about January. On the books I have watched, job changes chew through a couple of percent of a contact list every month, which is the monthly slope of the 30 percent annual curve above, so a list you verified six months ago has quietly rotted into the low double digits while you treated it as clean. The provider will not tell you, because to their accuracy math it was correct at ingest. The only way you know is to re-run your own SMTP pass against the addresses you still send to, and the only way that is affordable is that you built the verify stage as a repeatable step rather than a one-time cleanup.

Catch-all inflation is the hidden tax

Here is the mechanism most people miss. A catch-all domain accepts mail to every address, valid or not, so it never bounces at the SMTP check. On the lists I have audited, catch-all runs under 10 percent of domains overall and climbs to somewhere between a fifth and a third at large enterprises, because their mail security is configured to swallow everything.

That means your verification passes an address that will never reach a human. The vendor counts it valid. Your SMTP test counts it valid. Your rep sends to it and hears nothing, forever, and it looks like a cold prospect instead of a dead address. Flag catch-all as its own category or your enterprise segment’s real deliverability is 20 to 30 points worse than the dashboard claims.

1,000 vendor-supplied emails through an honest verify
The vendor reports 970 valid. After SMTP and catch-all separation, 510 are actually sendable. The 250 catch-all and 210 stale rows are where the 97 percent claim leaks.
View as table
ItemValue
Vendor "valid"970
Passed SMTP760
Not catch-all510
Truly sendable510

A worked example that reconciles to the curve

Take 1,000 vendor emails from a mixed list where the average record is about 12 months old, so the decay curve puts fresh validity near 64 percent before you even test. Run them down the verify stack and the four buckets fall out like this.

BucketCountShareEarns a send?
Valid, not catch-all51051%Yes
Catch-all25025%No, its own row
Stale / hard bounce21021%No, invalid
Unverified303%No, held back
Vendor reported “valid”97097%The deck number

The vendor’s 97 percent is the bottom row: 970 of 1,000 returned an answer that matched at ingest. Your real sendable set is the top row: 510, or 51 percent, which is the roughly-half valid-of-found in the first stat tile. The 250 catch-alls are the hidden tax the SMTP check alone would have passed as valid, and the 210 stale rows are the decay curve cashing in, close to the 30-percent-a-year figure once you account for a list that averages a year old. The gap between 970 and 510 is not a rounding error. It is 460 emails that will never reach a human, sitting in a send list that looks full.

The cost lands in routing, not just bounces

Bad emails bounce and you notice. Bad firmographics route silently and you do not.

Employee-count bands are the worst offender. You route a company into the “mid-market, assign an AE” band because the vendor said 340 employees. The real number is 55. That deal now sits with an AE carrying an enterprise quota who will never prioritize a 55-person account, while the SMB team that would have worked it fast never sees it. No bounce, no error, no alert. A deal dies in the wrong queue because you trusted an employee count nobody verified. This is the same failure that routing is latency describes from the other end: the routing rule fired instantly and correctly on data that was wrong.

FieldVendor saidTruthSilent cost
Emailvalidcatch-allRep sends, hears nothing, marks “cold”
Employee count34055Enterprise AE deprioritizes; SMB never sees it
Industry”Software”Staffing agencyWrong sequence, wrong messaging, no reply
Seniority”VP”left 8 months agoBounce, or worse, reaches their replacement cold

Multiply that across a routing rule that fires on every inbound lead and the vendor’s error rate becomes a structural leak in your funnel, and it never shows up as an error in any log. Firmographic errors cost more than email errors because they fail silently and compound. A bounced email tells you it bounced; the feedback loop is same-day and loud. A miscategorized employee count produces a deal that sits in the wrong queue, gets the wrong sequence, and dies of neglect over weeks, and the post-mortem blames the rep or the segment, never the field. Because nothing errored, nobody traces it back to the enrichment, so the same wrong band keeps routing the same kind of deal into the same dead queue quarter after quarter.

What the deck claims What the 100-row audit finds
Email accuracy 97% accurate ~50% valid-of-found, 25% catch-all
Coverage vs accuracy Reported as one number Two axes, both measured
Freshness Silent, assumed current ~30% a year gone (ZoomInfo)
Firmographic routing Assumed correct Hand-checked band by band
Who graded it The vendor You, on your data, today
You do not need a project to build the right column. You need an afternoon and an SMTP checker you control.

Run a 100-row spot audit this week

The 100-row audit anyone can run
  1. 1

    Pull 100 records your vendor recently enriched

    Random sample across your real segments, not the cleanest 100. Weight it toward the segment you route the most deals through.

  2. 2

    Run the emails through an SMTP validation you control

    Not the provider score. Mark hard-bounce as invalid. Flag catch-all as its own bucket, never as valid.

  3. 3

    Hand-check firmographics against the source

    Employee count and industry against the company site or LinkedIn, on the same 100. Ask whether the band would route where a human would pick.

  4. 4

    Count three numbers

    Valid-and-not-catch-all emails, employee bands that route correctly, and records the vendor filled versus got right. These are your real accuracy figures.

  5. 5

    Bring both numbers to the renewal

    Put your valid-of-found next to their 97 percent on the deck. The gap is the leverage, and it is the only accuracy figure you should trust, because you measured it.

One more thing the audit buys you: a defensible refusal to fill, which is L5 of the stack. When a chunk of your records cannot be recovered at an accuracy you would stand behind (the unrecoverable 135K on that name job), the disciplined move is to leave them empty and say so, not to let a vendor guess and call it coverage. An empty field is honest; a wrong field routes a deal into the wrong queue and never tells you. The vendor is incentivized to fill, because coverage is what the deck sells. You are incentivized to be right.

You can also model what an honest waterfall costs per verified record before you sign anything. Move the hit rates to what your own audit found, not the deck, and watch the blended cost move:

Blended cost per verified record

per verified record

Try

Order matters. Put the cheap high-hit provider first and blended cost drops, because the expensive one only ever touches the records nobody else could find.

per verified record: $0.024

The 97 percent on the renewal deck is not a lie. It is an answer to a question you do not care about, measured at a point on the curve you never send from. The question you care about is how many of these emails reach a human this week, and the only person who can answer it is you, with an SMTP test and an afternoon. Run the 100 rows before the renewal call, not after.

enrichment data-quality verification

Keep reading

One email. Every week.

One email a week: a system I built or broke, with the config, the numbers, and what I would change. No roundups, no theory, unsubscribe whenever it stops being useful.

The newsletter opens soon.

Connect a provider in src/config.ts