Local Business Leads from OpenStreetMap
Pricing
from $1.50 / 1,000 business leads
Local Business Leads from OpenStreetMap
Find local businesses by category in any suburb, city or radius from OpenStreetMap open data: name, address, phone, email, website, socials and a lead score. No login.
Pricing
from $1.50 / 1,000 business leads
Rating
0.0
(0)
Developer
Southern Data
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
9 hours ago
Last modified
Categories
Share
Local Business Leads from OpenStreetMap — Google Maps Alternative
Find local businesses in any suburb, city or radius from OpenStreetMap — open data you're allowed to reuse — with phone, email, website and a lead score.
Most "Google Maps scrapers" break Google's Terms of Service, need rotating proxies, and get slower and pricier every month. This Actor takes a different route: it queries OpenStreetMap, the world's largest open map database (10+ million contributors, edited every minute), and licensed under the ODbL — so you can store, combine and reuse the results commercially with simple attribution.
No login. No proxies. No browser.
What to expect
OpenStreetMap coverage is excellent for cafés, restaurants, pubs, shops, dentists and gyms in cities, and patchy for trades (plumbers, electricians) and small towns. Typically 20–40% of mapped businesses have a phone, email or website. Run with Dry run first: it's free and shows exactly how many leads you'll get.
Size guide: a city with up to 10 categories usually finishes in about 1 min (plus about 3 min per 1,000 leads with website checks and email finding). A whole state with up to 5 categories takes about 1–2 min. Bigger requests can take 10+ minutes when the public OpenStreetMap servers are busy, so split them by region. Use "City of Newcastle", not "Newcastle", for the whole council area.
| Request | What the Actor does |
|---|---|
| City, ≤ 10 categories | One OpenStreetMap query (typically under a minute) |
| State / country / radius > 50 km, > 5 categories | Splits automatically into batches of 5 categories, queried one after another, and tells you so in the log |
| Public servers busy | Checks for a free slot, backs off and retries on another mirror (up to 7 attempts); the run status shows "OpenStreetMap server busy … retry 2/6 on …" |
Why use it?
- ✅ Legally reusable data — ODbL open licence, not scraped from a platform that forbids it.
- ⚡ Cheap to run — one query per run (batched for very large areas); no headless browser, no proxy bill.
- 🎯 Precise areas — search inside an official suburb/city/council boundary, or a radius around any point.
- 🧹 Clean, deduplicated rows — one row per business, ranked by a 0–100 lead score (how contactable it is).
- 🚫 Find local businesses without a website: one setting returns businesses with no website, only a Facebook/Instagram/Linktree page, or a dead site. Ideal for web designers and SEO agencies.
- 🌐 Website health check (optional) — finds businesses whose site is down, has a broken HTTPS certificate, or redirects elsewhere. Useful for web-design and SEO agencies.
- 🌏 Worldwide, any script — names in Japanese, Chinese, Cyrillic, Arabic, Thai… are handled correctly. 135 plain-English categories built in (plus synonyms such as hair salon, solicitor, pizzeria), and any raw OSM tag (
shop=florist,craft=electrician,amenity=veterinary…).
Built around what people hate about lead scrapers
We read hundreds of 1–2★ reviews and issues on other lead Actors. These are the top complaints and what this Actor does about them:
| Common complaint | What this Actor does |
|---|---|
| "Charged for 66% unusable leads" / "$14 for 2 emails" | Dry run shows how many leads (and how many with phone/email/website) you'd get before you spend anything. Emails found on websites are charged only when one is actually found. |
| "0 results" with no explanation | Every run prints a funnel (OSM features → named → duplicates → filters → leads) and tells you which filter removed everything. Empty runs cost nothing. |
| "Gave it Queensland, it did all of Australia" / wrong city | The resolved place and its country are shown in the run status before anything is fetched. Genuinely different places with the same name (Newcastle NSW vs UK) are warned about; countryCode pins the country. If your text only matches a suburb, the surrounding city is used (and the log says so) unless you tick Exact location only. |
| "Doesn't pull emails like it says" / junk emails | findEmails visits the homepage + up to 2 contact/about pages, decodes Cloudflare-hidden emails, and tells you where each email was found (emailSource, emailFoundOn). Template placeholders (info@mysite.com, john@gmail.com), web-agency credits ("website by …") and injected spam are filtered out and never charged. No guessed or "pattern" emails. |
| "Asked for 100 leads with email, got 12" | With Required fields = email, Max results counts leads with an email: sites are searched best-first until enough are found. |
| "How can I exclude previous scrapings?" | excludeSeenStore remembers what you've already received — scheduled runs return only new businesses. |
| "I need businesses that don't have a website" / "filter out the ones that already have a site (not just 'no website field')" | websiteFilter: "no_real_website": no website, or only a Facebook/Instagram/Linktree/Yelp/Google Maps page, or (with Check websites) a dead website. See Find local businesses without a website. |
| Duplicates | Node + building-outline duplicates are merged (same name within 150 m, or within 300 m with the same phone or the same branch page). Chain branches that share a brand homepage or a 13xx number stay separate. |
| Slow sites reported as dead | Website check distinguishes live, live_blocked, http_error, tls_error, dead and inconclusive (timeouts are never called "dead"). |
| "Hit my spend limit and got nothing / no explanation" | Each lead is charged together with its enrichment when it is delivered, only if the whole lead fits your max cost per run. If the limit is reached, the status says "Stopped at your max cost per run (US$X): delivered N of M leads". |
Who is it for?
| Use case | How |
|---|---|
| Agencies & freelancers | Find local businesses without a real website (websiteFilter: "no_real_website"), or with a broken one (checkWebsites: true, filter websiteState = dead / http_error / tls_error). |
| B2B sales | Build territory lists — every gym, clinic or café in a council area — and push to your CRM. |
| Franchise / site selection | Map competitor density by suburb. |
| Researchers & journalists | Count and map businesses with an open, citable source. |
| Apps & AI agents | Fresh POI data with lat/lon, opening hours and OSM IDs for linking back. |
Input
| Field | Description |
|---|---|
| Business categories | e.g. cafe, plumber, dentist, real estate agent, or raw tags like shop=florist. Plurals, common synonyms and small typos (resturant) are understood; unknown words are skipped with suggestions (e.g. car → car repair, car wash, car dealer) and listed in the log. |
| Location | e.g. City of Newcastle, NSW, Australia, Brooklyn, New York, Manchester, UK. |
| Exact location only | Off by default: a suburb-only match is widened to its city. Tick to search exactly the place found. |
| Country code | Optional au, gb, us… — stops ambiguous names resolving to the wrong country. |
| Search area | boundary (inside the official boundary — most accurate) or radius. |
| Latitude / Longitude / Radius | For radius mode or when you want an exact centre. |
| Only leads with contact details | On by default — you only pay for businesses you can actually contact. Untick for full market maps. |
| Required fields | Only return rows that have e.g. phone and website. |
| Website filter | any, with_website, without_website (no website listed), or no_real_website (no website, a social/listing page only, or a dead website when Check websites is on). |
| Find emails on business websites | For leads with a website but no email in OSM: homepage + up to 2 contact/about pages, one site at a time. Charged only when an email is found. |
| Check websites are live | One lightweight request per business's own site (social/listing pages are skipped and not charged) → websiteState: live, live_blocked (site exists but blocks bots), http_error, tls_error (broken HTTPS certificate), dead, inconclusive. |
| Max results | Cap the number of leads (and your spend). With Required fields = email it counts leads with an email. |
| Skip leads delivered in earlier runs | A store name such as newcastle-leads; any run using the same name skips businesses you already have. |
| Dry run | Count only: see how many leads match (before and after Max results), how many have phone/email/website, and the estimated cost. Nothing written or charged. |
| Self-test | Health-check mode: runs 13 offline checks (category matching, de-duplication, email cleaning, website-presence rules) plus 3 live checks (geocoding, Overpass, a website fetch). The report is saved as SELF_TEST in the key-value store, and the run fails if any check fails. Nothing is written to the dataset or charged. Pair it with a daily Apify Schedule for a free health check. |
Example input
{"categories": ["cafe", "dentist", "real estate agent", "hairdresser", "craft=electrician"],"location": "City of Newcastle, NSW, Australia","searchMode": "boundary","checkWebsites": true,"maxResults": 150}
Output
Each lead is a flat row (no nested objects), so CSV/Excel exports have one clean column per value:
{"name": "Example Dental Care","branch": null,"category": "dentist","matchedQuery": "dentist","phone": "+61 2 4900 0000","email": "reception@example.com.au","emailSource": "website","emailFoundOn": "https://example.com.au/contact","emailOnOwnDomain": true,"websiteEmails": "reception@example.com.au; accounts@example.com.au","website": "https://example.com.au","websitePresence": "live","fullAddress": "12 Hunter Street, Newcastle, NSW 2300","latitude": -32.9271,"longitude": 151.7765,"openingHours": "Mo-Fr 08:00-17:30; Sa 08:00-12:00","facebook": "https://facebook.com/exampledental","instagram": null,"leadScore": 100,"websiteState": "live","websiteLive": true,"websiteStatusCode": 200,"websiteHttps": true,"websiteFinalUrl": "https://example.com.au/","websiteError": null,"osmUrl": "https://www.openstreetmap.org/node/123456789","googleMapsUrl": "https://www.google.com/maps/search/?api=1&query=-32.9271,151.7765","lastEditedAt": "2026-07-14T03:12:55Z","lastEditedDaysAgo": 109,"duplicateOsmIds": "way/987654321","resolvedLocation": "City of Newcastle, New South Wales, Australia","dataNote": "As mapped in OpenStreetMap — verify before use","attribution": "© OpenStreetMap contributors, ODbL 1.0 — https://www.openstreetmap.org/copyright"}
Open the Leads view for a ready-made table, All columns for a flat export, or Website checks for web-design prospecting, or export to CSV, Excel, JSON, Google Sheets, or your CRM via Zapier / Make / the Apify API. A RUN_SUMMARY record in the key-value store shows the full funnel, the resolved location (and any other places with the same name), and how many leads had a phone, email (from OSM vs. websites) and website.
Find local businesses without a website
Selling websites, SEO or Google Business setup? Set Website filter to no_real_website to get local businesses that don't have a real website of their own. Each row's websitePresence column says why it was included:
websitePresence | Meaning | Needs Check websites |
|---|---|---|
none | No website in OpenStreetMap (but a phone or email, by default) | no |
social_only | The "website" is only a Facebook, Instagram, TikTok, Linktree, Yelp, Google Maps / business.site, Uber Eats, booking-platform… page, or the domain redirects to one | no |
dead | The business's own domain no longer resolves or refuses connections | yes |
broken | The homepage returns 404 Not Found / 410 Gone | yes |
Without Check websites you get none + social_only (fast, and no extra charge). With it, each business's own website is checked once ($0.001 per delivered lead, see Pricing) and kept only if it is dead or broken. Live sites, sites that block bots, sites with certificate problems and sites that time out are not counted as "no website", so you don't pitch a business that actually has a working site. Websites are checked best lead-score first until Max results is reached.
Example: {"categories":["hairdresser","cafe","plumber"],"location":"City of Newcastle, NSW, Australia","websiteFilter":"no_real_website","checkWebsites":true,"maxResults":100}
Honest limits: OpenStreetMap doesn't always list a business's website even when it has one, so none means "no website on the map". Check before you pitch. Sites on free builder subdomains (e.g. *.wixsite.com, sites.google.com) count as real websites.
In the other modes, every row also has websitePresence (none, social_only, not_checked, or live/dead/broken/unknown after a check).
Lead score (0–100)
Name 10 · Phone 25 · Email 25 · Website 20 · Address 10 · Opening hours 10. Results are sorted best-first.
Built-in categories (135)
Food & drink (cafe, restaurant, pub, bakery, brewery…), health (dentist, doctor, physiotherapist, chiropractor, vet…), beauty & fitness (hairdresser, barber, beauty salon, gym, yoga studio…), trades (plumber, electrician, builder, painter, roofer, locksmith, landscaper, mechanic…), professional services (accountant, lawyer, real estate agent, architect, IT company, marketing agency…), retail (florist, jeweller, hardware store, pet store, bicycle shop…), education & childcare, accommodation & tourism, and more. Barber only returns barbers (tagged hairdresser=barber or with "barber" in the name), not every hair salon; church only Christian places of worship. Anything else: use a raw OSM tag (key=value) — see the OSM Map Features wiki.
Honest limitations
- Data is as mapped in OpenStreetMap. Every row says so (
dataNote); phone numbers and hours can be out of date — checklastEditedDaysAgo. - Coverage varies by place and category. OSM is excellent for shops, food, health and tourism in cities; trades that work from home (plumbers, electricians) are often under-mapped. Contact details are present for a share of places, not all — use Only leads with contact details or Required fields to keep only what you need.
- No star ratings or reviews — OSM doesn't store them. If you need Google reviews, use a Google Maps Actor; if you need leads you can legally keep and reuse, use this one.
- Email finding only reads what a business publishes on its own site. It does not guess addresses or buy data, so expect emails for roughly a third to a half of businesses that have a website (varies a lot by industry).
lastEditedDaysAgoshows how fresh each OSM record is — very old records are more likely to have changed phone numbers.- Public Overpass servers are a shared community resource; at busy times a run may wait several minutes and retry automatically (the status shows each retry). For very large jobs you can point Overpass API endpoint at your own instance.
Legal & attribution
Data © OpenStreetMap contributors, available under the Open Database License (ODbL) 1.0. Every row carries the attribution string. If you publish a database built from these results, keep the attribution and share-alike terms of the ODbL. When contacting businesses, follow your local anti-spam laws (e.g. Australia's Spam Act 2003, the US CAN-SPAM Act, GDPR/PECR in the UK/EU).
Pricing
$1.50 per 1,000 leads ($0.0015 per lead), plus $1.00 per 1,000 websites checked (inconclusive checks are free) and $2.00 per 1,000 emails found on websites (no email, no charge). No start fee. Dry runs and empty runs cost nothing. Set a maximum spend per run and the Actor stops cleanly when it's reached.
Feedback
Missing a category or seeing odd data? Open an issue on the Issues tab — we read every one. Spotted wrong data in OSM itself? Fix it at openstreetmap.org and it'll show up in your next run.