Local Business Leads — Phones & Emails by City
Pricing
from $4.00 / 1,000 business founds
Local Business Leads — Phones & Emails by City
Local businesses by category + city via OpenStreetMap (no Google API). Phones, websites, addresses; optional email enrich. PPE $0.004/business-found. Companions: gary_sells/domain-contact-finder · gary_sells/domain-emails-fast · gary_sells/maps-business-contact-enricher.
Pricing
from $4.00 / 1,000 business founds
Rating
0.0
(0)
Developer
Industrial AI
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
3 days ago
Last modified
Categories
Share
Local Business Leads — Phones, Websites & Emails by City
When to call this Actor
Use when a human or agent needs local business leads by category + place (phones / websites / optional emails):
- "Find plumbers in Austin with phone numbers"
- "List cafes near Brisbane CBD"
- "Get dentist leads in Prague with websites"
- "Local restaurant leads in Berlin with emails"
Do not use for: Google Maps unofficial scrapes (this Actor uses OpenStreetMap public data — no Google API key, no Maps CAPTCHA), LinkedIn / Sales Nav, inbox scraping, login walls, or people-search APIs.
Prefer Domain Contact Finder / Domain Emails Fast when you already have a domain list and only need site crawl enrichment.
Why OSM (not Google Maps)
- Ships on Cheerio + public HTTP — no Playwright CAPTCHA farm
- No Tim Google API key required for v1
- Phones / websites / addresses often present on OSM tags
- Optional Cheerio email enrich from public business websites
- Anonymous Store–safe, no LinkedIn ToS landmines
Agent quickstart
Input (prefer): { "category": "plumber", "location": "Austin, TX", "maxResults": 25 }
Optional: "enrichEmails": true to crawl websites for public emails
Output: one dataset item per business → name, phone, website, emails, address, lat, lon, osmId
Example prompts → input
| User says | Pass |
|---|---|
| Find cafes in Austin | category: "cafe", location: "Austin, TX" |
| Plumbers in Brisbane with emails | category: "plumber", location: "Brisbane, Australia", enrichEmails: true |
| 10 dentists near Prague | category: "dentist", location: "Prague", maxResults: 10 |
| Custom OSM tag in a bbox | category: "shop=bicycle", bbox: "50.0,14.3,50.1,14.5" |
Pricing (PPE): business-found once per business pushed; email-enriched once per business that has ≥1 email (from OSM tags or website enrich). Do not charge apify-default-dataset-item.
What this Actor does
- Resolves
categoryto OSM tags (friendly names or rawkey=value) - Geocodes
locationvia public Nominatim (or usesbbox) - Queries Overpass API for matching nodes/ways in the area
- Emits name, phone, website, address, coordinates from OSM tags
- Optionally Cheerio-crawls business websites for public emails
Stack: Node.js + Crawlee CheerioCrawler + Apify SDK PPE. usesStandbyMode: false.
Input
| Field | Type | Default | Description |
|---|---|---|---|
category | string | cafe | Friendly name (plumber, dentist, …) or OSM filter (amenity=restaurant) |
location | string | — | City/area for Nominatim geocode (required unless bbox) |
bbox | string | — | Optional south,west,north,east — skips geocode |
radiusKm | integer | 5 | Search radius around geocoded point (1–50) |
maxResults | integer | 25 | Cap on businesses returned (1–500) |
enrichEmails | boolean | false | Cheerio-crawl websites for public emails |
maxPagesPerWebsite | integer | 3 | Paths per site when enriching |
requirePhoneOrWebsite | boolean | true | Drop listings with neither phone nor website |
proxyConfiguration | object | Proxy off | Used only for website email enrich |
Example input
{"category": "cafe","location": "Austin, TX","radiusKm": 5,"maxResults": 10,"enrichEmails": false,"requirePhoneOrWebsite": true,"proxyConfiguration": { "useApifyProxy": false }}
Output
One item per business:
{"name": "Example Cafe","category": "cafe","phone": "+1-512-555-0100","website": "https://example-cafe.com/","emails": ["hello@example-cafe.com"],"address": "123 Main St, Austin, TX","city": "Austin","lat": 30.2672,"lon": -97.7431,"osmType": "node","osmId": "123456","status": "ok","error": null}
Pricing (Pay-per-event)
Suggested Store pricing (configure in Apify Console → Actor → Monetization — Tim/Gary):
| Event | When charged | Suggested price |
|---|---|---|
business-found (primary) | Once per business pushed to the dataset | $0.004 each (~$4.00 / 1,000) |
email-enriched | Once per business that has ≥1 email (OSM tag or website crawl) | $0.002 each (~$2.00 / 1,000) |
Console checklist
- Set the two PPE events above; remove or zero
apify-default-dataset-item - Keep PPE only — PPE + usage pass-through OFF
- Limited permissions
- Standby OFF (
usesStandbyMode: false)
Cost example
- 1,000 cafes discovery-only → ~$4.00 on
business-found - Same run with
40% email hit rate → +**$0.80** onemail-enriched
For AI agents / MCP
- Actor name:
gary_sells/local-business-leads - Prefer input fields:
category+location - PPE events:
business-found,email-enriched - Constraints: public OSM + public HTML only — no Google Maps unofficial scrape, no LinkedIn, no login/CAPTCHA bypass
- Discoverable via Apify Store / MCP
search-actorsonce published with PPE-only + Limited permissions + Standby off
API & agent usage
curl "https://api.apify.com/v2/acts/USERNAME~local-business-leads/runs" \-H "Authorization: Bearer $APIFY_TOKEN" \-H "Content-Type: application/json" \-d '{"category":"cafe","location":"Austin, TX","maxResults":10}'
Local PPE dry-run:
$ACTOR_TEST_PAY_PER_EVENT=true apify run -p
Inspect storage/datasets/charging_log/ for charged events (local default price $1/event).
Legal & ethics disclaimer
This Actor collects publicly available OpenStreetMap data and (optionally) public website HTML. It does not call Google Places/Maps APIs, bypass logins/CAPTCHAs, or access private directories.
You are responsible for complying with applicable laws (including GDPR/CCPA where relevant), OSM usage policies, website terms, and anti-spam rules (e.g. CAN-SPAM). Use contact data only for lawful purposes. The authors provide no warranty and accept no liability for misuse.
Respect Nominatim and Overpass usage policies (polite User-Agent, reasonable rate).
How it works (technical)
- Discovery: Nominatim geocode → Overpass
[out:json]for category tags in bbox - Enrich: optional
CheerioCrawleron/,/contact,/aboutpaths - PPE:
Actor.charge({ eventName: 'business-found' | 'email-enriched' }); stops oneventChargeLimitReached - Permissions: Designed for limited Actor permissions. No Standby mode.
Local development
cd local-business-leadsnpm installnpm testnpm run dry-run
Deploy (after apify login):
$apify push --force --wait-for-finish
Then Tim/Gary set PPE prices and keep Limited permissions in Apify Console (do not auto-publish from CI).
Changelog
- 1.0.0 — Initial Store-ready release: OSM local discovery, optional Cheerio email enrich, PPE
business-found+email-enriched, agent/MCP findability.