Lead Generation · Data Pipeline AutomationOperational

Automated Lead-Generation Engine

A self-running pipeline that scans public map data for businesses with no website, then enriches each one into a structured, pitch-ready lead — turning hours of manual prospecting into a single automated run.

Role

Solo Builder

Output

2,400+ Leads

Status

Operational

Schema

18-Field Record

Python 3.13OpenStreetMap APIFoursquare APIPandasDocker
Lead generation pipeline overview

Lead-Generation Pipeline · Source → Enrich → Export

2,400+

Businesses identified

1,632

Enriched from OSM tags

18

Fields per lead

0

Duplicates or missing rows

The Problem

Prospecting by hand is the manual step nobody has time for

The businesses that most need a website are the ones you can't easily find — they don't show up in search, they don't run ads, and they rarely appear on the lists a consultant would normally scrape. Building a prospect list for them means clicking through map apps one business at a time, copying names into a spreadsheet, and hoping you don't lose track halfway through.

That manual loop is exactly the kind of work that doesn't get done. It's slow, it's easy to abandon, and by the time a list exists, the moment to reach out has usually passed. The goal of this engine was to remove the loop entirely: point it at a city, walk away, and come back to a finished, qualified list.

My Role

Built end-to-end by one person

I designed the schema, wired up the two public data sources, wrote the enrichment and de-duplication logic, and built the resumable writer that keeps a run safe across interruptions. No separate analyst, no data vendor — the pipeline is the product.

  • 18-Field Enrichment Schema Design
  • OpenStreetMap + Foursquare Source Integration
  • Pain-Signal Tagging (no-website detection)
  • Resumable, De-Duplicated CSV Writer
  • Fill-Rate & Coverage QA with Pandas
  • Docker Packaging for Re-Runs
Architecture

Two public sources, one honest schema

The engine reads from OpenStreetMap's node API and Foursquare's public listings. Where a business has an OpenStreetMap node, the phone, opening hours, and cuisine tags are pulled straight from the record — verified data, not inferred. Businesses that only existed in Foursquare's listings still make the cut, but are flagged as source-only so the record is honest about what's confirmed.

Designing the 18-field schema and the resumable writer before any enrichment ran was the key decision. Because every row is written and flushed immediately, an API outage or a dead laptop mid-run doesn't corrupt the file — the next run skips what's already there and continues. The final QA pass confirmed 100% coverage with zero duplicates.

The Product

How the engine works

SOURCE SCAN
Source scanning from public map data

Pulling businesses from public map data

The engine queries OpenStreetMap's node API and Foursquare's public listings, then filters for businesses that have no website or owned domain — the exact gap that leaves a business invisible to customers already searching for it.

ENRICHMENT
18-field enrichment record

Every lead becomes an 18-field record

Each business is enriched into a structured record: name, city, country, category, phone, hours, services, pain signals, and social links. Where OpenStreetMap carries verified tags, the contact details are pulled directly — not guessed.

EXPORT
Pitch-ready lead export

A resumable, de-duplicated lead list

The output is a single CSV of 2,400+ rows that flushes after every record. If the run is interrupted, it resumes exactly where it stopped — no duplicates, no missing rows. Each row is one specific, named business you can call.

Technical Stack

Under the Hood

Python 3.13

Core language for the pipeline — readable, fast to iterate, easy to maintain.

Requests + OSM API

Fetches OpenStreetMap node records and their verified tags (phone, hours, cuisine).

Foursquare API

Second public source for businesses without an OpenStreetMap node record.

Resumable CSV Writer

Append-only writer with flush-per-row and de-duplication by business + city.

Pandas QA

Validation pass confirming coverage, fill rates, and zero duplicates before handoff.

Docker

Packaged so the run is reproducible and can be scheduled or re-run on demand.

Impact & Reflections

What the engine actually produces

A qualified list, not a raw dump

The output is 2,400+ named businesses, each carrying an 18-field record and a clear pain signal: no website. 1,632 of those came with verified contact details pulled from OpenStreetMap. That's a list specific enough to open a real conversation — "I noticed your shop doesn't have a site yet, and customers are searching for exactly what you do" — instead of a cold blast.

Why this matters for the bigger picture

A business with no website is the precise market for a Digital Presence Builder — an SEO-ready site, web app, or native mobile app. The engine doesn't just demonstrate a data pipeline; it feeds the rest of the work, turning "I should find some prospects" into a finished, prioritized list. It's the same philosophy behind every system here: remove the manual step, keep the human judgement.

Want a pipeline that finds your next customers for you?

Let's talk about the manual step in your business that shouldn't be manual — and the system that removes it.