How to Get Enriched Google Maps Leads With an AI Agent
A practical resource for Claude Code, Codex, Cursor, Manus, and other agents that need local business leads with owners, emails, phones, websites, and outreach context.
The money in local lead generation is not in the scrape.
The scrape is the first step. It gives you business names, phone numbers, websites, categories, ratings, and addresses. That is useful, but it is not enough to sell web design, SEO, ads, reputation management, recruiting, software, or any other local service at scale.
The money comes from what happens next:
- finding the businesses that match a real offer
- knowing who owns or runs them
- finding usable emails and phone numbers
- understanding what is weak about their website or online presence
- writing outreach that references something specific
- exporting everything into a CRM or cold email workflow
That is where Claude Code becomes interesting. Claude can write scripts, filter data, build CSVs, generate personalization, and wire the output into your stack. But it still needs one thing before it can help: a reliable lead source with data an AI can actually reason about.
LocalProspects is that lead gen skill.
You give Claude a simple markdown skill file. After that, it can search for local businesses, wait for enrichment, inspect the fields, filter the best prospects, and save a CRM-ready export from a plain English request.
The lead gen workflow that actually matters
Most people think the workflow is:
- Scrape a city and niche.
- Export a spreadsheet.
- Send a generic email.
That works poorly because the list is too raw. A roofing company with 400 reviews, a claimed profile, a modern website, and no visible owner is not the same lead as a roofing company with 18 reviews, no analytics, a broken WordPress site, and an owner name on the About page.
The workflow you want Claude to run looks more like this:
- Search a niche and location.
- Enrich every business with contact, website, owner, tech, and service data.
- Score the businesses against the offer.
- Filter out bad targets.
- Generate outreach using real context.
- Export the results to Instantly, GoHighLevel, HubSpot, Airtable, Google Sheets, or a custom CRM.
That is the difference between "I scraped 1,000 leads" and "I have 125 businesses that match my offer, have reachable contacts, and have a reason to take the call."
What Claude needs to know
For Claude Code to do useful lead gen work, it needs more than a CSV download. It needs a clear map of the whole system:
- Lead source: where the businesses come from
- Search inputs: niche, city, region, location code, result limits
- Authentication: how to call the API without exposing the key
- Job lifecycle: whether results are immediate or async
- Field schema: which fields exist and what they mean
- Enrichment depth: whether the tool only returns listings or also reads websites
- Contact quality: whether emails and phones are verified or just scraped
- Personalization fields: services, tech stack, owner names, review data, website copy
- Export rules: which fields should become CSV columns
- Outreach guardrails: do not invent facts, do not use invalid emails, do not send without approval
A markdown skill file is a good format for that. Claude reads it like project instructions, then follows the same sequence every time.
The alternatives: what most tools give you
There are plenty of ways to get local business lists. The important question is not "can it scrape leads?" The question is "does it return enough structured context for an AI agent to decide what to do next?"
Here is the practical map.
| Tool | Best for | What Claude gets | What is usually missing |
|---|---|---|---|
| Outscraper | raw Google Maps-style business exports at low per-record cost | names, categories, phones, websites, ratings, addresses, export/API access | owner names, verified emails, phone type, multi-page website text, service extraction, AI-ready business summaries |
| D7 Lead Finder | classic lead finder searches with emails, social links, and some website flags | business names, phone, website, email, address, review fields, social URLs, WordPress/pixel/analytics flags | deeper website crawl, owner extraction, email quality scoring, phone carrier/type, richer service and selling-point fields |
| Apify Google Maps actors | flexible scraping infrastructure and actor-based workflows | place records, reviews, images, optional contact-detail scraping depending on the actor/settings | one consistent enrichment schema, owner names, verified outreach fields, opinionated CRM export mapping |
| Google Places-style APIs | application features that need place data | official place identifiers, names, addresses, ratings, location data | outreach-specific enrichment, website crawl, owner names, emails, phone intelligence, personalization context |
| DIY scraper | maximum control when you have engineering time | whatever you build | maintenance, blocking, dedupe, retries, enrichment, verification, schema design, CSV mapping |
| LocalProspects | AI-assisted local prospecting and outreach prep | search plus owner names, verified emails, phone type, tech stack, website pages, services, summaries, socials, CRM export fields | not meant for generic map-app features; it is built around prospecting and enrichment |
Outscraper, D7, Apify, and DIY scripts can all get you some version of "local businesses in a city." That is not the hard part anymore.
The hard part is producing data Claude can use to make a good decision:
- Which businesses are worth contacting?
- What should the pitch be?
- Is there a person to address?
- Is the email usable?
- Is the phone likely mobile, landline, VoIP, or unknown?
- What website weakness or business context can the outreach reference?
- Which records should be excluded before they hit the CRM?
That is why LocalProspects is different. It is not just a list provider. It returns the enrichment layer Claude needs for filtering, scoring, personalization, and exports.
Where LocalProspects fits
| Layer | What Claude gets | How it is collected |
|---|---|---|
| Listing data | business name, category, website, address, phone, rating, review count, rank, claimed status, location | pulled from the local business search result |
| Website identity | official name, business type, address, phone, email, schema.org data | extracted from the business website and structured metadata |
| Website pages | page URLs, titles, meta descriptions, visible text, contact details | crawled from the homepage and useful internal pages like contact, about, team, and service pages |
| Owner signal | owner, founder, principal, or manager name when available | checked from business records and extracted from website copy when explicitly stated |
| Emails | all discovered emails plus a promoted best email | collected from website pages and metadata, deduped, then verified |
| Email quality | verified, catch-all, invalid, or unverified status; role-based and free-provider flags | checked through domain mail records and mailbox verification where possible |
| Phones | listing phone plus discovered website phones | normalized, deduped, and enriched with line type and carrier when available |
| Web presence | social profiles, logo, blog presence, meta description, theme color | extracted during the website crawl |
| Tech stack | CMS, CDN, server, chat tools, analytics, ad pixels, frameworks, other detected tools | detected from website markup and technical fingerprints |
| Services | services, specialties, service areas, selling points, customer type, year established, employee hints | extracted from website text and structured into outreach-friendly fields |
This is the data Claude wants. Not because it is more data for its own sake, but because each field maps to an action.
If you sell websites, Claude can look for outdated CMS choices, missing analytics, thin pages, weak metadata, or no blog.
If you sell SEO, Claude can look at categories, service areas, review counts, website copy, and local positioning.
If you sell paid ads, Claude can look for businesses with enough reviews and service pages but no obvious ad or analytics stack.
If you sell recruiting, software, bookkeeping, insurance, or any other local B2B service, Claude can use the business summary, services, employee hints, owner signal, and contact quality to build a tighter target list.
How this turns into money
The simplest agency workflow looks like this:
- Pick a niche with a clear pain point, like roofers, dentists, med spas, HVAC companies, or personal injury attorneys.
- Pick a city or region.
- Ask Claude to run the LocalProspects skill.
- Filter for businesses with a reason to buy: weak tech stack, no analytics, low review count, unclaimed profile, missing blog, thin service pages, or poor contact quality.
- Generate one or two personalized lines per lead.
- Export the list to your outreach system.
- Track replies, booked calls, and closed deals.
You can also package the output as a product:
- a niche lead list with verified contacts
- a local market map for an agency client
- a website audit spreadsheet
- a competitor intelligence report
- a weekly "new prospects in this city" feed
- a CRM enrichment job for an existing list
The key is that Claude is not just scraping. Claude is operating the workflow: gathering data, interpreting it, and producing the next artifact you can use to sell.
Example Claude prompts
Once the skill is installed, you can ask for outcomes instead of individual API steps.
Find med spas in Scottsdale. Keep businesses with websites, owner names, or verified emails. Add a personalization field based on their services or website copy. Export the top 100.
Find roofers in Tampa with 20+ reviews and no obvious analytics stack. Create a CSV for a website audit campaign.
Search dentists in Austin. Filter out chains, keep owner-led practices, and write a first line that references their services, reviews, or website.
Enrich these 10 business domains and tell me which ones are best for a cold email campaign.
This is the real value of the skill: Claude can move from "get data" to "prepare a campaign."
Paste this skill into Claude Code
Save the following as CLAUDE.md in a project, paste it into Claude Code's instructions, or adapt it for any coding assistant that reads markdown skill files.
# LocalProspects Lead Generation Skill
You can use LocalProspects to search for local businesses, enrich them with contact and website intelligence, and export the results to CSV.
## When to use this skill
Use this skill when the user asks for local lead generation, local business research, prospect lists, agency prospecting, CRM enrichment, owner-name research, verified business emails, local outreach lists, or website-intelligence reports.
Examples:
- "Find roofers in Tampa and export them to CSV."
- "Get dentists in Austin with owner names and verified emails."
- "Build a prospect list of med spas in Scottsdale."
- "Find local businesses running WordPress with no obvious analytics."
- "Enrich these business domains with contact data."
## Authentication
All API requests require an `x-api-key` header.
Ask the user for their LocalProspects API key before making requests. The key starts with `lp_`.
Base URL:
```text
https://localprospects.ai
```
Header:
```text
x-api-key: lp_your_key_here
```
## Main workflow: search and enrich local businesses
### Step 1: Find the location code
Search requires a `location_code`. Look it up by city or region first.
```bash
curl -s "https://localprospects.ai/api/v1/locations?q=Austin" \
-H "x-api-key: <API_KEY>"
```
Response shape:
```json
{
"locations": [
{
"location_code": 1026201,
"name": "Austin",
"region": "Texas",
"country": "US",
"type": "City",
"full_name": "Austin, Texas, US"
}
]
}
```
Pick the best matching city or region. Prefer US city matches when the user gives a US city.
### Step 2: Start the search
Start a search with a business category keyword and the selected `location_code`.
```bash
curl -s -X POST "https://localprospects.ai/api/v1/search" \
-H "Content-Type: application/json" \
-H "x-api-key: <API_KEY>" \
-d '{
"keyword": "plumber",
"location_code": 1026201
}'
```
The response returns a `job_id` and initial business counts. Enrichment continues asynchronously.
Important behavior:
- Searches require enough lead credits to run.
- Credits are based on businesses found and enriched.
- The initial response may include basic listing data.
- Do not treat the initial response as the final enriched result.
### Step 3: Poll the job
Poll every 5 seconds until `status` is `completed`.
```bash
curl -s "https://localprospects.ai/api/v1/job/<JOB_ID>" \
-H "x-api-key: <API_KEY>"
```
While the job is running, expect progress fields like:
```json
{
"job_id": "job-id",
"status": "enriching",
"total_businesses": 62,
"enriched_count": 30,
"failed_count": 2,
"progress": 51
}
```
### Step 4: Fetch completed results
When the job is complete, fetch the enriched businesses.
```bash
curl -s "https://localprospects.ai/api/v1/job/<JOB_ID>/results" \
-H "x-api-key: <API_KEY>"
```
Response shape:
```json
{
"businesses": [
{
"name": "Example Plumbing",
"category": "Plumber",
"website": "https://example.com",
"owner": "Jane Smith",
"summary": "Short business intelligence summary.",
"email": "jane@example.com",
"phone": "(512) 555-0101",
"phone_type": "mobile",
"contact": {
"address": "100 Main St, Austin, TX",
"city": "Austin",
"state": "Texas",
"state_code": "TX",
"lat": 30.2672,
"lng": -97.7431,
"all_emails": [
{
"email": "jane@example.com",
"status": "verified",
"is_role_based": false,
"is_free_provider": false
}
],
"all_phones": [
{
"number": "(512) 555-0101",
"line_type": "mobile",
"carrier": "T-Mobile"
}
]
},
"reputation": {
"rating": 4.8,
"reviews": 124,
"review_snippet": "Great service...",
"is_claimed": true
},
"services": {
"list": ["Drain Cleaning", "Water Heater Repair"],
"specialties": ["Emergency Plumbing"],
"areas": ["Austin", "Round Rock"],
"selling_points": ["24/7 Service", "Licensed & Insured"],
"customer_types": "both",
"year_established": 2015,
"employees": "10+"
},
"web": {
"tech": {
"cms": "wordpress",
"cdn": "cloudflare",
"server": null,
"chat": null,
"analytics": ["google_analytics"],
"frameworks": [],
"advertising": ["facebook_pixel"],
"other": []
},
"socials": {
"facebook": "https://facebook.com/example"
},
"has_blog": false,
"meta_description": "Austin plumbing company...",
"pages_crawled": 4,
"pages": [
{
"url": "https://example.com/about",
"title": "About Example Plumbing",
"meta_description": null,
"text": "Visible page text..."
}
]
}
}
]
}
```
## What each enrichment layer means
Use these fields when analyzing, filtering, or exporting results.
### Listing data
Fields: `name`, `category`, `additional_categories`, `website`, `phone`, `rank`, `reputation.rating`, `reputation.reviews`, `reputation.review_snippet`, `reputation.is_claimed`, `contact.address`, `contact.city`, `contact.state`, `contact.lat`, `contact.lng`.
Use for market sizing, territory filtering, review-based scoring, and basic CRM fields.
### Identity data
Fields: `owner`, `summary`, `services.year_established`, `services.employees`, `services.customer_types`.
Use for owner-led outreach, account research, and lead scoring.
Owner names come from business-record lookups when available and from explicit website statements when the website names an owner, founder, principal, or manager. Do not guess an owner from an email address, domain name, or business name.
### Email data
Primary field: `email`.
All emails: `contact.all_emails[]`.
Email statuses:
- `verified`: mailbox or domain checks indicate the email is likely usable
- `catch-all`: domain accepts broad mail, so the address may work but is less certain
- `invalid`: email should not be used
- `unverified`: not enough signal to confirm
Prefer non-role-based verified emails for outreach. Avoid invalid emails.
### Phone data
Primary fields: `phone`, `phone_type`.
All phones: `contact.all_phones[]`.
Common line types:
- `mobile`
- `landline`
- `voip`
- `toll_free`
- `unknown`
Use `mobile` for SMS workflows only when the user explicitly wants SMS-ready records. Otherwise, preserve all phone numbers in the export.
### Website and tech data
Fields: `web.tech`, `web.socials`, `web.has_blog`, `web.meta_description`, `web.pages_crawled`, `web.pages`.
Use these fields for:
- website audit targeting
- WordPress, Wix, or Squarespace segmentation
- analytics and ad-pixel detection
- personalization from page text
- identifying businesses with weak or thin web presence
### Service data
Fields: `services.list`, `services.specialties`, `services.areas`, `services.selling_points`.
Use for outreach personalization and niche segmentation.
Examples:
- target emergency plumbers
- find cosmetic dentists
- isolate roofers that mention storm damage
- write first lines based on service areas
## Optional workflow: enrich known domains
If the user already has business domains, use `/api/v1/enrich` instead of search.
Maximum: 10 leads per request.
```bash
curl -s -X POST "https://localprospects.ai/api/v1/enrich" \
-H "Content-Type: application/json" \
-H "x-api-key: <API_KEY>" \
-d '{
"leads": [
{
"domain": "https://example.com",
"business_name": "Example Plumbing",
"city": "Austin",
"state": "TX",
"country_iso_code": "US"
}
]
}'
```
Use this when the user provides an existing list and wants owner names, verified emails, phones, services, tech stack, socials, and website intelligence.
## CSV export
When the user asks for a CSV, flatten each business into one row.
Use this exact header order:
```csv
Google Maps Rank,Name,Category,Website,Owner,Email,Phone,Phone Type,Address,City,State,Rating,Reviews,Review Snippet,Claimed,Socials,Logo URL,Main Image URL,Email 1,Email 1 Status,Email 2,Email 2 Status,Email 3,Email 3 Status,Email 4,Email 4 Status,Email 5,Email 5 Status,Phone 1,Phone 1 Type,Phone 1 Carrier,Phone 2,Phone 2 Type,Phone 2 Carrier,Phone 3,Phone 3 Type,Phone 3 Carrier,Phone 4,Phone 4 Type,Phone 4 Carrier,Phone 5,Phone 5 Type,Phone 5 Carrier,Page 1 URL,Page 1 Title,Page 1 Meta,Page 1 Text,Page 2 URL,Page 2 Title,Page 2 Meta,Page 2 Text,Page 3 URL,Page 3 Title,Page 3 Meta,Page 3 Text,Page 4 URL,Page 4 Title,Page 4 Meta,Page 4 Text,Page 5 URL,Page 5 Title,Page 5 Meta,Page 5 Text
```
Mapping rules:
- `Google Maps Rank`: `rank`
- `Name`: `name`
- `Category`: `category`
- `Website`: `website`
- `Owner`: `owner`
- `Email`: `email`
- `Phone`: `phone`
- `Phone Type`: `phone_type`
- `Address`: `contact.address`
- `City`: `contact.city`
- `State`: `contact.state_code` or `contact.state`
- `Rating`: `reputation.rating`
- `Reviews`: `reputation.reviews`
- `Review Snippet`: `reputation.review_snippet`
- `Claimed`: `reputation.is_claimed`
- `Socials`: JSON-stringified `web.socials`
- `Logo URL`: `logo`
- `Main Image URL`: `main_image`
- `Email 1-5`: first five entries from `contact.all_emails`
- `Email 1-5 Status`: each email's `status`
- `Phone 1-5`: first five entries from `contact.all_phones`
- `Phone 1-5 Type`: each phone's `line_type`
- `Phone 1-5 Carrier`: each phone's `carrier`
- `Page 1-5 URL`: first five entries from `web.pages[].url`
- `Page 1-5 Title`: first five entries from `web.pages[].title`
- `Page 1-5 Meta`: first five entries from `web.pages[].meta_description`
- `Page 1-5 Text`: first five entries from `web.pages[].text`
Save the CSV locally using a descriptive file name like:
```text
<keyword>-<city>-localprospects.csv
```
What Claude can do after the skill is installed
Once Claude has those instructions, the user can make higher-level requests instead of walking through each API call manually.
For example:
Find HVAC companies in Dallas, keep only businesses with at least 30 reviews, and export the ones with owner names or verified emails.
Claude can resolve Dallas, run the search, wait for enrichment, filter by reputation.reviews, check owner and email, and write the final CSV.
Or:
Find dentists in Phoenix whose websites run WordPress and write a first-line personalization field for each.
Claude can use web.tech.cms, web.pages, services.list, and summary to build a more useful export than a basic name-phone-address list.
Why this works better than prompt-only lead gen
Prompt-only lead gen breaks because the assistant has no stable source of truth. It can write search queries, scrape random pages, and make a spreadsheet, but every run is a little different.
A skill file gives Claude a contract:
- the API endpoint is fixed
- the authentication method is clear
- the polling loop is documented
- the output schema is known
- the CSV columns are already decided
That lets Claude focus on the parts AI is good at: filtering, classifying, summarizing, writing outreach angles, and turning structured data into useful workflow artifacts.
The takeaway
The practical version of "Claude lead gen" is not asking an assistant to browse around and improvise a list. It is giving Claude a specific skill: search local businesses, enrich them, understand the fields, and export the result.
LocalProspects provides the data access. The skill file tells Claude how to use it. Together, they turn a coding assistant into a local business research agent you can run from a project folder.
Get an API key, paste the skill into CLAUDE.md, and Claude can start building enriched local prospect lists from plain English requests.