Businesses Without Websites: No-Website Leads (OpenStreetMap)
Pricing
from $3.00 / 1,000 business founds
Businesses Without Websites: No-Website Leads (OpenStreetMap)
Find local businesses with no website, a dead website or only a Facebook/Instagram page in any city: dentists, salons, restaurants, shops and 35+ niches. Phone (E.164), email and address from OpenStreetMap, chains filtered out. Leads for web designers and agencies. $3 per 1,000 leads.
Pricing
from $3.00 / 1,000 business founds
Rating
0.0
(0)
Developer
Catalin Friptu
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
6 hours ago
Last modified
Categories
Share
Businesses Without Websites: No-Website Leads Finder (OpenStreetMap)
Find local businesses with no website in any city or region: restaurants, dentists, beauty salons, car repair shops, lawyers and 30+ other niches. The Actor lists every business that has no website listed in OpenStreetMap, only a Facebook or Instagram page, or a website link that is dead, and gives you name, category, address, phone (E.164), email, social links, opening hours and coordinates. Ready for a spreadsheet, a CRM or a cold-calling list.
Built for web designers, web agencies, freelancers and local marketers who sell first websites, redesigns, Google Business profiles or booking pages. No Google Maps scraping, no proxies, no login: the data comes from OpenStreetMap, and every listed website is checked live.
Price: $3 per 1,000 leads. Businesses that are filtered out (live website, chain, duplicate) are free.
What does Businesses Without Websites Finder do?
- Turns a city or region name (e.g.
Chișinău, Moldova,Graz, Austria,Austin, Texas) or a bounding box into a search area. - Collects every named business in the categories you pick, plus any custom OpenStreetMap tag (
shop=bicycle,craft=carpenter...). - Checks every listed website live and labels it
none,social_only,deadorlive. A dead domain or a "website" that is really a Facebook page counts as a lead. - Skips chains and well-known venues (on by default), so you don't pitch a website to a franchise.
- Removes duplicates and converts phone numbers to international E.164 format (
+37360000001). - Exports to CSV, Excel, JSON or Google Sheets, or straight into your tools through the API, Make, Zapier or n8n.
Example output
A real run with the default input (dentists in Chișinău, Moldova). Phone digits and emails are masked here; the dataset has them in full.
| name | category | phone_e164 | website_status | website_check_detail | |
|---|---|---|---|---|---|
| Vita-Lic | dentist | +37322xxxx15 | v...@inbox.ru | none | no website listed in OpenStreetMap (unverified) |
| Galodent-M | dentist | social_only | website redirects to www.facebook.com (via galodent.md; listed host has no DNS) | ||
| SG Dent | dentist | +37322xxxx31 | dead | DNS lookup failed | |
| Dental.md | dentist | dead | timeout | ||
| Demi Dent | dentist | +37368xxxx31 | d...@gmail.com | none | no website listed in OpenStreetMap (unverified) |
| Centru Medical „Ivilius” | dentist | +37369xxxx53 | i...@gmail.com | social_only | website tag points to a social profile |
That run returned 100 leads in about 90 seconds.
Who it's for
- Web design and development agencies looking for local clients who need a first website.
- Freelancers and local marketers offering websites, Google Business profiles, booking pages or social-to-web upgrades.
- Sales teams and lead-generation agencies building a call list of small businesses in one city and niche (dentists, salons, car repair shops, cafes...).
- AI sales agents that need a fresh list of prospects on demand (see Use with AI agents and MCP).
How to find businesses without a website
- Click Try for free and create a free Apify account (no credit card needed).
- Type a Location, e.g.
Kraków, Poland, and pick one or more Business categories. - Set Maximum results to cap the cost, then click Start.
- Open the Output tab and download the leads as CSV or Excel, or connect them to Google Sheets, Make, Zapier or n8n.
- Check each lead before you contact it:
nonemeans "no website in OpenStreetMap", not "no website anywhere" (see Limitations).
How it works
-
Turns your location into a search area through OpenStreetMap's Nominatim geocoder. You can pass an exact bounding box instead.
-
Runs one OpenStreetMap (Overpass API) query per category and collects every named business in the area.
-
Removes duplicates. A business is often mapped twice in OpenStreetMap, once as a point and once as a building outline. The Actor drops the second copy when the name and phone match, or when the same name appears within 100 m.
-
Skips chains and well-known venues (
excludeChains, on by default). OpenStreetMap often leaves out the website of chain locations, so a Dave & Buster's or a Maggiano's would otherwise look like a business without a website. A business with no website listed is skipped when:- it has a
brand,brand:wikidata,brand:wikipedia,operator:wikidata,wikidataorwikipediatag; - its name is a known brand of the same kind of business in the OpenStreetMap name-suggestion-index for the area's country or state;
- another business with the same name in the search lists a website or brand tag; or
- the same name appears at two or more locations more than 100 m apart.
The last two rules ignore generic names, because two places with such a name are usually unrelated: names the name-suggestion-index has reviewed and rejected as brands (e.g.
Dental Clinic,Стоматология) plus a short built-in list (e.g.Stomatologie,Pizzeria,Frizerie).Businesses whose listed website is dead are always kept.
- it has a
-
Classifies each business's web presence:
website_status | Meaning |
|---|---|
none | No website listed in OpenStreetMap (unverified) and no social profile. The business may still have a website that OpenStreetMap doesn't know about. |
social_only | Only a Facebook/Instagram profile, a website field that points to one, or a domain that redirects to one. |
dead | The listed website doesn't resolve (DNS), refuses connections, times out, or returns HTTP 404/410. |
live | The listed website answered. Any other HTTP status counts as live, including 403 bot walls and 5xx errors, because a server is still there. |
unchecked | A website is listed but verification was turned off. |
- By default it keeps only
none,social_onlyanddead: businesses with no working website on record. Check them before outreach. - Converts phone numbers to E.164 (
+37360000001). The country comes from the business address or the search area, and can be overridden.
Input
| Field | Type | Default | Description |
|---|---|---|---|
location | string | City or region name, e.g. "Chișinău, Moldova". | |
boundingBox | string | Instead of location: "south,west,north,east", e.g. "46.35,14.08,46.38,14.13". Used when both are set. | |
categories | array | ["dentist"] | Any of: restaurant, cafe, bar, pub, fast_food, bakery, dentist, doctors, clinic, pharmacy, veterinary, hairdresser, beauty, massage, tattoo, fitness_centre, hotel, guest_house, car_repair, car_wash, tyres, florist, clothes, shoes, jewelry, optician, furniture, hardware, electronics, mobile_phone, pet, butcher, convenience, lawyer, accountant, estate_agent, plumber, electrician, photographer. |
customTags | array | Any other OpenStreetMap tag as key=value (e.g. shop=bicycle, craft=carpenter), or just key. | |
onlyWithoutWebsite | boolean | true | Keep only none / social_only / dead. Turn it off to get every business with its status. |
verifyWebsites | boolean | true | Check each listed website with one HEAD/GET request. |
excludeChains | boolean | true | Skip chains and well-known venues that have no website listed (see step 4 above). |
requirePhone | boolean | false | Skip businesses without a phone number. |
maxItems | integer | 100 | Stop after this many results, which also caps the cost. |
phoneCountry | string | auto | 2-letter country code for local phone numbers. Normally detected automatically. |
Example:
{"location": "Chișinău, Moldova","categories": ["dentist", "beauty", "car_repair"],"customTags": ["shop=bicycle"],"onlyWithoutWebsite": true,"verifyWebsites": true,"requirePhone": true,"maxItems": 200}
Output
One dataset item per business. Example (phone digits and email shortened here):
{"name": "Public & Vegan Kitchen","category": "restaurant","osm_tag": "amenity=restaurant","address": "Ljubljanska cesta 4, 4260 Bled","street": "Ljubljanska cesta","housenumber": "4","postcode": "4260","city": "Bled","country": "SI","lat": 46.3666858,"lon": 14.1096165,"phone": "+386 xx xxx x12","phone_e164": "+386xxxxxx12","phones_e164": ["+386xxxxxx12"],"email": "p...@gmail.com","website": null,"website_status": "social_only","website_check_detail": "no website listed in OpenStreetMap (unverified); social profile listed","facebook": "https://www.facebook.com/PublicBarVeganKitchen/","instagram": null,"opening_hours": "Tu-Th, Su 12:00-00:00; Fr, Sa 12:00-03:00","osm_id": "node/4578415854","osm_url": "https://www.openstreetmap.org/node/4578415854","source": "OpenStreetMap","license": "ODbL 1.0, (c) OpenStreetMap contributors, https://www.openstreetmap.org/copyright"}
website, facebook and instagram are null when OpenStreetMap has no value. website_check_detail explains each verdict, e.g. HTTP 404, DNS lookup failed, timeout, or website redirects to www.facebook.com (via example.md; listed host has no DNS). You can export the dataset as CSV, Excel, JSON or XML from the Storage tab, or through the API.
How much does it cost to find businesses without a website?
The Actor uses pay-per-event pricing: $3 per 1,000 leads ($0.003 per business written to the dataset), plus a start fee of $0.00005 per run. Apify platform usage is included in that price.
| Leads | Price |
|---|---|
| 100 | $0.30 |
| 1,000 | $3.00 |
| 10,000 | $30.00 |
Businesses that are filtered out, such as those with a live website, chains, duplicates, or ones without a phone when requirePhone is on, cost nothing. The run stops at maxItems or at the maximum charge you set for the run, whichever comes first. Apify's free plan includes monthly credit, enough to try the Actor on a few cities.
Use with AI agents and MCP
Give Claude, Cursor, ChatGPT or your own agent a "find businesses without a website" tool through the Apify MCP server. Add this server URL to your MCP client:
https://mcp.apify.com?tools=malmurk/osm-no-website-leads
Then ask, for example: "Find 50 hair salons in Valencia, Spain with no website and a phone number, and put them in a table." The agent fills in location, categories, requirePhone and maxItems itself. Keep maxItems small in agent workflows to control cost.
Integrations and API
- Make, Zapier and n8n: run the Actor from a scenario, zap or workflow and push new leads to Google Sheets, HubSpot, Pipedrive, Airtable or email. See the Make, Zapier and n8n guides.
- Schedules: run the same city every week with Apify Schedules to catch newly mapped businesses.
- Webhooks: get notified when a run finishes (webhooks).
- API: one HTTP call runs the Actor and returns the leads.
curl -X POST "https://api.apify.com/v2/acts/malmurk~osm-no-website-leads/run-sync-get-dataset-items?token=<YOUR_API_TOKEN>&format=csv" \-H "Content-Type: application/json" \-d '{"location": "Graz, Austria", "categories": ["hairdresser", "beauty"], "requirePhone": true, "maxItems": 50}'
from apify_client import ApifyClientclient = ApifyClient("<YOUR_API_TOKEN>")run = client.actor("malmurk/osm-no-website-leads").call(run_input={"location": "Graz, Austria", "categories": ["hairdresser"], "maxItems": 50,})for lead in client.dataset(run["defaultDatasetId"]).iterate_items():print(lead["name"], lead["phone_e164"], lead["website_status"])
FAQ
How is this different from Google Maps "no website" scrapers? It uses OpenStreetMap, an open database with a license that allows reuse (ODbL), instead of scraping Google Maps. There are no proxies and no CAPTCHAs, so it's cheap and stable. The trade-off: OpenStreetMap has no ratings or reviews, and coverage is best in European cities. It also checks listed websites live, so dead domains and Facebook-only "websites" become leads.
Does none mean the business has no website at all?
No. It means OpenStreetMap has no website for it. Mappers often skip that field, so search the business name before you contact it.
Which countries work?
Any country OpenStreetMap covers. Big European cities are usually mapped in the most detail. Test a small maxItems first for a new city.
Can I get emails?
Yes, when mappers added one (email field). Most leads have a phone number rather than an email. Use requirePhone to keep only callable leads.
Is it legal? The data is published by OpenStreetMap under the ODbL, which allows reuse with attribution. You are responsible for how you contact businesses: cold outreach is regulated in many countries (e.g. GDPR / ePrivacy in the EU).
I found a bug or need a new category.
Open an issue in the Issues tab. Custom OpenStreetMap tags (customTags) cover most niches that aren't in the list.
Related Actors
- Website Screenshot & URL to PDF: capture full-page screenshots of your leads' websites (or their Facebook pages) for a before/after pitch.
- PDF Text Extractor with OCR: turn PDFs, Word files and scans into text and Markdown for AI.
Data source and license
Contains information from © OpenStreetMap contributors, available under the Open Database License (ODbL) 1.0. Every item carries source and license fields. If you publish or redistribute the data, credit OpenStreetMap contributors and follow the ODbL share-alike terms for derived databases.
The chain filter uses brand names from the OpenStreetMap name-suggestion-index (BSD-3-Clause), bundled with the Actor and regenerated with scripts/build_brand_index.py.
The Actor uses the public Nominatim and Overpass APIs within their usage policies:
- It identifies itself with a User-Agent.
- It sends at most 1 Nominatim request per second, and usually only one per run.
- It sends one Overpass query per category, with server-side timeouts, retries with exponential backoff that honor
Retry-After, and a fallback endpoint (overpass.private.coffee). - An Overpass answer cut off by a server limit (a
remark, missing timestamps, or no area data) is retried, never reported as "0 found". If every attempt fails within about 3.5 minutes, that category is skipped, and the run fails with an error when all categories fail.
Limitations
- OpenStreetMap coverage varies. Big cities in Europe are usually well mapped. Small towns and some countries are not. If a business isn't in OpenStreetMap, the Actor can't find it.
nonemeans "no website listed in OpenStreetMap", not "no website". OpenStreetMap volunteers often skip the website field. The live check catches dead links and social-only links that are listed, but it can't discover a website OpenStreetMap doesn't mention. Search each business's name before you contact it.- The chain filter is not complete. It only knows chains that OpenStreetMap or the name-suggestion-index mark as brands, or that appear more than once in your search. A chain with a single untagged location in the area, or a well-known independent venue, can still appear (in an Austin test run: Grand Lux Café, Pappasitos, Fonda San Miguel). It can also wrongly skip unrelated businesses that share a generic name missing from its lists at two or more locations. Turn
excludeChainsoff if you want chain locations too, or to see everything. liveis deliberately generous: a site behind a bot wall or temporarily down counts as live, so you don't pitch a website to someone who already has one.- Phone numbers and emails are whatever mappers entered. Invalid numbers are kept in
phonebut left out ofphone_e164. - Very large areas (whole countries) can exceed Overpass's query time limit. Split them into cities or bounding boxes.
- You are responsible for how you use the contact data. Cold outreach is regulated in many countries (e.g. GDPR / ePrivacy in the EU).
Local development
python -m venv .venv && .venv/Scripts/pip install -r requirements-dev.txt # Windows; use .venv/bin on Linux/macOS.venv/Scripts/python -m pytest # offline tests, no networkapify run --purge --input '{"location":"Chișinău, Moldova","categories":["dentist"],"maxItems":5}'
To test pay-per-event behavior locally, set ACTOR_TEST_PAY_PER_EVENT=true and ACTOR_MAX_TOTAL_CHARGE_USD=<n>. Locally, the SDK prices each result at $1 plus $1 for the dataset item, so n=10 stops after 5 results. The charge log is written to storage/datasets/charging-log/.