---
# === IDENTITY ===
id: business/lead-generation/apollo-zoominfo-api-lead-pull/2026
canonical_question: "How do I pull leads from Apollo.io/ZoomInfo API — query construction, enrichment fields, dedup, cost-per-lead benchmarks?"
aliases:
  - "Apollo.io API lead generation and enrichment workflow"
  - "ZoomInfo API contact search and export process"
  - "Programmatic lead pull from sales intelligence APIs"
entity_type: execution_recipe
domain: business > lead-generation > apollo zoominfo api lead pull
region: global
jurisdiction: global
temporal_scope: 2024-2026

# === VERIFICATION ===
last_verified: 2026-03-11
confidence: 0.89
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:
  - "Apollo.io free tier: 10,000 records export/month, 60 mobile credits, 120 email credits"
  - "Apollo Professional ($79/seat/mo billed annually): unlimited emails, 100 mobile credits/mo, advanced filters"
  - "ZoomInfo has no public pricing — starts ~$15,000/year for basic package, API access requires enterprise tier"
  - "Apollo API rate limit: 100 requests/minute on most endpoints, 50/min on enrichment"
  - "Both platforms require opt-out compliance for CCPA and GDPR — do not suppress opt-out requests"

# === SKIP CONDITIONS ===
skip_this_unit_if:
  - condition: "Need to scrape LinkedIn directly, not use a data provider API"
    use_instead: "business/lead-generation/linkedin-sales-navigator-scraping-workflow/2026"
  - condition: "Need a lead generation strategy, not execution"
    use_instead: "Search knowledgelib.io for lead generation strategy — no dedicated unit yet"
  - condition: "Budget is zero — no paid tool budget available"
    use_instead: "business/lead-generation/web-scraping-for-lead-lists/2026"

# === AGENT HINTS ===
inputs_needed:
  - key: data_provider
    question: "Which data provider to use?"
    type: choice
    options: ["Apollo.io", "ZoomInfo", "both (waterfall)", "no preference — auto-select"]
  - 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 tool/API budget?"
    type: choice
    options: ["free tier only", "up to $100/month", "up to $500/month", "enterprise ($15K+/year)"]
  - key: scale
    question: "How many leads per month?"
    type: choice
    options: ["100-500 leads", "500-2000 leads", "2000-10000 leads"]

# === EXECUTION METADATA ===
execution:
  required_inputs:
    - name: "ICP definition"
      source: "agents/startup/persona-builder"
      format: "structured data"
    - name: "Target account list (optional)"
      source: "manual or CRM export"
      format: "CSV with company names or domains"
  outputs:
    - name: "Enriched lead database"
      format: "CSV"
      description: "Leads with name, title, company, email, phone, firmographic data, and enrichment metadata"
    - name: "API query log"
      format: "JSON"
      description: "Saved API queries for reproducibility and credit tracking"
  tools_required:
    - name: "Apollo.io"
      purpose: "Contact search, email/phone credits, firmographic enrichment"
      tier: "paid"
      cost: "$79/seat/month (Professional, billed annually)"
      alternatives: ["ZoomInfo ($15K+/year)", "Lusha ($49/mo)", "Clearbit ($99/mo)"]
    - name: "ZoomInfo"
      purpose: "Enterprise-grade contact and company intelligence"
      tier: "enterprise"
      cost: "$15,000-$40,000+/year"
      alternatives: ["Apollo.io ($79/mo)", "Cognism ($1K+/mo)", "6sense"]
  credentials_needed:
    - service: "Apollo.io"
      type: "API key"
      where_to_get: "https://app.apollo.io/#/settings/integrations/api"
      free_tier_limits: "10,000 records/mo, 120 email credits, 60 mobile credits"
    - service: "ZoomInfo"
      type: "API key + OAuth"
      where_to_get: "https://developers.zoominfo.com/"
      free_tier_limits: "No free tier — enterprise contract required"
  estimated_duration: "20-45 minutes for 500 leads"
  estimated_cost: "$0 (Apollo free) to $79/mo (Apollo Pro) to $15K+/yr (ZoomInfo)"

# === DISTRIBUTION ===
canonical_source: "https://knowledgelib.io/business/lead-generation/apollo-zoominfo-api-lead-pull/2026"
suggested_citation: "Source: knowledgelib.io — AI Knowledge Library (verified 2026-03-11)"

# === RELATED UNITS ===
related_kos:
  depends_on:
    - id: "business/customer-research/ideal-customer-profile-framework/2026"
      label: "Building an ICP — firmographic (B2B) or demographic (B2C) criteria, behavioral signals, disqualification criteria"
  feeds_into:
    - id: "business/lead-generation/lead-enrichment-pipeline/2026"
      label: "Further enrichment with additional data providers"
    - id: "business/lead-generation/lead-scoring-implementation/2026"
      label: "Score leads before outreach"
    - id: "business/lead-generation/email-verification-workflow/2026"
      label: "Verify emails before sending"
  related_to:
    - id: "business/lead-generation/linkedin-sales-navigator-scraping-workflow/2026"
      label: "LinkedIn-direct alternative"
  alternative_to:
    - id: "business/lead-generation/web-scraping-for-lead-lists/2026"
      label: "Free alternative using public web data"

# === SOURCES ===
sources:
  - id: src1
    title: "Apollo.io API Pricing"
    author: Apollo.io
    url: https://docs.apollo.io/docs/api-pricing
    type: official_docs
    published: 2026-01-15
    reliability: authoritative
  - id: src2
    title: "Apollo.io People Enrichment API Documentation"
    author: Apollo.io
    url: https://docs.apollo.io/reference/people-enrichment
    type: official_docs
    published: 2026-01-15
    reliability: authoritative
  - id: src3
    title: "Apollo.io Pricing 2026: What Each Plan Actually Gets You"
    author: Cotera
    url: https://cotera.co/articles/apollo-io-pricing-guide
    type: industry_report
    published: 2026-02-10
    reliability: high
  - id: src4
    title: "ZoomInfo Pricing Explained (2026): Real Costs, Plans, and Hidden Fees"
    author: SmarterB2B
    url: https://www.smarte.pro/blog/zoominfo-pricing
    type: industry_report
    published: 2026-01-20
    reliability: high
  - id: src5
    title: "ZoomInfo API Review 2026: Enrichment That Actually Works?"
    author: Generect
    url: https://generect.com/blog/zoominfo-api/
    type: technical_blog
    published: 2026-02-05
    reliability: high
  - id: src6
    title: "Apollo.io Review 2026: Features, Pricing, Pros and Cons"
    author: LaGrowthMachine
    url: https://lagrowthmachine.com/apollo-io-review/
    type: technical_blog
    published: 2026-02-15
    reliability: high
---

# Apollo.io / ZoomInfo API Lead Pull

## Purpose

This recipe produces an enriched lead database of 200-5,000 contacts pulled from Apollo.io or ZoomInfo APIs, with verified work emails, direct phone numbers, firmographic data (industry, employee count, revenue), and technographic signals. The output includes deduplication and cost tracking per lead, ready for scoring and outreach.

## Prerequisites

- [ ] **ICP definition** available from `persona-builder` agent — [ICP Definition](/business/customer-research/ideal-customer-profile-definition/2026)
- [ ] **Apollo.io API key** — from [Apollo Settings](https://app.apollo.io/#/settings/integrations/api) (free tier: 10K records/mo)
- [ ] **Python 3.10+** or **Node.js 18+** installed for API scripting
- [ ] **Target account list** (optional) — CSV with company names or domains for account-based search

## Constraints

- Apollo.io free tier: 10,000 record exports/month, 120 email credits, 60 mobile credits. Each email reveal costs 1 credit; phone costs 5 credits. [src1]
- Apollo Professional plan ($79/seat/mo annually) unlocks unlimited email credits and advanced filters including technographics and intent data. [src3]
- ZoomInfo requires enterprise contract starting at ~$15,000/year with no self-serve option. API access typically requires the highest tier. [src4]
- Apollo API rate limit: 100 requests/minute on search, 50/minute on enrichment endpoints. [src1]
- Both platforms require CCPA/GDPR opt-out compliance — maintain suppression lists. [src2]

## Tool Selection Decision

```
Which path?
├── Budget = free AND scale < 500 leads/mo
│   └── PATH A: Apollo Free Tier — UI search + CSV export
├── Budget = $50-200/mo AND scale 500-2000
│   └── PATH B: Apollo Professional — API + advanced filters
├── Budget = enterprise ($15K+/yr) AND scale 2000+
│   └── PATH C: ZoomInfo API — full enrichment + intent data
└── Need maximum coverage
    └── PATH D: Waterfall — Apollo first, ZoomInfo for gaps
```

| Path | Tools | Cost | Speed | Output Quality |
|------|-------|------|-------|---------------|
| A: Apollo Free | Apollo UI + export | $0 | 30 min/200 leads | Good — limited credits |
| B: Apollo Pro | Apollo API | $79/mo/seat | 20 min/1000 leads | High — full enrichment |
| C: ZoomInfo | ZoomInfo API | $15K+/yr | 15 min/2000 leads | Highest — intent + org charts |
| D: Waterfall | Apollo + ZoomInfo | $79/mo + $15K/yr | 30 min/2000 leads | Maximum coverage |

## Execution Flow

### Step 1: Construct API Search Query

**Duration**: 10 minutes
**Tool**: Apollo.io API (or ZoomInfo equivalent)

Translate ICP into API query parameters. Apollo's People Search endpoint accepts company size, title keywords, industry, location, and technology filters.

```python
import requests

APOLLO_API_KEY = "your_api_key_here"

# Apollo People Search API
response = requests.post(
    "https://api.apollo.io/api/v1/mixed_people/search",
    headers={"Content-Type": "application/json"},
    json={
        "api_key": APOLLO_API_KEY,
        "person_titles": ["VP Sales", "Director Sales", "Head of Revenue"],
        "organization_num_employees_ranges": ["51,200", "201,500"],
        "person_locations": ["United States"],
        "organization_industry_tag_ids": [],  # Use Apollo industry IDs
        "page": 1,
        "per_page": 100
    }
)

data = response.json()
print(f"Total matches: {data.get('pagination', {}).get('total_entries', 0)}")
```

**Verify**: API returns 200 status and `total_entries > 0`. If zero results, broaden title or industry filters.
**If failed**: Check API key validity. Ensure query parameters match Apollo's expected format.

### Step 2: Paginate and Extract All Results

**Duration**: 10-30 minutes depending on volume
**Tool**: Python script
**Rate limit**: 100 requests/minute. With 100 results/page, 1,000 leads = 10 pages = 10 seconds minimum. [src1]

```python
import time

all_leads = []
page = 1
total_pages = 1

while page <= total_pages:
    response = requests.post(
        "https://api.apollo.io/api/v1/mixed_people/search",
        headers={"Content-Type": "application/json"},
        json={
            "api_key": APOLLO_API_KEY,
            "person_titles": ["VP Sales", "Director Sales"],
            "organization_num_employees_ranges": ["51,200"],
            "person_locations": ["United States"],
            "page": page,
            "per_page": 100
        }
    )
    data = response.json()
    total_pages = data["pagination"]["total_pages"]

    for person in data.get("people", []):
        all_leads.append({
            "first_name": person.get("first_name"),
            "last_name": person.get("last_name"),
            "title": person.get("title"),
            "company": person.get("organization", {}).get("name"),
            "email": person.get("email"),
            "phone": person.get("phone_numbers", [{}])[0].get("number") if person.get("phone_numbers") else None,
            "linkedin_url": person.get("linkedin_url"),
            "company_size": person.get("organization", {}).get("estimated_num_employees"),
            "industry": person.get("organization", {}).get("industry"),
            "city": person.get("city"),
            "state": person.get("state"),
        })

    page += 1
    time.sleep(0.7)  # Stay under 100 req/min

print(f"Extracted {len(all_leads)} leads across {total_pages} pages")
```

**Expected output**: List of dicts with 200-5,000 leads depending on ICP breadth.
**Verify**: Row count > 100. Check that email field is populated for > 50% of records.
**If failed**: If email field is null, you may need to use the People Enrichment endpoint separately (costs additional credits). [src2]

### Step 3: Enrich Missing Fields

**Duration**: 5-15 minutes
**Tool**: Apollo People Enrichment API

For leads missing email or phone, run them through the enrichment endpoint.

```python
leads_needing_enrichment = [l for l in all_leads if not l["email"]]

for lead in leads_needing_enrichment:
    response = requests.post(
        "https://api.apollo.io/api/v1/people/match",
        json={
            "api_key": APOLLO_API_KEY,
            "first_name": lead["first_name"],
            "last_name": lead["last_name"],
            "organization_name": lead["company"],
            "linkedin_url": lead.get("linkedin_url")
        }
    )
    if response.status_code == 200:
        person = response.json().get("person", {})
        lead["email"] = person.get("email")
        lead["phone"] = person.get("phone_numbers", [{}])[0].get("number") if person.get("phone_numbers") else None
    time.sleep(1.2)  # 50 req/min limit on enrichment
```

**Verify**: Email coverage rate improves to > 70% after enrichment.
**If failed**: Remaining gaps can be filled with Hunter.io or Lusha in the enrichment pipeline.

### Step 4: Deduplicate and Clean

**Duration**: 5-10 minutes
**Tool**: Python (pandas)

```python
import pandas as pd

df = pd.DataFrame(all_leads)

# Deduplicate by email (primary) and name+company (secondary)
df = df.drop_duplicates(subset=["email"], keep="first")
df = df.drop_duplicates(subset=["first_name", "last_name", "company"], keep="first")

# Remove rows missing critical fields
df = df.dropna(subset=["first_name", "last_name", "company"])

# Track credit usage
credits_used = len(df[df["email"].notna()])  # 1 credit per email revealed
phone_credits = len(df[df["phone"].notna()]) * 5  # 5 credits per phone

print(f"Final: {len(df)} leads | Email credits: {credits_used} | Phone credits: {phone_credits}")
print(f"Cost per lead: ${(credits_used * 0.01 + phone_credits * 0.01):.2f} total / {len(df)} = ${((credits_used + phone_credits) * 0.01 / len(df)):.4f}/lead")

df.to_csv("apollo_leads_final.csv", index=False)
```

**Verify**: Final list has zero duplicates on email column. Credit usage is within monthly budget.

### Step 5: Export with Cost Tracking

**Duration**: 5 minutes

```python
# Add metadata columns
df["lead_source"] = "Apollo.io"
df["date_pulled"] = "2026-03-11"
df["credit_cost"] = df.apply(
    lambda r: 1 + (5 if pd.notna(r["phone"]) else 0), axis=1
)

df.to_csv("final_leads_with_costs.csv", index=False)

# Summary report
summary = {
    "total_leads": len(df),
    "emails_found": len(df[df["email"].notna()]),
    "phones_found": len(df[df["phone"].notna()]),
    "total_credits": df["credit_cost"].sum(),
    "cost_per_lead": f"${df['credit_cost'].sum() * 0.01 / len(df):.4f}"
}
print(summary)
```

**Output files**:
- `final_leads_with_costs.csv` — Primary lead database with cost tracking
- `api_queries.json` — Saved API parameters for reproducibility

## 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": "title", "type": "string", "description": "Job title", "required": true},
    {"name": "company", "type": "string", "description": "Company name", "required": true},
    {"name": "email", "type": "string", "description": "Work email address", "required": false},
    {"name": "phone", "type": "string", "description": "Direct phone number", "required": false},
    {"name": "linkedin_url", "type": "string", "description": "LinkedIn profile URL", "required": false},
    {"name": "company_size", "type": "number", "description": "Estimated employee count", "required": false},
    {"name": "industry", "type": "string", "description": "Company industry", "required": false},
    {"name": "city", "type": "string", "description": "Contact city", "required": false},
    {"name": "state", "type": "string", "description": "Contact state/region", "required": false},
    {"name": "lead_source", "type": "string", "description": "Data provider name", "required": true},
    {"name": "credit_cost", "type": "number", "description": "Credits consumed for this lead", "required": true}
  ],
  "expected_row_count": "200-5000",
  "sort_order": "company ascending",
  "deduplication_key": "email"
}
```

## Quality Benchmarks

| Quality Metric | Minimum Acceptable | Good | Excellent |
|---------------|-------------------|------|-----------|
| Email coverage | > 50% | > 70% | > 85% |
| Phone coverage | > 15% | > 30% | > 50% |
| ICP match rate | > 75% | > 85% | > 95% |
| Duplicate rate | < 5% | < 2% | < 0.5% |
| Data freshness (contact still at company) | > 80% | > 90% | > 95% |

**If below minimum**: Switch to Professional tier for better data access, or supplement with second data provider (waterfall approach).

## Error Handling

| Error | Likely Cause | Recovery Action |
|-------|-------------|----------------|
| 429 Too Many Requests | Rate limit exceeded | Wait 60 seconds, reduce request frequency |
| 401 Unauthorized | API key invalid or expired | Regenerate key at Apollo settings page |
| Empty results (0 matches) | Query too narrow | Broaden title keywords, expand company size range |
| Low email coverage (<30%) | Free tier credit exhaustion | Upgrade to Professional or use enrichment pipeline |
| Stale data (contact left company) | Database lag | Cross-reference with LinkedIn profile |

## Cost Breakdown

| Component | Free Tier | Paid Tier | At Scale |
|-----------|-----------|-----------|----------|
| Apollo.io search | 10K records/mo | Unlimited (Pro $79/mo) | Unlimited |
| Email credits | 120/mo | Unlimited (Pro) | Unlimited |
| Mobile credits | 60/mo ($0.10/credit) | 100/mo (Pro) | 200/mo ($199/mo) |
| ZoomInfo (alternative) | No free tier | $15K-$25K/yr | $25K-$40K+/yr |
| **Cost per lead (Apollo)** | **~$0.01** | **~$0.05-0.15** | **~$0.03-0.10** |

## Anti-Patterns

### Wrong: Pulling maximum leads without credit monitoring
Running the API without tracking credit consumption can exhaust monthly allocation mid-campaign, leaving no credits for enrichment or follow-up pulls. [src3]

### Correct: Track credits per lead and set budget alerts
Log credit_cost per record. Set a 75% usage alert. Reserve 20% of monthly credits for enrichment and re-pulls.

### Wrong: Using Apollo free tier for enterprise-scale prospecting
The 120 email credits/month on free tier means you can only reveal ~120 emails — far below the 1,000+ needed for sustained outbound. [src1]

### Correct: Match tier to volume needs
Free tier works for validation (50-100 leads). Professional ($79/mo) for sustained outbound (500-2,000/mo). ZoomInfo for enterprise (5,000+/mo). [src3]

## When This Matters

Use when the agent needs to pull a lead list from a sales intelligence API with structured filters rather than scraping. Ideal for teams with budget for data providers who want clean, enriched data without LinkedIn rate limit constraints.

## Related Units

- [ICP Definition](/business/customer-research/ideal-customer-profile-definition/2026)
- [Lead Enrichment Pipeline](/business/lead-generation/lead-enrichment-pipeline/2026)
- [Lead Scoring Implementation](/business/lead-generation/lead-scoring-implementation/2026)
- [LinkedIn Sales Navigator Scraping](/business/lead-generation/linkedin-sales-navigator-scraping-workflow/2026)
- [Email Verification Workflow](/business/lead-generation/email-verification-workflow/2026)
