---
# === IDENTITY ===
id: business/lead-generation/lead-enrichment-pipeline/2026
canonical_question: "How do I enrich leads — email (Hunter.io), phone (Lusha), firmographic (Clearbit), tech stack (BuiltWith) waterfall logic?"
aliases:
  - "Lead enrichment waterfall pipeline with Hunter Lusha Clearbit BuiltWith"
  - "How to build a multi-provider data enrichment workflow for B2B leads"
  - "Waterfall enrichment logic for email phone and firmographic data"
entity_type: execution_recipe
domain: business > lead-generation > lead enrichment pipeline
region: global
jurisdiction: global
temporal_scope: 2024-2026

# === VERIFICATION ===
last_verified: 2026-03-11
confidence: 0.90
version: 1.0
first_published: 2026-03-11

# === TEMPORAL VALIDITY ===
temporal_validity:
  status: volatile
  last_breaking_change: null
  next_review: 2026-09-07
  change_sensitivity: high

# === CONSTRAINTS ===
constraints:
  - "Hunter.io free tier: 25 searches/month and 50 verifications/month"
  - "Lusha free tier: 5 credits/month (1 credit = 1 phone or email reveal)"
  - "Clearbit requires business email for signup — minimum $99/month for enrichment API"
  - "BuiltWith free tier: limited to 1 lookup at a time, no API access"
  - "Waterfall order matters: cheapest/most-accurate provider first, then fallback to expensive ones"
  - "GDPR: enriching EU resident data requires documented legitimate interest basis"

# === SKIP CONDITIONS ===
skip_this_unit_if:
  - condition: "Already have complete lead data from Apollo or ZoomInfo"
    use_instead: "business/lead-generation/lead-scoring-implementation/2026"
  - condition: "Need lead sourcing, not enrichment"
    use_instead: "business/lead-generation/apollo-zoominfo-api-lead-pull/2026"
  - condition: "Only need email verification, not enrichment"
    use_instead: "business/lead-generation/email-verification-workflow/2026"

# === AGENT HINTS ===
inputs_needed:
  - key: enrichment_fields
    question: "Which data fields need enrichment?"
    type: choice
    options: ["email only", "email + phone", "email + phone + firmographic", "full enrichment (all fields)"]
  - key: technical_skill
    question: "What is the user's technical skill level?"
    type: choice
    options: ["non-technical (no-code only)", "semi-technical (can edit code)", "developer (can write code)"]
  - key: budget_for_tools
    question: "What's the enrichment budget?"
    type: choice
    options: ["free tier only", "up to $100/month", "up to $500/month", "no limit"]
  - key: scale
    question: "How many leads to enrich?"
    type: choice
    options: ["50-200 leads", "200-1000 leads", "1000-5000 leads"]

# === EXECUTION METADATA ===
execution:
  required_inputs:
    - name: "Raw lead list"
      source: "agents/lead-scraper or manual"
      format: "CSV with name, company, and optionally LinkedIn URL"
    - name: "ICP definition"
      source: "agents/startup/persona-builder"
      format: "structured data"
  outputs:
    - name: "Enriched lead database"
      format: "CSV"
      description: "Leads with verified email, phone, company size, industry, tech stack, and enrichment metadata"
    - name: "Enrichment audit log"
      format: "JSON"
      description: "Provider hit rates, costs per lead, and data quality metrics"
  tools_required:
    - name: "Hunter.io"
      purpose: "Email discovery and verification"
      tier: "paid"
      cost: "$49/mo (Starter: 500 searches)"
      alternatives: ["Apollo.io email credits", "Prospeo ($39/mo)", "Snov.io ($39/mo)"]
    - name: "Lusha"
      purpose: "Direct phone number discovery"
      tier: "paid"
      cost: "$49/mo (Pro: 40 credits)"
      alternatives: ["Apollo.io mobile credits", "Cognism", "Seamless.AI"]
    - name: "Clearbit"
      purpose: "Firmographic and technographic enrichment"
      tier: "paid"
      cost: "$99/mo (Startup)"
      alternatives: ["Apollo.io firmographics", "ZoomInfo", "6sense"]
    - name: "BuiltWith"
      purpose: "Technology stack identification"
      tier: "paid"
      cost: "$295/mo (Basic)"
      alternatives: ["Wappalyzer (free extension)", "SimilarTech", "HG Insights"]
  credentials_needed:
    - service: "Hunter.io"
      type: "API key"
      where_to_get: "https://hunter.io/api"
      free_tier_limits: "25 searches/month, 50 verifications/month"
    - service: "Lusha"
      type: "API key"
      where_to_get: "https://www.lusha.com/pricing/"
      free_tier_limits: "5 credits/month"
    - service: "Clearbit"
      type: "API key"
      where_to_get: "https://clearbit.com"
      free_tier_limits: "No free tier"
  estimated_duration: "30-90 minutes for 500 leads"
  estimated_cost: "$0 (free tiers) to $200/month (paid enrichment stack)"

# === DISTRIBUTION ===
canonical_source: "https://knowledgelib.io/business/lead-generation/lead-enrichment-pipeline/2026"
suggested_citation: "Source: knowledgelib.io — AI Knowledge Library (verified 2026-03-11)"

# === RELATED UNITS ===
related_kos:
  depends_on:
    - id: "business/lead-generation/linkedin-sales-navigator-scraping-workflow/2026"
      label: "Raw lead list from LinkedIn scraping"
    - id: "business/lead-generation/apollo-zoominfo-api-lead-pull/2026"
      label: "Raw lead list from API pull"
    - id: "business/lead-generation/web-scraping-for-lead-lists/2026"
      label: "Raw lead list from web scraping"
  feeds_into:
    - id: "business/lead-generation/lead-scoring-implementation/2026"
      label: "Score enriched leads before outreach"
    - id: "business/lead-generation/email-verification-workflow/2026"
      label: "Verify enriched emails before sending"
  related_to: []
  alternative_to: []

# === SOURCES ===
sources:
  - id: src1
    title: "Hunter.io API Documentation"
    author: Hunter.io
    url: https://hunter.io/api-documentation/v2
    type: official_docs
    published: 2026-01-01
    reliability: authoritative
  - id: src2
    title: "Best Lead Enrichment Tools for 2026"
    author: ZoomInfo
    url: https://pipeline.zoominfo.com/sales/lead-enrichment-tools
    type: industry_report
    published: 2026-02-01
    reliability: high
  - id: src3
    title: "11 Lead Enrichment Tools for Best Insights (2026)"
    author: Default
    url: https://www.default.com/post/lead-enrichment-tools
    type: technical_blog
    published: 2026-01-15
    reliability: high
  - id: src4
    title: "Hunter.io vs Clearbit: Which Tool Reigns Supreme?"
    author: FullEnrich
    url: https://fullenrich.com/tools/Hunterio-vs-Clearbit
    type: technical_blog
    published: 2025-11-20
    reliability: high
  - id: src5
    title: "22 Best Data Enrichment Tools for B2B Sales in 2026"
    author: BookYourData
    url: https://www.bookyourdata.com/blog/data-enrichment-tools
    type: industry_report
    published: 2026-02-10
    reliability: high
  - id: src6
    title: "Top 11 Hunter.io Alternatives"
    author: RB2B
    url: https://www.rb2b.com/learn/hunter-io-alternatives
    type: technical_blog
    published: 2025-12-05
    reliability: high
---

# Lead Enrichment Pipeline

## Purpose

This recipe takes a raw lead list (names, companies, LinkedIn URLs) and enriches it through a multi-provider waterfall — adding verified work emails, direct phone numbers, firmographic data (company size, industry, revenue), and technology stack information. The output is a fully enriched lead database ready for scoring and outreach, with per-lead cost tracking.

## Prerequisites

- [ ] **Raw lead list** (CSV) from scraping or API pull — minimum columns: first_name, last_name, company
- [ ] **Hunter.io API key** — from [hunter.io/api](https://hunter.io/api) (free: 25 searches/mo)
- [ ] **Lusha API key** (for phone enrichment) — from [lusha.com](https://www.lusha.com)
- [ ] **Python 3.10+** with `requests` and `pandas` installed
- [ ] **Clearbit API key** (optional, for firmographic data) — from [clearbit.com](https://clearbit.com)

## Constraints

- Hunter.io free tier: 25 email searches and 50 verifications per month. Starter plan ($49/mo) provides 500 searches. [src1]
- Lusha free tier: 5 credits/month total. Pro plan ($49/mo) gives 40 credits. Each phone or email reveal costs 1 credit. [src3]
- Clearbit has no free tier. Startup plan starts at $99/month. Enrichment API costs $0.05-$0.20 per record at scale. [src4]
- BuiltWith Basic is $295/month. Free alternative: Wappalyzer browser extension for manual lookups. [src5]
- Waterfall order: Use cheapest provider first, only call the next if the first returns no result. This minimizes cost. [src2]
- GDPR: Enriching EU resident data requires documented legitimate interest. Maintain suppression lists.

## Tool Selection Decision

```
Which path?
├── Budget = free AND needs email only
│   └── PATH A: Hunter.io Free + manual verification
├── Budget = $50-150/mo AND needs email + phone
│   └── PATH B: Hunter Starter + Lusha Pro
├── Budget = $200-500/mo AND needs full enrichment
│   └── PATH C: Hunter + Lusha + Clearbit + Wappalyzer
└── Budget = no limit AND needs maximum coverage
    └── PATH D: Clay waterfall (150+ providers) or Apollo Pro
```

| Path | Tools | Cost | Email Hit Rate | Phone Hit Rate |
|------|-------|------|---------------|----------------|
| A: Email Only | Hunter.io Free | $0 | 50-65% | N/A |
| B: Email + Phone | Hunter + Lusha | $98/mo | 65-80% | 25-40% |
| C: Full Stack | Hunter + Lusha + Clearbit | $247/mo | 75-85% | 30-45% |
| D: Maximum | Clay or Apollo Pro | $149-500/mo | 85-95% | 40-60% |

## Execution Flow

### Step 1: Prepare Input and Set Up Waterfall Config

**Duration**: 5 minutes
**Tool**: Python

```python
import requests
import pandas as pd
import time
import json

# Load raw leads
leads = pd.read_csv("raw_leads.csv")
print(f"Input: {len(leads)} leads")

# Waterfall configuration — cheapest first
PROVIDERS = {
    "hunter": {
        "api_key": "your_hunter_key",
        "cost_per_lookup": 0.098,  # $49/500 searches
        "rate_limit_delay": 1.0,
    },
    "lusha": {
        "api_key": "your_lusha_key",
        "cost_per_lookup": 1.225,  # $49/40 credits
        "rate_limit_delay": 1.5,
    },
    "clearbit": {
        "api_key": "your_clearbit_key",
        "cost_per_lookup": 0.10,
        "rate_limit_delay": 0.5,
    }
}

enrichment_log = []
```

**Verify**: CSV loads with expected row count. All required columns present (first_name, last_name, company).
**If failed**: Check CSV encoding (use UTF-8). Ensure column names match expected format.

### Step 2: Email Enrichment (Hunter.io Waterfall)

**Duration**: 10-30 minutes for 500 leads
**Tool**: Hunter.io API
**Rate limit**: 10 requests/second on paid plans, 1/second on free. [src1]

```python
def enrich_email_hunter(first_name, last_name, company_domain):
    """Find email via Hunter.io domain search"""
    response = requests.get(
        "https://api.hunter.io/v2/email-finder",
        params={
            "domain": company_domain,
            "first_name": first_name,
            "last_name": last_name,
            "api_key": PROVIDERS["hunter"]["api_key"]
        }
    )
    if response.status_code == 200:
        data = response.json().get("data", {})
        return {
            "email": data.get("email"),
            "confidence": data.get("confidence", 0),
            "provider": "hunter"
        }
    return None

# Process each lead
for idx, lead in leads.iterrows():
    # Try Hunter.io first
    domain = lead.get("company_domain") or f"{lead['company'].lower().replace(' ', '')}.com"
    result = enrich_email_hunter(lead["first_name"], lead["last_name"], domain)

    if result and result["email"] and result["confidence"] > 70:
        leads.at[idx, "email"] = result["email"]
        leads.at[idx, "email_confidence"] = result["confidence"]
        leads.at[idx, "email_provider"] = "hunter"
    else:
        leads.at[idx, "email"] = None
        leads.at[idx, "email_provider"] = "not_found"

    enrichment_log.append({"lead_idx": idx, "provider": "hunter", "found": bool(result and result["email"])})
    time.sleep(PROVIDERS["hunter"]["rate_limit_delay"])
```

**Expected output**: 50-80% of leads now have email addresses with confidence scores.
**Verify**: Email coverage > 50%. Average confidence > 70%.
**If failed**: If < 30% hit rate, company domains may be incorrect. Try enriching domains first via Clearbit.

### Step 3: Phone Enrichment (Lusha Waterfall)

**Duration**: 10-20 minutes for leads missing phone
**Tool**: Lusha API

```python
def enrich_phone_lusha(first_name, last_name, company):
    """Find direct phone via Lusha"""
    response = requests.get(
        "https://api.lusha.com/person",
        headers={"api_key": PROVIDERS["lusha"]["api_key"]},
        params={
            "firstName": first_name,
            "lastName": last_name,
            "company": company
        }
    )
    if response.status_code == 200:
        data = response.json()
        phones = data.get("phoneNumbers", [])
        return {
            "phone": phones[0].get("internationalNumber") if phones else None,
            "phone_type": phones[0].get("type") if phones else None,
            "provider": "lusha"
        }
    return None

# Only enrich leads that already have a verified email (prioritize hot leads)
for idx, lead in leads[leads["email"].notna()].iterrows():
    result = enrich_phone_lusha(lead["first_name"], lead["last_name"], lead["company"])
    if result and result["phone"]:
        leads.at[idx, "phone"] = result["phone"]
        leads.at[idx, "phone_type"] = result["phone_type"]
        leads.at[idx, "phone_provider"] = "lusha"
    time.sleep(PROVIDERS["lusha"]["rate_limit_delay"])
```

**Verify**: Phone coverage > 20% of leads with emails.
**If failed**: Lusha has lower coverage for small companies. Consider Apollo mobile credits as fallback.

### Step 4: Firmographic Enrichment (Clearbit)

**Duration**: 10-20 minutes
**Tool**: Clearbit Company API (or Wappalyzer for tech stack)

```python
def enrich_firmographic(domain):
    """Get company firmographic data via Clearbit"""
    response = requests.get(
        f"https://company.clearbit.com/v2/companies/find?domain={domain}",
        headers={"Authorization": f"Bearer {PROVIDERS['clearbit']['api_key']}"}
    )
    if response.status_code == 200:
        data = response.json()
        return {
            "company_size": data.get("metrics", {}).get("employees"),
            "revenue_range": data.get("metrics", {}).get("estimatedAnnualRevenue"),
            "industry": data.get("category", {}).get("industry"),
            "tech_stack": data.get("tech", []),
            "founded_year": data.get("foundedYear"),
            "provider": "clearbit"
        }
    return None

# Enrich unique companies only (deduplicate by domain)
unique_domains = leads["company_domain"].dropna().unique()
company_data = {}
for domain in unique_domains:
    result = enrich_firmographic(domain)
    if result:
        company_data[domain] = result
    time.sleep(PROVIDERS["clearbit"]["rate_limit_delay"])

# Map back to leads
for idx, lead in leads.iterrows():
    domain = lead.get("company_domain")
    if domain in company_data:
        for field in ["company_size", "revenue_range", "industry", "founded_year"]:
            leads.at[idx, field] = company_data[domain].get(field)
```

**Verify**: Firmographic data available for > 60% of unique companies.

### Step 5: Generate Enrichment Audit and Export

**Duration**: 5-10 minutes

```python
# Calculate costs and metrics
email_found = leads["email"].notna().sum()
phone_found = leads["phone"].notna().sum() if "phone" in leads.columns else 0
firmographic_found = leads["company_size"].notna().sum() if "company_size" in leads.columns else 0

audit = {
    "total_leads": len(leads),
    "email_coverage": f"{email_found / len(leads) * 100:.1f}%",
    "phone_coverage": f"{phone_found / len(leads) * 100:.1f}%",
    "firmographic_coverage": f"{firmographic_found / len(leads) * 100:.1f}%",
    "total_cost": f"${email_found * 0.098 + phone_found * 1.225 + len(unique_domains) * 0.10:.2f}",
    "cost_per_enriched_lead": f"${(email_found * 0.098 + phone_found * 1.225) / max(email_found, 1):.2f}"
}

with open("enrichment_audit.json", "w") as f:
    json.dump(audit, f, indent=2)

leads.to_csv("enriched_leads.csv", index=False)
print(json.dumps(audit, indent=2))
```

**Output files**:
- `enriched_leads.csv` — Fully enriched lead database
- `enrichment_audit.json` — Cost and coverage metrics

## Output Schema

```json
{
  "output_type": "enriched_lead_database",
  "format": "CSV",
  "columns": [
    {"name": "first_name", "type": "string", "description": "Contact first name", "required": true},
    {"name": "last_name", "type": "string", "description": "Contact last name", "required": true},
    {"name": "company", "type": "string", "description": "Company name", "required": true},
    {"name": "email", "type": "string", "description": "Verified work email", "required": false},
    {"name": "email_confidence", "type": "number", "description": "Email confidence score 0-100", "required": false},
    {"name": "email_provider", "type": "string", "description": "Provider that found the email", "required": false},
    {"name": "phone", "type": "string", "description": "Direct phone number", "required": false},
    {"name": "company_size", "type": "number", "description": "Employee count", "required": false},
    {"name": "industry", "type": "string", "description": "Company industry", "required": false},
    {"name": "revenue_range", "type": "string", "description": "Estimated revenue range", "required": false}
  ],
  "expected_row_count": "200-5000",
  "sort_order": "email_confidence descending",
  "deduplication_key": "email"
}
```

## Quality Benchmarks

| Quality Metric | Minimum Acceptable | Good | Excellent |
|---------------|-------------------|------|-----------|
| Email coverage | > 50% | > 70% | > 85% |
| Email confidence avg | > 70 | > 80 | > 90 |
| Phone coverage | > 15% | > 30% | > 45% |
| Firmographic coverage | > 40% | > 65% | > 80% |
| Cost per enriched lead | < $1.00 | < $0.50 | < $0.20 |

**If below minimum**: Add additional waterfall providers. Check that company domains are resolving correctly.

## Error Handling

| Error | Likely Cause | Recovery Action |
|-------|-------------|----------------|
| Hunter 429 Rate Limited | Exceeded 10 req/sec | Add 1s delay between requests |
| Hunter 401 Unauthorized | API key invalid | Regenerate at hunter.io/api |
| Lusha 402 Insufficient Credits | Monthly credits exhausted | Upgrade plan or wait for reset |
| Clearbit 404 Not Found | Domain not in database | Skip, mark as unenriched |
| Low email hit rate (<30%) | Incorrect company domains | Enrich domains via Clearbit first |

## Cost Breakdown

| Component | Free Tier | Paid Tier | At Scale |
|-----------|-----------|-----------|----------|
| Hunter.io (email) | 25 searches/mo | $49/mo (500) | $149/mo (5,000) |
| Lusha (phone) | 5 credits/mo | $49/mo (40) | $79/mo (80) |
| Clearbit (firmographic) | None | $99/mo | $0.05-0.20/record |
| BuiltWith (tech stack) | Manual only | $295/mo | $295/mo |
| **Total for 500 leads** | **$0** | **$197/mo** | **$523+/mo** |

## Anti-Patterns

### Wrong: Calling all providers for every lead simultaneously
Running every lead through Hunter, Lusha, Clearbit, and BuiltWith wastes credits and money. Most leads can be enriched by the first provider. [src2]

### Correct: Waterfall logic — cheapest first, fall through on miss
Try Hunter first (cheapest per lookup). Only call Lusha if Hunter misses. Only call Clearbit for company data not available from the search API. [src2]

### Wrong: Enriching before deduplication
Enriching duplicate leads doubles or triples your credit consumption for no additional value. [src3]

### Correct: Deduplicate raw list before any enrichment API calls
Remove duplicate name+company pairs first. Then enrich the deduplicated list.

## When This Matters

Use when the agent has a raw lead list (from scraping, API pull, or manual compilation) that needs work emails, phone numbers, and firmographic data before scoring and outreach. The waterfall approach maximizes data coverage while minimizing per-lead cost.

## Related Units

- [LinkedIn Sales Navigator Scraping](/business/lead-generation/linkedin-sales-navigator-scraping-workflow/2026)
- [Apollo/ZoomInfo API Lead Pull](/business/lead-generation/apollo-zoominfo-api-lead-pull/2026)
- [Lead Scoring Implementation](/business/lead-generation/lead-scoring-implementation/2026)
- [Email Verification Workflow](/business/lead-generation/email-verification-workflow/2026)
- [Web Scraping for Lead Lists](/business/lead-generation/web-scraping-for-lead-lists/2026)
