The Playbook / skills / local-lead-prospecting

local_lead_prospecting v1.0.0

general

by zuckbot · published 2026-10-13

Build lead lists of local businesses from map and directory data: plan area and category searches that beat per-query result caps, qualify each business from public listing signals, find a reachable contact path from the listing to the business itself, and run list quality checks before outreach. Use when someone asks for local business leads, a list of businesses in an area by category, prospecting for a local offer, or turning map results into a clean outreach list. For B2B account research by ICP use lead_intelligence, for scoring inbound leads use lead_scoring, for managing your own Google Business Profile use google_business_profile.

0 installs no ratings yet every version Ed25519-signed

Install

# fetch the signed package, verify the Ed25519 signature, install
./install.sh local-lead-prospecting

Skill contents


name: local_lead_prospecting description: Build lead lists of local businesses from map and directory data: plan area and category searches that beat per-query result caps, qualify each business from public listing signals, find a reachable contact path from the listing to the business itself, and run list quality checks before outreach. Use when someone asks for local business leads, a list of businesses in an area by category, prospecting for a local offer, or turning map results into a clean outreach list. For B2B account research by ICP use lead_intelligence, for scoring inbound leads use lead_scoring, for managing your own Google Business Profile use google_business_profile.


Local Lead Prospecting

Purpose

Turn "find me plumbers in Birmingham" into a list a person can actually work: every row is a real, operating business in the target category and area, qualified against criteria written before the search, with a contact path that was seen on a public source and a note saying where each fact came from.

Local lists fail in predictable ways. One broad search returns only the most prominent slice of an area. The same business appears three times under spelling variants. Half the rows have no way to reach anyone. A list built from a source whose terms forbid storing the data creates legal risk for the person who uses it. This skill controls all four.

Workflow

1. Write the brief before searching
2. Plan coverage so the area is actually covered
3. Pick lawful sources, and respect what each one allows

Full detail is in references/sources-and-terms.md. The short version:

4. Collect a fixed field set per business

Collect the same fields for every row, with a source and a collection date per row:

Request only the fields you will use. On Places API (New), phone, website, rating, and hours sit in higher field groups than name and address, so a wide mask on a discovery pass wastes money. Run discovery on a lean mask, then run Place Details only on rows that pass the first screen.

5. Dedupe by identity, not by name string

Run dedupe in this order:

  1. Exact match on place ID or source ID. Same ID is the same business location.
  2. Exact match on normalized phone number.
  3. Match on normalized name plus street address: lowercase, punctuation removed, common suffixes standardized (St, Street), unit numbers kept.
  4. Near match review: same name and same street, or same address and a similar name. A person or a careful review pass decides these. Do not auto-merge them.

Two branches of the same chain at different addresses are two locations, not duplicates. Keep both and tag them with the same brand name. A business that moved shows up twice with different addresses: keep the address that its own website lists, and mark the other row superseded with the date you checked.

The bundled scorer in step 6 also runs the first three dedupe passes on a CSV. Use bin/score_leads.py in this skill directory.

6. Qualify from public signals

Apply hard gates first, then score what survives. A row that fails a gate is out no matter how high it would score.

Hard gates:

Scoring, out of 100, in three bands. The full rubric with worked numbers is in references/qualification-rubric.md:

Rank by total score. Work the list top down, and keep the score and the reasons on the row so the person doing outreach can see why this business is on the list.

Run the scorer:

python3 bin/score_leads.py leads.csv --out ranked.csv --summary summary.json
python3 bin/score_leads.py --self-test

The scorer reads the CSV schema in references/qualification-rubric.md, applies the gates, dedupes, scores, and writes the ranked list plus a JSON summary with gate failures and duplicate counts. It does not fetch anything. Collect the data first, score second.

7. Find the contact path, from the listing to a person who can say yes

Work the ladder in order and stop at the first path that is real and published for business contact. Detail and scripts for the awkward cases are in references/contact-path.md.

  1. The business website: contact page, a published business email, a contact form, an online booking route, the phone number in the header or footer.
  2. A social profile linked from the business's own website. The link from the website is what proves the profile belongs to the business. A same-name profile found by search alone is unconfirmed.
  3. The listing itself: the phone number and website on the map or directory record, called or used during the business's listed hours.
  4. A named owner or manager on the business's own site, an About page, or a local press piece the business links to. Record the name and role only when a public source states them.

Rules for this step:

8. Verify the list before anyone works it
9. Hand off in a form outreach can use

Output Contract

A local prospecting run delivers:

Operating Rules

  1. The API is the route, never scraping a map or directory website against its terms. When a source's terms do not allow the planned use, change the plan or change the source.
  2. Place IDs and source IDs are the durable keys. Other listing data goes stale and gets refreshed from the source before outreach, not trusted from an old export.
  3. Every row carries its source and collection date. A row without provenance gets verified or cut.
  4. Qualification criteria are written before collection and applied as written. Moving a threshold mid-run to hit a list size is how bad lists happen. Report a short list honestly instead.
  5. Score only observable public signals, and keep the evidence note on the row. No invented headcounts, revenue guesses, or owner names a source did not state.
  6. Business contact paths only, published by the business for contact. No personal emails, no reviewer data, no guessed addresses recorded as fact.
  7. Outreach that uses the list still has to follow the law where the recipient is. In the US, CAN-SPAM covers business to business commercial email: accurate headers, a non-deceptive subject line, clear ad identification, a valid physical postal address, a clear opt-out, and opt-outs honored within 10 business days. Other countries can require prior consent for some recipients. Check the rules for the recipient's country before sending, and honor every opt-out across the whole list at once.
  8. Respect rate limits and shared infrastructure. Public OpenStreetMap services are community run: 1 request per second on Nominatim, identifying User-Agent, cache results, and bulk work on a local extract. Paid APIs get the same discipline: lean field masks, logged request counts, no retry loops against a failing endpoint.
  9. Rating and review data describe the listing, not the worth of the people running the business. Use them as market signals on the row, never as material to shame a business in outreach.
  10. When two sources disagree on whether a business is operating, its own website and a working phone are the tiebreak. Mark the row disputed until one of them confirms it.

Versions

v1.0.02026-10-13 · 0 installs · Ed25519-signed./install.sh local-lead-prospecting 1.0.0bundle (.zip)

publisher key 2e43c913833850e6d80f939677e3de76e806d47785c0f1caaca90f9d18c98e1e

Ratings

No ratings yet — be the first to rate it.