Waterfall Enrichment for Email Finding: Maximize Coverage with Multi-Provider Strategies

How to chain multiple email finding providers in a waterfall to maximize coverage from 60% to 85%+. Includes step-by-step Clay setup, provider ordering strategies, and real results.

The Single-Provider Problem

Here is a frustrating reality of B2B email finding: no single provider can find emails for more than ~85% of your prospect list. In our 2026 benchmark, the highest coverage from any single tool was 88.2% (Apollo), and the highest accuracy tool (Findymail) covered 78.4%.

That means for every 100 prospects you search, 12-22 come back empty. If your prospect list has 5,000 people, that is 600-1,100 contacts you cannot reach.

Each email provider has different data sources, different crawling patterns, and different databases. Provider A might have the email for a VP at Stripe that Provider B missed, while Provider B has the email for a director at Notion that Provider A does not have. Their coverage is partially overlapping but never identical.

Waterfall enrichment solves this by chaining providers together: try Provider A first, then pass any “not found” results to Provider B, then to Provider C, and so on. Each subsequent provider fills in gaps the previous ones missed.

How Waterfall Enrichment Works

The concept is straightforward:

Input: 1,000 prospects (name + company)
        |
        v
  [Provider 1: Findymail]
   Found: 784 emails (78.4%)
   Not found: 216
        |
        v
  [Provider 2: Apollo]
   From 216 remaining:
   Found: 128 additional emails
   Not found: 88
        |
        v
  [Provider 3: Hunter]
   From 88 remaining:
   Found: 42 additional emails
   Not found: 46
        |
        v
  Final result: 954 emails found (95.4% coverage)

The numbers above are illustrative, but the pattern is real. In practice, we consistently see waterfall approaches increase coverage by 15-25 percentage points compared to a single provider.

Why Provider Order Matters

Waterfall enrichment is not just about which providers you use — the order matters significantly because of two competing goals:

  1. Accuracy: You want to use the most accurate provider first, because its results will be trusted without a second opinion.
  2. Cost: You want to use the cheapest provider first to minimize spend, since subsequent providers only process the remaining (smaller) set.

These goals often conflict. The most accurate provider is rarely the cheapest. Here is how to think about ordering:

Accuracy-first ordering (recommended for cold outreach):

PositionProviderRationale
1stFindymailHighest accuracy (93.2%), built-in verification
2ndHunterStrong accuracy (84.7%), transparent confidence scores
3rdApolloBroadest coverage (88.2%), catches remaining gaps

Cost-first ordering (for budget-sensitive operations):

PositionProviderRationale
1stApolloCheapest per-email, generous free tier
2ndSnov.ioLow cost, decent coverage
3rdFindymailHigh accuracy for remaining hard-to-find contacts

The accuracy-first approach is almost always better. Here is why: the emails you find in position 1 make up the bulk of your results (typically 70-80%). If your first-position provider has 93% accuracy versus 81%, that 12-point difference applies to the majority of your results. Saving a few cents per email in position 1 but getting worse data is a false economy.

Building a Waterfall in Clay (Step by Step)

Clay is the most popular platform for building enrichment waterfalls because it provides no-code integrations with dozens of data providers. Here is how to set one up.

Step 1: Import Your Prospect List

Upload a CSV or connect Clay to your CRM. Your input data needs at minimum:

  • Full name (or first name + last name in separate columns)
  • Company name or company domain
  • LinkedIn URL (optional, but improves accuracy for some providers)

If you only have company names without domains, add a “Find Company Domain” enrichment step first. Clay has built-in domain resolution.

Step 2: Add Your First Email Provider

Click “Add Enrichment” and select your first-position provider (we recommend Findymail for accuracy-first waterfalls).

Configure the enrichment:

  • Input mapping: Map your name and company columns to the provider’s required fields
  • Output column: Name it something clear like email_provider_1
  • Run condition: Run for all rows (this is the first provider, no filtering needed)

Run the enrichment. Wait for results.

Step 3: Add Your Second Provider with Conditional Logic

Add a second enrichment step for your second provider (e.g., Hunter).

Critical configuration: Set the run condition to only process rows where the first provider returned no result:

Run when: {email_provider_1} is empty

This is the “waterfall” logic. Provider 2 only runs on contacts that Provider 1 missed. This saves credits and avoids paying twice for the same contact.

Map the inputs the same way as Step 2. Name the output column email_provider_2.

Step 4: Add Your Third Provider

Same process as Step 3, but the run condition checks both previous columns:

Run when: {email_provider_1} is empty AND {email_provider_2} is empty

Name the output email_provider_3.

Step 5: Create a Unified Email Column

Add a formula column that consolidates all three provider columns into a single email field:

Formula: COALESCE({email_provider_1}, {email_provider_2}, {email_provider_3})

Or in Clay’s formula syntax:

IF({email_provider_1} != "", {email_provider_1},
  IF({email_provider_2} != "", {email_provider_2},
    {email_provider_3}))

This gives you one clean email column with the best available result for each contact.

Step 6: Add Verification (If Needed)

If your first-position provider (e.g., Findymail) includes built-in verification, those results are already verified. But emails from Provider 2 and 3 should be verified separately.

Add a verification enrichment step with this run condition:

Run when: {email_provider_1} is empty AND {final_email} is not empty

This only verifies emails that came from providers without built-in verification. Use ZeroBounce, NeverBounce, or another verification service (see our email verification guide for a comparison).

Step 7: Export Clean Results

Filter your table to only rows where:

  • final_email is not empty, AND
  • verification_status is “valid” (or the email came from a provider with built-in verification)

Export this filtered set to your CRM or outreach tool.

Building a Waterfall with Code

If you prefer programmatic control or need to process at high volume, here is a Python implementation:

import time
from dataclasses import dataclass
from typing import Optional

@dataclass
class EmailResult:
    email: Optional[str]
    provider: str
    confidence: float
    verified: bool

class WaterfallEnricher:
    def __init__(self, providers):
        """
        providers: List of dicts with keys:
          - name: str
          - find_fn: callable(first_name, last_name, domain) -> dict
          - has_verification: bool
          - cost_per_lookup: float
        """
        self.providers = providers
        self.stats = {p["name"]: {"attempted": 0, "found": 0} for p in providers}

    def find_email(self, first_name, last_name, domain):
        """Try each provider in order until one returns a result."""
        for provider in self.providers:
            self.stats[provider["name"]]["attempted"] += 1

            result = provider["find_fn"](first_name, last_name, domain)

            if result and result.get("email"):
                self.stats[provider["name"]]["found"] += 1
                return EmailResult(
                    email=result["email"],
                    provider=provider["name"],
                    confidence=result.get("confidence", 0),
                    verified=provider["has_verification"],
                )

            time.sleep(0.2)  # Brief pause between providers

        return EmailResult(email=None, provider="none", confidence=0, verified=False)

    def print_stats(self):
        """Print coverage statistics for each provider in the waterfall."""
        total_attempted = self.stats[self.providers[0]["name"]]["attempted"]
        total_found = sum(s["found"] for s in self.stats.values())

        print(f"\n{'Provider':<20} {'Attempted':<12} {'Found':<10} {'Contribution'}")
        print("-" * 60)
        for provider in self.providers:
            name = provider["name"]
            stats = self.stats[name]
            contribution = stats["found"] / total_attempted * 100 if total_attempted else 0
            print(f"{name:<20} {stats['attempted']:<12} {stats['found']:<10} {contribution:.1f}%")
        print("-" * 60)
        print(f"{'TOTAL':<20} {total_attempted:<12} {total_found:<10} {total_found/total_attempted*100:.1f}%")


# Example usage with placeholder provider functions
enricher = WaterfallEnricher([
    {
        "name": "Findymail",
        "find_fn": findymail_lookup,   # Your API wrapper
        "has_verification": True,
        "cost_per_lookup": 0.05,
    },
    {
        "name": "Hunter",
        "find_fn": hunter_lookup,       # Your API wrapper
        "has_verification": False,
        "cost_per_lookup": 0.045,
    },
    {
        "name": "Apollo",
        "find_fn": apollo_lookup,       # Your API wrapper
        "has_verification": False,
        "cost_per_lookup": 0.03,
    },
])

# Process contacts
for contact in contacts:
    result = enricher.find_email(
        contact["first_name"],
        contact["last_name"],
        contact["domain"],
    )
    if result.email:
        print(f"Found: {result.email} (via {result.provider})")

enricher.print_stats()

Real Results: What Waterfall Enrichment Actually Achieves

We ran our 500-contact benchmark dataset through three different waterfall configurations. Here are the actual results:

Configuration A: Findymail -> Hunter -> Apollo

MetricProvider 1 (Findymail)+ Provider 2 (Hunter)+ Provider 3 (Apollo)
Cumulative coverage78.4%87.6%93.8%
New emails added3924631
Cumulative accuracy93.2%91.8%90.1%
Total cost$19.60$21.67$22.60

Configuration B: Apollo -> Snov.io -> Findymail

MetricProvider 1 (Apollo)+ Provider 2 (Snov.io)+ Provider 3 (Findymail)
Cumulative coverage88.2%91.4%94.2%
New emails added4411614
Cumulative accuracy81.3%80.7%82.1%
Total cost$13.23$13.71$14.41

Configuration C: Findymail -> Apollo -> RocketReach

MetricProvider 1 (Findymail)+ Provider 2 (Apollo)+ Provider 3 (RocketReach)
Cumulative coverage78.4%91.0%94.6%
New emails added3926318
Cumulative accuracy93.2%90.4%89.7%
Total cost$19.60$21.49$23.11

Key takeaways from the results:

  1. All configurations reached 93-95% coverage, dramatically outperforming any single provider.
  2. Configuration A (Findymail -> Hunter -> Apollo) had the best accuracy at 90.1%, because the first provider (which contributed most emails) had the highest accuracy.
  3. Configuration B was cheapest ($14.41 total) but had the lowest accuracy at 82.1%, because Apollo (first position) has lower accuracy and its emails made up the bulk of results.
  4. The third provider added diminishing returns in every configuration — typically only 14-31 additional emails. Two providers capture most of the incremental value.
  5. Cost per additional email increases sharply after the first provider. Provider 1 cost ~$0.05 per email. Provider 3 cost ~$0.05 per email but only for 14-31 emails, meaning the marginal cost is low in absolute terms even if the per-unit is higher.

Provider Ordering Strategy Matrix

Use this decision matrix to choose your waterfall configuration:

PriorityPosition 1Position 2Position 3Expected CoverageExpected Accuracy
Accuracy firstFindymailHunterApollo~94%~90%
Coverage firstApolloFindymailRocketReach~95%~85%
Budget firstApollo (free tier)Snov.ioHunter~93%~82%
Enterprise focusLushaFindymailApollo~92%~89%
EU/GDPR focusFindymailKasprHunter~90%~88%

For details on individual providers, see our guides on Hunter.io and Apollo.io.

Cost Optimization Tips

1. Always Filter Before Enriching

Before running contacts through your waterfall, filter out:

  • Contacts you already have emails for in your CRM
  • Contacts at companies outside your ICP
  • Duplicate entries
  • Contacts without enough identifying information (no company, no last name)

Every lookup costs money. Do not pay to enrich contacts you will never email.

2. Use Free Tiers Strategically

Apollo offers 10,000 free credits per month. If your monthly volume is under 10,000, you can use Apollo as your first-pass provider at zero cost, then use a paid provider for the remaining “not found” results. This alone can cut your enrichment costs by 60-70%.

3. Cache Results

Email addresses do not change frequently. Cache your lookup results and skip re-enrichment for contacts you have already found within the last 90 days.

import json
import os
from datetime import datetime, timedelta

CACHE_FILE = "email_cache.json"
CACHE_TTL_DAYS = 90

def load_cache():
    if os.path.exists(CACHE_FILE):
        with open(CACHE_FILE) as f:
            return json.load(f)
    return {}

def save_cache(cache):
    with open(CACHE_FILE, "w") as f:
        json.dump(cache, f)

def get_cached_email(name, domain):
    cache = load_cache()
    key = f"{name.lower()}|{domain.lower()}"
    if key in cache:
        entry = cache[key]
        cached_date = datetime.fromisoformat(entry["date"])
        if datetime.now() - cached_date < timedelta(days=CACHE_TTL_DAYS):
            return entry["email"]
    return None

def cache_email(name, domain, email):
    cache = load_cache()
    key = f"{name.lower()}|{domain.lower()}"
    cache[key] = {"email": email, "date": datetime.now().isoformat()}
    save_cache(cache)

4. Set Confidence Thresholds Between Providers

Instead of a binary “found or not found” waterfall, use confidence scores:

If Provider 1 returns an email with confidence >= 90%: accept it
If Provider 1 returns an email with confidence 70-89%: accept but flag for verification
If Provider 1 returns an email with confidence < 70%: pass to Provider 2
If Provider 1 returns nothing: pass to Provider 2

This prevents accepting low-confidence guesses from your first provider when a second provider might have better data.

5. Monitor Provider Performance Over Time

Provider accuracy is not static. Databases get refreshed, algorithms change, companies update their data sources. Track your per-provider metrics monthly:

MonthProviderEmails FoundBouncedAccuracy
Jan 2026Findymail2,3402898.8%
Jan 2026Hunter4563193.2%
Jan 2026Apollo3124286.5%
Feb 2026Findymail2,5123298.7%

If a provider’s accuracy drops significantly, consider reordering your waterfall or replacing them.

When Waterfall Enrichment Is Not Worth It

Waterfall enrichment adds complexity and cost. It is not always justified:

  • Low volume (under 200 contacts/month): A single good provider is simpler and sufficient. The incremental coverage from a waterfall does not justify the setup overhead.
  • Non-critical outreach: If you are sending a newsletter or marketing emails to opted-in contacts, a single provider with verification is fine.
  • Tight budget with no room for multiple subscriptions: Two provider subscriptions cost more than one. If budget is hard-capped, invest in one high-accuracy provider instead.
  • One-time enrichment: If you need to enrich a list once and never again, manually running “not found” contacts through a second tool is easier than setting up a waterfall pipeline.

Bottom Line

Waterfall enrichment is the most effective way to maximize your email finding coverage without sacrificing accuracy. By chaining providers in the right order — accuracy-first for outreach, cost-first for budget operations — you can consistently reach 90-95% coverage where a single provider would top out at 78-88%.

The setup takes 30-60 minutes in Clay, or a few hours if you are building a custom pipeline. The ongoing cost per additional email is modest. And the coverage improvement is dramatic.

Start with two providers. Add a third only if the incremental coverage justifies the cost and complexity. Verify everything that is not already verified. And track your per-provider metrics so you can optimize over time.

For provider-specific setup details, see our guides on Hunter.io and Apollo.io. For verification best practices, see our email verification guide.