# Local Business Leads from OpenStreetMap - No Website Finder (`monriah-studio/osm-local-business-leads`) Actor

Build local business lead lists from OpenStreetMap open data: name, category, address, phone, website, email, opening hours and social links for any city or radius. Filter to businesses with or without a website. No login, no API key.

- **URL**: https://apify.com/monriah-studio/osm-local-business-leads.md
- **Developed by:** [MonRiah Studio](https://apify.com/monriah-studio) (community)
- **Categories:** Lead generation, Business, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.50 / 1,000 business leads

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Local Business Leads from OpenStreetMap – No Website Finder

A test run with the default input (50 hairdressers and restaurants in Austin, TX) costs about $0.08 ($0.0015 per lead, plus a $0.00005 start fee). Apify's free plan includes monthly platform credit.

**OSM Local Business Leads** builds **local business lead lists for any city, neighborhood or radius** from **OpenStreetMap open data**. Each row has the **business name, category, street address, coordinates, phone, website, email, opening hours and social links** (Facebook, Instagram, X, LinkedIn, YouTube, TikTok, Yelp, Tripadvisor), along with a **`has_website`** flag and a link to the OpenStreetMap record.

You can filter to **businesses without a website**, which makes ready-made prospect lists for web designers, agencies and website-builder outreach.

It uses OpenStreetMap's public **Nominatim** (geocoding) and **Overpass** (data) APIs: **no login, no API key, no Google Maps quota, no proxy**. This data is **compiled from OpenStreetMap**, not scraped from Google or Yelp.

### Use cases

- **Agencies (marketing, SEO, web design):** pull every dentist, plumber or salon in a city with phone, email and website, then segment it by who already has a site.
- **Website-builder and web-design outreach:** set **Website filter = Only businesses WITHOUT a website** to get local businesses that have no web presence in OSM, which are your best prospects. Add **Only businesses with a phone or email** so every lead is contactable, and **Exclude chains** to skip franchises.
- **Finding businesses with no website:** check how much of a neighborhood is still offline, or build a "get your business online" campaign list.
- **Sales prospecting and territory mapping:** lat/lon plus a radius gives you everything near an office, store or event venue.
- **Market research:** count competitors by category in an area, or map opening hours and cuisines.
- **AI agents:** a cheap, keyless local-business lookup tool (see *Use from an AI agent* below).

### How to use it

1. Click **Try for free**.
2. Enter a **Location** (`Austin, TX`, `Brooklyn, New York`, `Leeds, UK`). You can also set **Latitude / Longitude** with a **Radius (km)**.
3. Add **Business categories**: OSM tags like `shop=hairdresser`, `amenity=restaurant`, `craft=plumber`, `office=accountant`, or friendly names like `plumber`, `dentist`, `lawyer`, `gym`.
4. Optionally pick a **Website filter**, **Only businesses with a phone or email**, or **Exclude chains**.
5. Set **Max results** and click **Start**. Most runs finish in 20–90 seconds.

Empty input works: `{}` returns 50 hairdressers and restaurants in Austin, TX.

#### How the area is searched

- **Named place:** the Actor geocodes it with Nominatim. If OSM has a boundary for it (a city, county or neighborhood polygon), only businesses **inside that boundary** are returned. If the place is just a point, it searches a 5 km radius around it.
- **Radius:** set `radiusKm` (max 50) to search around the place's center instead of its boundary.
- **Lat/lon:** `latitude` + `longitude` + `radiusKm` (default 5 km) overrides `location`.

#### Friendly category names

`hairdresser`, `barber`, `beauty_salon`, `nail_salon`, `massage`, `tattoo`, `spa`, `restaurant`, `cafe`, `bar`, `pub`, `fast_food`, `bakery`, `ice_cream`, `butcher`, `deli`, `supermarket`, `convenience`, `dentist`, `doctor`, `clinic`, `pharmacy`, `veterinary`, `optician`, `physiotherapist`, `chiropractor`, `gym`, `plumber`, `electrician`, `carpenter`, `roofer`, `painter`, `hvac`, `locksmith`, `gardener`, `landscaper`, `builder`, `photographer`, `accountant`, `lawyer`, `notary`, `real_estate`, `insurance`, `financial_advisor`, `tax_advisor`, `architect`, `it_services`, `marketing_agency`, `travel_agency`, `car_repair`, `car_dealer`, `car_wash`, `tyres`, `florist`, `clothes`, `shoes`, `jewelry`, `furniture`, `hardware`, `bicycle`, `pet_shop`, `pet_grooming`, `dry_cleaning`, `laundry`, `mobile_phone`, `electronics`, `books`, `gift`, `hotel`, `motel`, `guest_house`, `childcare`, `kindergarten`, `driving_school`.

Any other OSM tag works as `key=value` (see the [OSM Map Features](https://wiki.openstreetmap.org/wiki/Map_features) list), and `key=*` matches any value, e.g. `craft=*` for all trades.

### Input example

```json
{
  "location": "Austin, TX",
  "categories": ["shop=hairdresser", "amenity=restaurant"],
  "websiteFilter": "all",
  "maxResults": 50,
  "requireName": true,
  "requireContact": false,
  "excludeChains": false
}
```

Radius search for trades without a website:

```json
{
  "latitude": 30.2672,
  "longitude": -97.7431,
  "radiusKm": 10,
  "categories": ["plumber", "electrician", "craft=roofer"],
  "websiteFilter": "withoutWebsite",
  "requireContact": true,
  "maxResults": 200
}
```

### Output example

```json
{
  "name": "Geiser Barbering",
  "category": "hairdresser",
  "osm_tag": "shop=hairdresser",
  "all_categories": ["hairdresser"],
  "brand": null,
  "street": "West 11th Street",
  "housenumber": "821",
  "unit": "1",
  "city": "Austin",
  "state": "TX",
  "postcode": "78701",
  "country": null,
  "full_address": "821 West 11th Street #1, Austin, TX 78701",
  "lat": 30.2751986,
  "lon": -97.7504281,
  "phone": "+1-512-596-9956",
  "website": "https://www.geiserbarbering.org",
  "email": "nick@geiserbarbering.org",
  "opening_hours": "Mo,Tu,Th,Fr 10:00-19:00; We 13:30-19:00; Sa 09:00-14:00",
  "facebook": "https://www.facebook.com/geiserbarbering",
  "instagram": "https://www.instagram.com/geiserbarbering",
  "twitter": null, "linkedin": null, "youtube": null, "tiktok": null, "yelp": null, "tripadvisor": null,
  "cuisine": null,
  "has_website": true,
  "osm_type": "node",
  "osm_id": "node/13541879134",
  "osm_url": "https://www.openstreetmap.org/node/13541879134",
  "osm_last_check": "2026-02-10",
  "search_location": "Austin, Travis County, Texas, United States",
  "data_license": "ODbL-1.0, © OpenStreetMap contributors (openstreetmap.org/copyright)",
  "scraped_at": "2026-10-24T05:05:58.113Z"
}
```

The key-value record `SUMMARY` shows the resolved area (boundary or radius), the categories used, how many businesses matched, how many were removed by each filter, duplicates merged, the with/without website counts and the Overpass server used.

#### Ordering, dedupe and limits

- Results are **split evenly across your categories**. Within each category, the most complete records (phone, website, email, address, hours) come first.
- **Dedupe:** each OSM feature is returned once. A business mapped twice (say, as a point and as a building outline) is merged when the name matches and the phone, street address or location matches.
- **Max results** applies after all filters, so filtered-out businesses are never returned or charged.

### Data quality and limits (please read)

- OSM is maintained by volunteers. Coverage is **excellent in much of Europe** and **good but patchier in parts of the US and elsewhere**. Some businesses are missing, and phone, email and website are present only when a mapper added them. Results only cover what OSM has.
- **"No website" means OSM lists no website.** The business might still have one, so check before you pitch.
- Addresses come only from the business's own `addr:*` tags, so `city` can be empty even when the business is inside the city you searched.
- Requests use the public Nominatim (1 request per second, with an identifying User-Agent) and Overpass services. If the main Overpass server is busy, the Actor retries and falls back to public mirrors.
- Contact details are business contact data published in OSM. You are responsible for following anti-spam and privacy law (CAN-SPAM, GDPR/PECR, TCPA and so on) when you contact anyone.

### Data license and attribution (ODbL)

This Actor's output is **data compiled from OpenStreetMap**. It is © **OpenStreetMap contributors** and licensed under the **[Open Database License (ODbL) 1.0](https://opendatacommons.org/licenses/odbl/1-0/)**. See [openstreetmap.org/copyright](https://www.openstreetmap.org/copyright).

If you use, publish or share this data:

- **Attribute it:** credit "© OpenStreetMap contributors" with a link to https://www.openstreetmap.org/copyright wherever you display or distribute the data or anything made from it.
- **Share-alike:** if you publicly distribute a database derived from this data, it must also be offered under the ODbL.
- Every row carries a `data_license` field, and the run `SUMMARY` includes the full attribution text.

This Actor isn't affiliated with or endorsed by the OpenStreetMap Foundation. OpenStreetMap® is a trademark of the OSMF.

### Pricing

Pay per result: **$1.50 per 1,000 businesses delivered** (`result` event). Businesses removed by filters and duplicates are **not charged**. The Actor also stops at your run's spending limit.

### Use from an AI agent

You can give this Actor to an AI agent as a tool through the [Apify MCP server](https://docs.apify.com/platform/integrations/mcp) (`https://mcp.apify.com`), from Claude, Cursor, VS Code and other MCP clients:

```json
{
  "mcpServers": {
    "apify": {
      "url": "https://mcp.apify.com?tools=monriah-studio/osm-local-business-leads"
    }
  }
}
```

Then ask something like "Find 30 plumbers in Denver with no website".

Or call it through the [Apify API](https://docs.apify.com/api/v2):

```bash
curl -X POST "https://api.apify.com/v2/acts/monriah-studio~osm-local-business-leads/run-sync-get-dataset-items" \
  -H "Authorization: Bearer $APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"location": "Denver, CO", "categories": ["plumber"], "websiteFilter": "withoutWebsite", "maxResults": 30}'
```

### More actors from MonRiah Studio

- [Bluesky Mentions Monitor](https://apify.com/monriah-studio/bluesky-mentions): brand and keyword mentions on Bluesky, with follower counts and sentiment.
- [Greenhouse, Lever, Ashby & Workday Jobs Scraper](https://apify.com/monriah-studio/ats-hiring-signals): open roles and hiring signals from 6 ATS job boards.
- [RSS Feed Scraper & Monitor](https://apify.com/monriah-studio/rss-feed-monitor): RSS to JSON with new-item change detection.
- [Journalist Requests Scraper](https://apify.com/monriah-studio/journalist-requests): live #journorequest and PR source requests.

# Actor input Schema

## `location` (type: `string`):

City, town, neighborhood, county or region, e.g. `Austin, TX`, `Brooklyn, New York`, `Manchester, UK`. The place's official boundary is searched when OSM has one; otherwise a radius around it. Ignored when latitude and longitude are set.

## `latitude` (type: `number`):

Search around a point instead of a named place. Use with longitude and radius, e.g. `30.2672`.

## `longitude` (type: `number`):

e.g. `-97.7431`.

## `radiusKm` (type: `number`):

Radius around the point (default 5 km). With a named location, setting a radius searches around its center instead of its boundary. Leave empty or 0 to use the boundary.

## `categories` (type: `array`):

OSM tags such as `shop=hairdresser`, `amenity=restaurant`, `craft=plumber`, `office=accountant`, `amenity=dentist`, or friendly names such as `plumber`, `dentist`, `lawyer`, `gym`, `car_repair`, `beauty_salon`, `florist`, `real_estate`, `cafe`. See the README for the full list. `key=*` matches any value.

## `websiteFilter` (type: `string`):

Pick `Only businesses WITHOUT a website` to find web-design and website-builder prospects. Based on OSM's website/url tags.

## `maxResults` (type: `integer`):

Maximum businesses returned, split evenly across categories. Records with phone, website and address come first. You pay only for businesses delivered.

## `requireName` (type: `boolean`):

Skip OSM features with no name (recommended for lead lists).

## `requireContact` (type: `boolean`):

Skip businesses that have neither a phone number nor an email in OSM, so every row is contactable.

## `excludeChains` (type: `boolean`):

Skip outlets tagged with a brand (e.g. Supercuts, McDonald's) to focus on independent local businesses.

## Actor input object example

```json
{
  "location": "Austin, TX",
  "categories": [
    "shop=hairdresser",
    "amenity=restaurant"
  ],
  "websiteFilter": "all",
  "maxResults": 50,
  "requireName": true,
  "requireContact": false,
  "excludeChains": false
}
```

# Actor output Schema

## `results` (type: `string`):

All businesses delivered by this run.

## `summary` (type: `string`):

JSON record SUMMARY: resolved area, categories, counts with/without website, duplicates merged, OSM attribution.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "location": "Austin, TX",
    "categories": [
        "shop=hairdresser",
        "amenity=restaurant"
    ],
    "maxResults": 50
};

// Run the Actor and wait for it to finish
const run = await client.actor("monriah-studio/osm-local-business-leads").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "location": "Austin, TX",
    "categories": [
        "shop=hairdresser",
        "amenity=restaurant",
    ],
    "maxResults": 50,
}

# Run the Actor and wait for it to finish
run = client.actor("monriah-studio/osm-local-business-leads").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "location": "Austin, TX",
  "categories": [
    "shop=hairdresser",
    "amenity=restaurant"
  ],
  "maxResults": 50
}' |
apify call monriah-studio/osm-local-business-leads --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,monriah-studio/osm-local-business-leads"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/CHrJFwDlamSOTadnH/builds/GXUUFhpU8D0iQv6cT/openapi.json
