Complete B2B lead generation machine combining Apollo.io, Google Search, LinkedIn scraping, and AI-powered qualification into one automated system.
Generate, enrich, and qualify thousands of high-quality B2B leads automatically. This intelligent system finds prospects from multiple sources, enriches profiles with complete data, and scores lead quality using AI.
- Overview
- Key Features
- System Architecture
- Five Automated Workflows
- Tech Stack
- Prerequisites
- Installation
- Configuration
- Usage Guide
- Airtable Structure
- API Configuration
- Lead Qualification
- Troubleshooting
- Best Practices
- License
Lead Generation System is an enterprise-grade automation that combines multiple lead sources and enrichment methods into a single, intelligent workflow. It scrapes leads from Apollo.io, finds prospects via Google Search, enriches all profiles with LinkedIn data, and uses AI to qualify leads against your Ideal Customer Profile (ICP).
- π’ B2B Sales Teams - Scale prospecting from dozens to thousands of leads
- π Marketing Agencies - Build targeted prospect lists for clients
- πΌ Growth Teams - Automate entire lead generation pipeline
- π Startups - Compete with enterprise-level prospecting capabilities
- π₯ SDR Teams - Focus on outreach instead of manual research
Traditional B2B lead generation requires:
- Manually searching Apollo or LinkedIn Sales Navigator
- Copying data into spreadsheets one by one
- Researching company websites for qualification
- Scoring leads subjectively
- Days of work for hundreds of leads
This system automates everything in hours, processing thousands of leads with consistent quality and AI-powered scoring.
- Apollo.io search result scraping
- Google Search for LinkedIn profiles
- Dual-channel approach maximizes coverage
- Configurable lead limits per campaign
- Full LinkedIn profile scraping via Apify
- Company website data extraction
- 25+ data fields per lead
- Mobile numbers and emails
- Work experience history
- Company size and details
- Google Gemini analyzes each lead
- Scores 0-10 based on ICP fit
- Considers job title, company type, size, location
- Analyzes website content automatically
- Natural language ICP definitions
- Organized Airtable base structure
- Campaign-based lead organization
- Automatic status tracking
- ICP details stored with each lead
- Easy export to CRM systems
- 5 distinct workflow paths
- Webhook-triggered automation
- Process leads from any source
- Enrich existing databases
- Qualify pre-scraped leads
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β WEBHOOK TRIGGER β
β (Single endpoint, multiple actions) β
βββββββββββββββββββββββββ¬ββββββββββββββββββββββββββββββββββββββββββ
β
β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β SWITCH ROUTER β
β Directs to appropriate workflow branch β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β β
β 1. ScrapeApollo β
β 2. EnrichApolloProfiles β
β 3. ScrapeLinkedInProfiles β
β 4. EnrichLinkedInProfiles β
β 5. QualifyLeads β
β β
βββββββββββββββββββββββββ¬ββββββββββββββββββββββββββββββββββββββββββ
β
βββββββββββββ΄ββββββββββββ
β β
β β
βββββββββββββββββββββββ βββββββββββββββββββββββ
β APOLLO WORKFLOW β β LINKEDIN WORKFLOW β
βββββββββββββββββββββββ€ βββββββββββββββββββββββ€
β β β β
β β’ Scrape Apollo β β β’ Build Google Queryβ
β β’ Extract Leads β β β’ Search LinkedIn β
β β’ Store in Airtable β β β’ Paginate Results β
β β’ Trigger Enrich β β β’ Store Profiles β
β β β β’ Trigger Enrich β
ββββββββββββ¬βββββββββββ ββββββββββββ¬βββββββββββ
β β
ββββββββββββββ¬ββββββββββββ
β
β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β ENRICHMENT WORKFLOW β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β β
β β’ Fetch Lead from Airtable β
β β’ Scrape LinkedIn Profile (Apify) β
β β’ Extract 25+ data fields β
β β’ Parse experience, company, contact info β
β β’ Update Airtable with enriched data β
β β
βββββββββββββββββββββββββ¬ββββββββββββββββββββββββββββββββββββββββββ
β
β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β QUALIFICATION WORKFLOW β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β β
β 1. Fetch Lead Data from Airtable β
β 2. Extract Company Website with Tavily β
β 3. Send to Google Gemini with ICP β
β 4. AI Analyzes Fit (Job, Company, Industry) β
β 5. Returns Score 0-10 β
β 6. Update Airtable with Qualification Score β
β β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β
β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β AIRTABLE DATABASE β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β β
β β’ Apollo Campaigns & Leads β
β β’ Google Search Campaigns & Leads β
β β’ Aggregated Emails (Qualified Leads) β
β β’ Full lead profiles with 25+ fields β
β β’ Qualification scores and ICP details β
β β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Purpose: Extract leads from Apollo.io search results
Trigger: Webhook with action=ScrapeApollo
Process:
- Reads Apollo campaign from Airtable
- Calls Apify Apollo Scraper with search URL
- Scrapes specified number of leads
- Inserts into Apollo Leads table
- Updates campaign status to "Scraping Complete"
Output: Apollo leads with basic info (name, title, company, email)
Purpose: Enrich Apollo leads with full LinkedIn profile data
Trigger: Webhook with action=EnrichApolloProfiles
Process:
- Reads lead from Apollo Leads table
- Calls Apify LinkedIn Profile Scraper
- Extracts 25+ data fields
- Parses experience, company details
- Updates lead with enriched data
Output: Fully enriched Apollo lead ready for qualification
Purpose: Find LinkedIn profiles via Google Search based on ICP
Trigger: Webhook with action=ScrapeLinkedInProfiles
Process:
- Reads Google Search campaign from Airtable
- Builds search query:
site:linkedin.com/in/ [Job Title] [Company Type] [Location] - Calls Serper.dev API for Google results
- Handles pagination (20 results per page)
- Extracts LinkedIn profile URLs from search results
- Inserts into Google Search Leads table
- Stores ICP details with each lead
- Updates campaign status
Output: LinkedIn profile URLs matching ICP criteria
Purpose: Enrich Google-found LinkedIn profiles with full data
Trigger: Webhook with action=EnrichLinkedInProfiles
Process:
- Reads lead from Google Search Leads table
- Calls Apify LinkedIn Profile Scraper
- Extracts complete profile information
- Updates lead with enriched data
Output: Fully enriched LinkedIn lead ready for qualification
Purpose: Score leads using AI against ICP
Trigger: Webhook with action=QualifyLeads
Process:
- Reads lead from Aggregated Emails table
- Extracts company website content with Tavily
- Sends to Google Gemini with:
- Target ICP (job title, location, company type, size)
- Lead data (title, headline, about, company)
- Raw website content
- AI analyzes fit and returns score 0-10
- Updates Airtable with qualification score
Output: Qualified lead with AI-generated score
| Category | Technology | Purpose |
|---|---|---|
| Automation | n8n | Workflow orchestration |
| Database | Airtable | Lead storage and campaign management |
| Scraping | Apify | Apollo scraper, LinkedIn profile scraper |
| Search | Serper.dev | Google Search API for LinkedIn discovery |
| Web Extraction | Tavily | Company website content extraction |
| AI Qualification | Google Gemini 2.0 Flash | Lead scoring against ICP |
| Triggers | Webhooks | Airtable automation triggers |
| Service | Required? | Purpose | Cost |
|---|---|---|---|
| n8n | β Yes | Workflow automation | Free (self-hosted) or $20/mo |
| Airtable | β Yes | Database & UI | Free tier available |
| Apify | β Yes | LinkedIn scraping | $49/mo or pay-per-use |
| Serper.dev | β Yes | Google Search API | $50/mo for 5,000 searches |
| Tavily | β Yes | Web content extraction | Free tier: 1,000 requests/mo |
| Google Gemini | β Yes | AI lead qualification | Free tier available |
- β Airtable Personal Access Token
- β Apify API Token
- β Serper.dev API Key
- β Tavily API Key
- β Google Gemini API Key
| Workflow | Source | Output | Use Case |
|---|---|---|---|
| Scrape Apollo | Apollo.io | Basic leads | Have Apollo subscription |
| Scrape LinkedIn | Google Search | LinkedIn URLs | No Apollo, use ICP search |
| Enrich Apollo | Airtable | Full profiles | Enrich Apollo leads |
| Enrich LinkedIn | Airtable | Full profiles | Enrich Google leads |
| Qualify Leads | Airtable | AI scores | Score any leads |
| Metric | Value | Notes |
|---|---|---|
| Apollo Scraping | 50 leads/min | Depends on Apify |
| Google Search | 20 profiles/min | Serper.dev limit |
| Enrichment | 30 sec/lead | Apify processing |
| Qualification | 5 sec/lead | Gemini AI speed |
| Daily Capacity | 50,000+ leads | With proper setup |
| Cost per Lead | $0.05-0.15 | API costs |
- Download
Lead Generation System.jsonfrom this repository - Save to your local machine
- Open your n8n instance
- Click "Workflows" β "Import from File"
- Select the JSON file
- Click "Import"
- Create new base: "Lead Generation Machine"
- Create the following tables:
Table 1: Apollo Campaigns
Fields:
- Campaign Name (Single line text)
- Apollo Search URL (URL)
- Number Of Leads (Number)
- ICP Details (Long text)
- Start Campaign (Checkbox)
- Campaign Status (Single select: Idle, Scraping Leads, Scraping Complete)
Table 2: Apollo Leads
Fields:
- Name (Single line text)
- First Name (Single line text)
- Last Name (Single line text)
- Title (Single line text)
- Headline (Single line text)
- Company (Single line text)
- Industry (Single line text)
- Website (URL)
- Company LinkedIn Url (URL)
- Email (Email)
- LinkedIn Profile Url (URL)
- City (Single line text)
- Country (Single line text)
- LinkedIn Headline (Long text)
- About (Long text)
- Experience (Long text)
- Mobile Number (Phone)
- Company Size (Single line text)
- ICP Details (Long text)
- Apollo Campaigns (Link to Apollo Campaigns)
Table 3: Google Search Campaigns
Fields:
- Campaign Name (Single line text)
- Job Title (Single line text)
- Company Type (Single line text)
- Location (Single line text)
- CompanySize (Single line text)
- Industry (Single line text)
- Number Of Leads (Number)
- Campaign Status (Single select)
- Start Campaign (Checkbox)
Table 4: Google Search Leads
Fields:
- Title (Single line text)
- Linkedin Profile Url (URL)
- LinkedIn Profile Snippet (Long text)
- ICP Details (Long text)
- First Name (Single line text)
- Last Name (Single line text)
- Headline (Long text)
- Address (Single line text)
- About (Long text)
- experianceDetails (Long text)
- email (Email)
- Company Name (Single line text)
- companyWebsite (URL)
- Company LinkedIn (URL)
- Company Size (Single line text)
- Job Title (Single line text)
- Mobile Number (Phone)
- Google Search Campaigns (Link to Google Search Campaigns)
Table 5: Aggregated Emails
Fields:
- First Name (Single line text)
- Last Name (Single line text)
- Title (Single line text)
- Headline (Long text)
- Company (Single line text)
- Industry (Single line text)
- Website (URL)
- Company LinkedIn Url (URL)
- Email (Email)
- LinkedIn Profile Url (URL)
- City (Single line text)
- Country (Single line text)
- LinkedIn Headline (Long text)
- About (Long text)
- Experience (Long text)
- Mobile Number (Phone)
- Company Size (Single line text)
- ICP (Long text)
- Qualification Score (Number)
- Apollo Campaigns (Link to Apollo Campaigns)
- Go to https://airtable.com/create/tokens
- Create new token with scopes:
- data.records:read
- data.records:write
- schema.bases:read
- Add access to your base
- Copy token
Open the imported workflow and update these nodes:
All Airtable nodes need credentials:
- In n8n: Settings β Credentials
- Add "Airtable Personal Access Token"
- Paste your token
In nodes:
- "Apollo Scraper"
- "Apify" (both instances)
- "Apify1"
Replace INSERT_API_KEY_HERE with your Apify token in the URL:
https://api.apify.com/v2/acts/[actor]/run-sync-get-dataset-items?token=YOUR_TOKEN
Nodes: "SerperDev", "SerperDev1"
- Create Header Auth credential in n8n
- Header name:
X-API-KEY - Header value: Your Serper.dev API key
Node: "Tavily Extract"
In header parameters:
Authorization: Bearer YOUR_TAVILY_API_KEY
Node: "Google Gemini Chat Model6"
- Get API key from https://aistudio.google.com/app/apikey
- Add to n8n credentials: "Google Gemini(PaLM) Api"
In all Airtable nodes, update:
- Base ID: Your Airtable base ID
- Table IDs: Your table IDs
Find these in Airtable URL:
https://airtable.com/appXXXXXXXXXXXXXX/tblYYYYYYYYYYYYYY
^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^
Base ID Table ID
- Click "Active" toggle (top-right)
- Workflow is now live and ready!
After activation, get your webhook URL from the "Webhook" node:
https://your-n8n-instance.com/webhook/lead-machine-v2
Create automations in each campaign table:
For Apollo Campaigns:
When: Record matches conditions
Condition: Start Campaign = true
Action: Send webhook request
URL: [Your webhook URL]?action=ScrapeApollo&recordId={Record ID}
Method: GET
For Google Search Campaigns:
When: Record matches conditions
Condition: Start Campaign = true
Action: Send webhook request
URL: [Your webhook URL]?action=ScrapeLinkedInProfiles&recordId={Record ID}
Method: GET
- Open Apollo Campaigns table
- Add new record:
- Campaign Name: "SaaS Founders Q1 2025"
- Apollo Search URL: [Your saved search URL]
- Number Of Leads: 100
- ICP Details: "Series A/B SaaS founders in USA"
- Start Campaign: βοΈ
- Campaign Status changes to "Scraping Leads"
- Workflow scrapes leads from Apollo
- Leads appear in Apollo Leads table
- Status updates to "Scraping Complete"
For each lead you want to enrich:
- In Airtable, create automation or button
- Trigger webhook:
?action=EnrichApolloProfiles&recordId={ID} - System scrapes full LinkedIn profile
- Updates lead with 25+ data fields
- Open Google Search Campaigns table
- Add new record:
- Campaign Name: "Agency Founders NYC"
- Job Title: "Founder"
- Company Type: "Marketing Agency"
- Location: "New York"
- CompanySize: "10-50"
- Industry: "Marketing"
- Number Of Leads: 50
- Start Campaign: βοΈ
- System builds Google query automatically
- Searches:
site:linkedin.com/in/ Founder Marketing Agency New York - Handles pagination (20 results per page)
- Extracts LinkedIn profile URLs
- Inserts into Google Search Leads table
- Trigger enrichment for each lead
- Then trigger qualification
- AI scores lead 0-10 based on ICP fit
If you have leads in Aggregated Emails table:
- Ensure lead has:
- Company website
- Title, Headline, About
- ICP Details field populated
- Trigger webhook:
?action=QualifyLeads&recordId={ID} - System extracts website content
- AI analyzes fit against ICP
- Returns score 0-10
- Updates Qualification Score field
Score Interpretation:
- 10: Perfect ICP fit - highest priority
- 8-9: Strong fit - definitely contact
- 7: Good fit - contact-worthy
- 5-6: Moderate fit - investigate further
- 2-4: Weak fit - low priority
- 0-1: Not qualified - skip
Campaign Creation β Lead Scraping β Profile Enrichment β Lead Qualification
β β β β
Apollo/Google Raw Profiles Full LinkedIn Data Scored Leads
Campaigns Table Updated Ready for Outreach
Apollo Campaign
β
Apollo Leads (Basic)
β
Apollo Leads (Enriched) ββββββ Aggregated Emails
β
Google Search Campaign Qualified Leads
β (With Scores)
Google Search Leads (URLs)
β
Google Search Leads (Enriched) βββ Aggregated Emails
1. Apollo Scraper
Actor: (Custom Apify actor)
Endpoint: /v2/acts/[actor-id]/run-sync-get-dataset-items
Parameters:
- url: Apollo search URL
- totalRecords: Number of leads to scrape
- fileName: Output file name
2. LinkedIn Profile Scraper
Actor: dev_fusion~linkedin-profile-scraper
Endpoint: /v2/acts/dev_fusion~linkedin-profile-scraper/run-sync-get-dataset-items
Parameters:
- profileUrls: Array of LinkedIn URLs
POST https://google.serper.dev/search
Headers:
{
"X-API-KEY": "your_api_key",
"Content-Type": "application/json"
}
Body:
{
"q": "site:linkedin.com/in/ Founder Marketing Agency",
"num": 20,
"page": 1
}POST https://api.tavily.com/extract
Headers:
{
"Authorization": "Bearer your_api_key"
}
Body:
{
"urls": ["https://company-website.com"],
"include_images": false,
"extract_depth": "basic"
}The AI uses this system prompt for qualification:
You are a Lead Qualification Analyst. Analyze lead data against ICP.
Return ONLY a number 0-10 representing fit quality.
Input:
- Target ICP (job title, location, company type, size)
- Lead Data (title, headline, about, company details)
- Raw Website Content
Scoring:
- 10: Perfect fit on all criteria
- 7-9: Strong fit
- 4-6: Moderate fit
- 0-3: Weak/no fit
Output: Single integer only.
Error: "Actor not found" or 401 error
Solution:
- Verify Apify token is correct
- Check actor ID is correct in URL
- Ensure sufficient Apify credits
- Test actor directly in Apify console
Error: Empty results from Google Search
Solution:
- Check Serper.dev API key is valid
- Verify search query is constructed correctly
- Try broader search terms
- Ensure Number Of Leads is reasonable (50-100)
Error: "Profile not found" or timeout
Solution:
- Verify LinkedIn URL is valid and public
- Check Apify actor is running
- Increase timeout in HTTP Request node (60s)
- Ensure profile URL format:
linkedin.com/in/username
Error: AI returns text instead of number
Solution:
- Check Gemini API key is valid
- Verify prompt hasn't been modified
- Ensure model is "gemini-2.0-flash"
- Check if website URL is accessible
- Add parsing logic to extract number from response
Error: Campaign starts but workflow doesn't run
Solution:
- Verify workflow is Active in n8n
- Check webhook URL is correct in Airtable automation
- Include
?action=and&recordId=parameters - Test webhook URL manually in browser
- Check n8n execution logs for errors
β Do:
- Start with 50-100 leads per campaign
- Define clear ICP criteria
- Use specific job titles and locations
- Test with small batch first
β Don't:
- Request 1000+ leads at once (rate limits)
- Use vague search terms
- Skip ICP definition
- Forget to activate workflow
β Do:
- Enrich in batches of 50-100
- Verify URLs are public LinkedIn profiles
- Check Apify credits before large batches
- Monitor for failures and retry
β Don't:
- Enrich thousands simultaneously
- Use expired or invalid URLs
- Skip manual spot-checks
- Ignore errors in logs
β Do:
- Define detailed ICP in natural language
- Include company website when possible
- Review AI scores for accuracy
- Adjust ICP based on results
β Don't:
- Use vague ICP definitions
- Qualify without website data
- Trust scores blindly without review
- Skip manual validation of top scores
This project is licensed under the MIT License.
β
Commercial use allowed
β
Modification allowed
β
Distribution allowed
β
Private use allowed
Built with powerful tools:
- n8n - Workflow automation
- Airtable - Database and UI
- Apify - Web scraping
- Serper.dev - Google Search API
- Tavily - Web content extraction
- Google Gemini - AI qualification
- Email verification integration
- CRM direct export (HubSpot, Salesforce)
- Automated outreach sequences
- Duplicate detection across campaigns
- Lead scoring dashboard
- Bulk enrichment interface
- Apollo.io direct API integration
- LinkedIn Sales Navigator scraping
- Company technographics data
- Industry-specific ICP templates
- π§ Email: [email protected]
- π GitHub Issues: Report bugs
Processing Times:
- Apollo scraping: ~2 min per 100 leads
- LinkedIn profile enrichment: ~30 sec per lead
- Google Search: ~1 min per 50 profiles
- AI qualification: ~5 sec per lead
Capacity:
- Apollo: 1,000+ leads/day
- Google Search: 500+ profiles/day
- Enrichment: 2,000+ profiles/day
- Qualification: Unlimited (API dependent)
Made with β€οΈ for B2B Sales & Marketing Teams
β Star this repo if it supercharges your lead generation!
π’ Share with teams who need automated prospecting!
π Fork and customize for your specific needs!
Ready to generate 50,000+ leads? Set up your first campaign and start automating! π