06 Research

44% of enriched contacts were wrong

Not slightly stale. Attached to an entirely different employer. Measured across 254 contacts at 100 companies, and the causes are more interesting than the number.

Across a run of 254 enriched contacts at 100 companies, roughly 44% came back attached to the wrong employer and had to be discarded. The enrichment tooling was not malfunctioning. It resolved exactly what it was given, and the failures came from handing it identifiers that did not uniquely identify the target company.

The setup

I was turning a list of companies that advertise on Meta into named humans with contact details. The pipeline: take the advertiser, resolve a company domain, then ask an enrichment service for the decision-makers at that domain.

The first problem is upstream and worth naming, because it shapes everything after. Most ad-library leads have no website in the ad. And essentially no people-enrichment tool will accept a company without a domain. So before you can enrich anything, you have to find a domain.

Resolving the advertiser’s public page profile got a usable domain for 196 of 210 leads. That step also returns things the ad itself does not: an email, a phone number, a category, and the social links. Good enough to proceed.

Then the enrichment ran, returned around 450 contacts, and about 200 of them were wrong.

Failure mode one: platform collision

This is the big one, and it is entirely predictable in hindsight.

Small businesses very often do not have a conventional website. Their “website” field points at a link-in-bio service, a social profile, a form builder, a community platform, or a video channel. When you hand that URL to an enrichment tool, it does its job perfectly: it resolves the domain you gave it.

The domain you gave it belongs to a technology company. So you get that company’s employees.

What the lead listedWhat came back
A TikTok profile20 TikTok recruiters
A Typeform link20 Typeform employees
A Linktree page20 Linktree staff

Sixty contacts, all perfectly accurate, all completely useless. Worse than useless: they look like real enriched data, they have real names and real titles, and if they reach a CRM unchecked somebody will eventually email them.

The fix is to strip platform domains before enriching, not to clean up afterwards. If the only URL you have for a lead is a link-in-bio, you do not have a domain, and you should treat that lead as unresolved rather than pretending otherwise.

Failure mode two: brand collision

Rarer, harder to catch, and more embarrassing.

A small local insurance agency happened to sit on a domain that a very large national organisation of the same name also uses. The enrichment returned the national body’s senior executives. Real people, real titles, entirely the wrong company, and no automated signal that anything had gone wrong.

There is no clean programmatic fix. The practical mitigation is a sanity check on scale: if you asked for decision-makers at a five-person agency and got back a Fortune 500 C-suite, something is wrong. Company size is the cheapest tripwire available.

The check that catches most of it

One rule, applied in code before anything reaches a CRM:

Keep a contact only if its own domain equals the company domain, or its most recent employer matches the company name.

That is it. It is not sophisticated and it removed almost all of the bad records. The reason it works is that the failure is always the same shape: the contact is real, but the link between the contact and your company is fabricated by inference.

Do this in the pipeline, not in a spreadsheet afterwards. Manual review does not survive contact with 450 rows, and the records that slip through are indistinguishable from good ones.

The blocklist bug

Worth its own section because it is the kind of mistake that deletes real customers silently.

Building a platform blocklist, the obvious implementation is to check whether a banned domain appears anywhere in the lead’s URL. That is wrong, and the failure is invisible.

Checking whether x.com appears inside alwaysthereairtx.com returns true. It appears at the end of “airtx.com”. So a legitimate company is silently dropped from the pipeline and nobody notices, because the whole point of a blocklist is that things disappear.

Match on the exact domain, or on a proper suffix boundary with the dot included. Never on substring. This class of bug applies to every blocklist you will ever write, not just this one.

Other things that cost me time

  • Filters can return nothing rather than something. Asking for senior titles at small companies frequently returns an empty set, because a five-person business has no VP of anything. The recovery is to retry the same domain with no title filters at all, rather than concluding there are no contacts.
  • Verify social handles against a stable identifier. A company search will return a plausible social account that belongs to a different business with a similar name. Match on the underlying page identifier you already hold, not on the name. That check rejected a genuine mismatch in this run.
  • Do not request extra data points you do not need. Email lookups in particular cost credits per record, and requesting them by default on a 450-row run is expensive for data you may discard.
  • Enrichment calls are slow. Around ten seconds each. Two hundred sequential calls is impractical; parallelise or plan for it.

What I would tell anyone buying enriched data

  1. Assume a double-digit error rate and design for it. The number here was 44%.
  2. The errors are confident. Bad records look exactly like good ones: real names, real titles, real companies. There is no low-confidence flag to filter on.
  3. Validate the link, not the person. The person is usually real. It is the connection to your target company that is invented.
  4. Fix it upstream. Every hour spent improving the domain you feed in is worth several spent cleaning up what comes out.
  5. Never let unvalidated enrichment reach a sending tool. The cost of emailing 200 wrong people is not zero — it is your sending reputation.

None of this means enrichment is not worth doing. Fifty-six percent of 450 contacts is still a good day’s work for an afternoon of pipeline. It means the output is a draft, not an answer.

FAQ

How accurate is AI-powered B2B contact enrichment?

In this run, roughly 44% of returned contacts were the wrong employer. The tooling resolves whatever identifier you give it; the errors come from ambiguous identifiers.

What is platform collision?

When a company’s listed website is a link-in-bio or social URL, the tool resolves that platform and returns the platform’s own staff. A lead whose site is a Linktree comes back with Linktree employees.

How do I validate enriched contacts?

Keep a contact only if its domain matches the company domain or its latest employer matches the company name. Do it in code, before a CRM.

Why not blocklist by substring?

Because “x.com” matches inside “alwaysthereairtx.com” and you silently delete a real company. Match exact domains or proper suffix boundaries.

Related: the false-zero machine, another way this pipeline hands you a confident wrong answer, and the ad study these companies came from.