Enrichment waterfalls

Chain providers so a miss from one becomes a hit from the next, order by marginal recovery instead of hit rate, and pay mostly on verified data. The build, the queries, the credit math.

GTM Engineering guide

The first waterfall I built ran ZoomInfo before anything else, because ZoomInfo was the provider I trusted. It also charged me on the miss. So I was paying the most expensive per-lookup rate in the chain to clear the easy records a 1-credit provider would have caught for a fraction of the cost. The order was backwards. It cost me for a month before I looked at the bill line by line and saw the shape of the mistake: premium credits burned on contacts that were never hard to find.

A single provider tops out well short of your list. ZoomInfo finds work email on roughly 65% of US contacts and 35% globally. Apollo returns something on more of them, but only about half of what it returns is valid. A waterfall chains providers so a miss falls through to the next one, and you stop the moment a valid answer comes back. An independent four-tool test hit 67.6% coverage at 62% valid, a 23-point lift in valid emails over the best single provider. That is the honest ceiling. Anyone quoting 92% is counting catch-all addresses that will bounce.

67.6%
Coverage from a 4-tool waterfall, 62% valid (independent test)
~4x
Cost swing between a good provider order and a bad one
~22%/yr
B2B email decay, so last quarter's hit can be dead now

A waterfall is not a data source. It is a routing system that decides, per record, which provider to ask, in what order, and when to quit. The routing is the whole product. Get it right and you clear coverage at a blended cost below your cheapest premium provider’s list price. Get it wrong and you pay premium rates to find contacts that were never hard.

The mechanism A record falls until one provider returns a verified value
10,000 records inProvider A$0.01 / trymissProvider B$0.03 / trymissProvider C$0.08 / tryhithithitVerify (catch-all decision)Write + tag source, cost, timestamp
Each provider only runs on the records the provider above it missed. You pay per attempt, so the order decides the bill.
Normalize input
Provider A
Provider B
Provider C
Verify
Write + tag source
Same chain in linear form. A record moves right until one provider returns a value that passes verification.

Order by marginal recovery, not by hit rate

Two decisions set your cost: which provider goes first, and whether adjacent providers overlap. Put the cheapest high-hit provider first so it clears the easy records before anyone expensive touches them. Then order the rest by what they recover incrementally, not by their standalone hit rate. A provider that finds 60% of a cold list is worthless in slot three if slots one and two already found those same records. Two resellers of the same underlying database recover almost nothing from each other, and you will pay twice to learn it.

Ordering by database size instead of accuracy is the expensive mistake. The cost swing between a good order and a bad one on the same list runs about 4x, because you either clear volume cheaply first or you pay premium rates on records a cheap provider would have caught. The published find rates that most teams order on are the wrong axis entirely. Here is what a single provider delivers, and why no single row is enough on its own:

ProviderEmail find rateValid of what it returnsConf
ZoomInfo (US work email)65%highV
ZoomInfo (global)35%highV
Cognism (email find)68%91% EMEA / 74% USV
Apollo (returns something)high91% of found, ~50% overallV
Huntermoderate79% of found, ~45% overallV

Source: published find rates, independent verification (2025-2026). “Valid overall” is the number that matters. Apollo returning a value on most records means little when half of what it returns bounces.

Now watch coverage climb as you add depth. The lift is real but it flattens hard, which is the argument against a fifth and sixth provider:

Coverage by waterfall depth
Depth 3 gets you ~78%. Depth 6 gets ~87%. Slots five and six add cost, not records. Cap at 3-4 providers.
View as table
StageValue
1 provider45%
3 providers78%
4 providers84%
5 providers86%
6 providers87%

Feed your own numbers into the blended-cost math and watch the per-verified-record figure move. This is the calculation that tells you whether a provider is earning its slot:

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

For a US-heavy B2B list, the order that holds up in practice runs the low-cost, high-accuracy specialists first, then the broad databases, then the deep-but-pricey fallback. Findymail, LeadMagic, and Prospeo tend to clear the bulk cheaply and clean. Apollo and Hunter fill the middle. Dropcontact or a premium source catches the stragglers. The mobile chain is separate and it is expensive: a mobile lookup runs about 8x the cost of an email at roughly half the hit rate, so it never runs on an unqualified record.

FieldSlot 1Slot 2Slot 3Gate
Work emailFindymail / LeadMagic / ProspeoApollo / HunterDropcontactVerify every winner
Mobile phoneCognism DiamondZoomInfo(stop)Only after ICP qualifies
Company firmographicsClay / free sourceApolloZoomInfoRuns first, gates everything

Company firmographics run first on purpose. That is the filter step, and it is where most of the savings live.

Filter to ICP before you enrich, not after

The credit you never spend is the cheapest. Run a company-level waterfall first and drop everything outside ICP before a single contact-level lookup fires. On most raw lists that kills 40 to 60% of rows, and those are rows you would otherwise have paid to enrich and then discarded. In Clay this is the conditional-run toggle: the email column fires only when the prior column came back empty and the company passed your filter. Set a per-row credit cap around 5 or 6 so a stubborn record cannot walk the entire chain and drain credits chasing a contact that does not exist.

The consolidation pattern is one column that reads the first non-empty value across the chain, written as {A}||{B}||{C}. That single formula is what makes “stop on first hit” real; without it you enrich every provider on every row and the waterfall is a waterfall in name only.

# Clay column config, sketched
email_final = {findymail_email} || {leadmagic_email} || {apollo_email}
run_if      = company_in_icp = true AND email_final is empty
per_row_cap = 6 credits
verify      = millionverifier(email_final), catch_all = "conservative"
Build order: standing up the waterfall
  1. 1

    1. Normalize the key

    Lowercase the email domain, strip LinkedIn URL params, standardize the company name. Match on domain plus LinkedIn URL, not company name; that lifts match rates 15 to 25%.

  2. 2

    2. Qualify the company first

    Run the firmographic waterfall and drop out-of-ICP rows before any contact lookup. This kills 40 to 60% of the list and is the single biggest credit saver.

  3. 3

    3. Call provider 1

    On the survivors, call the cheapest high-accuracy provider. If it returns a value that passes your validity check, write it, tag the source, stop.

  4. 4

    4. Fall through on a miss

    Pass the same key to provider 2, then 3, until a valid result returns or the per-row credit cap trips.

  5. 5

    5. Verify the winning hit

    Run a verification pass on the email. Catch-all is a separate decision, not an automatic pass. Conservative excludes catch-all, Balanced includes it.

  6. 6

    6. Write with provenance

    Store the value plus which provider supplied it, a confidence score, a timestamp, and the cost. You cannot debug or renegotiate without this.

  7. 7

    7. Handle exhaustion and cache

    Route no-hit records to a Claygent scrape or a manual queue, or mark them no_hit. Cache the miss so next quarter does not pay to fail on the same record again.

Clay or roll your own

Clay Custom (n8n / code)
Setup Providers as ordered columns, conditional-run toggle, BYOK to cut cost 50 to 80% You build ordering, retries, caching against provider APIs yourself
Control Credit accounting handled; limited retry tuning Full control over ordering, caching, dedup, backoff
Best when The list is the unit of work and you iterate weekly Always-on pipeline feeding a warehouse at high volume
Cost shape Credits per hit, from $0.05; full record 6 to 20cr Raw API pricing, cheaper at scale, more to maintain
Failure mode Credit surprises if caps and conditional-run are off You own idempotency and rate limits; a bad retry loop bills twice
Pick by whether the list or the pipeline is the unit of work.

Clay wins when the list is the thing you touch every week and you want one bill instead of five contracts. Custom wins when enrichment is a standing pipe feeding the warehouse and volume makes raw API pricing worth the maintenance. Cargo runs a single-credit waterfall alternative if you want the orchestration handled but not the per-provider accounting. If you go custom, treat idempotency and retries as one pattern, the same discipline covered in API integration: a retry without an idempotency key bills you twice for the same lookup.

The mistakes that cost real money

Most waterfall failures are not exotic. They are the same five, and each one has a fix you can ship this week.

The freshness point is the one that quietly wrecks a program. At ~22% annual decay, a list you enriched twelve months ago is roughly a fifth wrong today, and every one of those bounces charges against the sender reputation you are trying to protect. Bad data at scale is not a rounding error; Gartner puts the cost of poor data quality near $15M a year for the average organization. A waterfall does not fix decay. Caching with a TTL does, because it forces a re-run instead of trusting a stale hit.

What to do next

Before you add a fifth provider, go re-order the three you have and read the marginal column on each. Pull the sample, run the 25-row test, and look at what slot three recovered that slots one and two did not. If it is a rounding error, that provider is a logo, not a slot, and it is costing you on every run. The waterfall you already own has more savings in its ordering than a new contract will ever add. For the deeper argument on picking the providers themselves, the companion piece is the enrichment waterfall and when your enrichment vendor is the wrong one. Then wire the verified output into a motion that earns it: enriched contacts feed signal-based outbound, where timing turns a clean address into a reply.