Automation · Python · B2B Pipeline
Automated B2B prospecting infrastructure — from raw domain list to scored, enriched lead in CRM with zero manual steps. Multi-source discovery, API-based enrichment, qualification scoring, and sequenced outreach running as an async Python pipeline.
Sales teams burn hours per day on manual prospecting tasks that are structurally automatable: finding companies that match ICP, enriching contact data from multiple sources, scoring leads for fit, and queuing them for outreach. Each step is routine enough to have deterministic rules — but complex enough that no single off-the-shelf tool covers the full chain. The result is a broken manual handoff between tools that should be one pipeline.
The system treats lead generation as a data pipeline problem: structured ingestion, deterministic transformation stages, scored output. Each stage is independently replaceable. The enrichment layer is pluggable — swap API providers without touching scoring or outreach logic.
Playwright-based scraping for niche directories and job boards as ICP signals. Structured parsers for CSV exports from LinkedIn Sales Navigator and Apollo. Each source produces a normalized ProspectRaw record.
Async HTTP fan-out to enrichment APIs (Clearbit / Hunter / Prospeo) with exponential backoff and per-provider rate limiting. Merges partial records from multiple providers into a single enriched contact. Missing fields degrade gracefully — don't block scoring.
Weighted scoring model over enriched fields. Configurable ICP rules in YAML — no code change to adjust weights or add signals. Outputs a QualificationScore with per-dimension breakdown so you can see why a lead ranked as it did.
Each lead exits the pipeline with a composite score and per-signal breakdown. Example output for a SaaS company in the target ICP:
| Signal | Weight | Value | Outcome |
|---|---|---|---|
| Company size (11–200 employees) | 25% | 47 employees | PASS |
| Tech stack match (Node / Python / React) | 30% | 3/3 match | PASS |
| Recent funding signal | 20% | Seed (18mo ago) | REVIEW |
| Decision-maker reachable | 15% | CTO email verified | PASS |
| Competitor tool usage | 10% | No signal | MISS |
Concurrent API calls per lead vs. sequential. Enrichment is I/O-bound — asyncio + httpx cuts per-lead latency from ~4s to ~0.8s when hitting 3 providers simultaneously.
Scoring weights and ICP criteria live in config, not code. Sales ops can adjust qualification rules without a deploy. Version-controlled alongside pipeline code.
Missing enrichment data scores that dimension as zero rather than blocking the pipeline. A lead with partial enrichment still enters scoring — incomplete data is a signal, not a failure.
Per-provider API rate limits enforced in Redis — not in application state. Survives process restarts. Prevents accidental 429s burning API credits mid-run.
Every pipeline stage has typed I/O contracts. ProspectRaw → EnrichedContact → QualifiedLead. Schema mismatches fail loudly at stage boundaries, not silently downstream.
SHA-256 hash of normalized domain + email checked against existing CRM records before insert. Prevents duplicate outreach without full-table scans on every insert.
Drop PNG screenshots into images/projects/lead-gen-*.png — they'll appear here automatically.