# No Website Business Leads: Local Businesses Without a Site (`atesen-software/no-website-business-leads`) Actor

Find local businesses that have a phone number but no website, by city or map area and category, with a lead score. Built from the open Overture Maps places dataset, no scraping. Closed, duplicate, chain and low-confidence rows are filtered out. Made for web design and local marketing agencies.

- **URL**: https://apify.com/atesen-software/no-website-business-leads.md
- **Developed by:** [Atesen Software](https://apify.com/atesen-software) (community)
- **Categories:** Lead generation, Marketing
- **Features:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$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

## No Website Business Leads: local businesses with a phone number and no website

Find local businesses that have a phone number but no website. Pick a city (or a map area) and a business type, and get a list of businesses that need a website, each with a **lead score** so you can call the best ones first.

The data comes from the open **Overture Maps** places dataset, so there is **no scraping, no proxy and no login**. It is built for web design and marketing agencies that sell websites to local businesses: a **list of businesses without websites** that you can send to your CRM, a call sheet or a spreadsheet.

### Three ways to use it

**1. Find website clients in your town.** You build websites for local businesses and need your next ten clients. Run one search for your city and a category that depends on being found online, sort by `leadScore`, and call the top of the list.

```json
{ "city": "Manchester", "country": "GB", "categories": ["hair salon", "plumber"], "maxItems": 200 }
```

**2. Prepare one trade for local marketing.** You have a package for dentists, restaurants or roofers. Pull one category over a whole area (a `bbox`), keep only the better leads with `minLeadScore`, and work through the list region by region.

```json
{ "bbox": [-79.65, 43.58, -79.30, 43.80], "categories": ["plumber"], "minLeadScore": 70, "maxItems": 500 }
```

**3. Map the opportunity in a region.** You want to know where the gaps are before you plan a campaign. Run several categories for a city, then count rows per `postalCode` or `category` in a spreadsheet. `hasSocialPage` tells you which of these businesses are already active online (often a Facebook page) and only lack a real site.

```json
{ "city": "Austin", "country": "US", "categories": ["restaurant", "auto repair", "dentist"], "maxItems": 1000 }
```

### Data source and permission

Source: **Overture Maps Foundation "places" theme** (overturemaps.org), read from the public Overture GeoParquet files on Amazon S3. The data is published under an open license: **CDLA-Permissive-2.0** for most contributors, **Apache-2.0** for the Foursquare data and **CC0** for AllThePlaces. These licenses allow commercial use of the data; when you share it, keep the license notice (the attribution text below). Nothing is scraped from Google, Yelp, Facebook or any other website, and no website's terms are bypassed. The Actor reads the Overture files only; it never visits a business or a search engine.

Every run writes an `attribution` text to the run summary (key-value store record `SUMMARY`). Keep it with your data when you share or resell the list:

`Overture Maps Foundation, overturemaps.org (places, <release>), CDLA-Permissive-2.0 (https://cdla.dev/permissive-2-0/); includes Foursquare data under Apache-2.0`

Foursquare data is Copyright Foursquare Labs, Inc., licensed under Apache-2.0 and transformed to the Overture schema (notice: docs.overturemaps.org/attribution).

This Actor is not affiliated with or endorsed by the Overture Maps Foundation, Google or any listed business.

#### How "no website" is decided

A business is listed when the **Overture record has no website of its own**. That is the whole test. **No live internet check is made**: the Actor does not open any site or run a web search. Social media pages (Facebook, Instagram and similar) and listing, review, booking or delivery pages (Yelp, Tripadvisor, Fresha, Treatwell, Lieferando, Just Eat, Google pages and similar, in every country version such as yelp.de or just-eat.es) do not count as a website, while a Google Sites or Wix page does count as the business's own site, so a business with only a Facebook page is listed. The Facebook address is not written to the output; you only get `hasSocialPage` (true or false).

So "no website" means "no website recorded in Overture". The business may still have a site that Overture does not know. **Check by hand for 30 seconds** (search the business name and city) before the first call, and drop the rows that turn out to have a site.

#### How often is "no website" wrong?

We measured it on Overture release 2026-10-21.0. For 3 cities (Austin US, Manchester GB, Toronto CA), one category (hair salon), we built the lead list and looked for proof inside Overture that a listed business does have a website: another record in the same release with the same phone number, the same name within 300 m, or the same street address and a similar name, that has a website; or the same Overture ID with a website in the previous release (2026-09-23.1). No web search was used.

- **15 random businesses** (5 per city): **3 of 15** had such proof (20% false "no website").
- **All 308 rows** the Actor returned for these three cities (107 in Austin, 46 in Manchester, 155 in Toronto, with the default filters): **29 of 308** had such proof (9%).

This is a lower bound of the real error, because only a website that Overture itself lists on another record can be found this way. A business can have a site that Overture never saw. The share is below 30% for hair salons, the only category measured; other categories can differ. A second check on plumbers had only 14 rows (2 with proof), too few to conclude anything. Plan on the 30-second manual check anyway, and raise `minConfidence` if you want to drop the weaker records.

### What you get

One row per business. Rows are sorted by Overture's confidence score, best first.

| Field | Meaning |
|---|---|
| `overtureId` | Stable Overture place ID |
| `name` | Business name |
| `category` | Overture primary category, for example `hair_salon` |
| `street`, `city`, `region`, `postalCode`, `country` | Address as listed in Overture |
| `latitude`, `longitude` | Location |
| `phone` | First phone number that passed the filters, as listed (formats vary) |
| `hasSocialPage` | `true` when Overture lists a social media page for the business (the address is not included) |
| `confidence` | Overture score from 0 to 1 that the place exists |
| `operatingStatus` | `open`, `permanently_closed`, `temporarily_closed` or empty when unknown |
| `release` | Overture release used (the newest one is looked up at run time) |
| `leadScore` | 0 to 100, explained below |

#### Lead score

The score is a plain sum, so you can check any row by hand. There is no hidden model.

`leadScore = round(45 x confidence) + phone + category + social`

- **confidence part:** `round(45 x confidence)`, so 0 to 45 points. Overture's confidence is a number from 0 to 1.
- **phone part:** 15 points when the number is not recognisable as a mobile number (a landline, or a country where mobile numbers cannot be recognised), 5 points when it is a mobile number (only possible when `dropMobileNumbers` is off).
- **category part:** the commercial weight of the business type, 30, 20 or 10 points. The weight of each category is in the table below; any other category weighs 10. If a place belongs to several categories, the highest weight counts.
- **social part:** 10 points when `hasSocialPage` is true (the business is active online and only lacks its own site).

Example: a dentist with confidence 0.95, a landline and a Facebook page scores 43 + 15 + 30 + 10 = 98.

#### Example input

```json
{
  "city": "Austin",
  "country": "US",
  "categories": ["hair salon"],
  "minConfidence": 0.8,
  "minLeadScore": 60,
  "maxItems": 50
}
```

#### Example output row

```json
{
  "overtureId": "090e8bf5-f361-4a62-b09a-8af842b52a32",
  "name": "California Cuts by Jimmy",
  "category": "hair_salon",
  "street": "The Salon Arbor Walk 10515 N Mopac Expy Service Rd",
  "city": "Austin",
  "region": "TX",
  "postalCode": "78759",
  "country": "US",
  "latitude": 30.391888,
  "longitude": -97.731476,
  "phone": "+1512491xxxx",
  "hasSocialPage": true,
  "confidence": 0.99,
  "operatingStatus": "open",
  "release": "2026-10-21.0",
  "leadScore": 100
}
```

This row is from a real run; the last four digits of the phone number are masked here.

### Input

| Field | Default | What it does |
|---|---|---|
| `city` + `country` | Austin, US | City name and two-letter country code (US, GB, CA, DE, FR, AU ...). The Actor finds the city boundary in Overture and keeps only places inside it. If the city has no boundary polygon, it uses a circle of 8 km around the city centre. Add `region` (for example `TX`) when several cities share a name. |
| `bbox` | none | Alternative to city: `[minLon, minLat, maxLon, maxLat]`, at most 2.5 degrees on a side. Everything inside the box is searched. |
| `categories` | hair salon | Plain business types (see the table below). A name that is not in the table is tried as an Overture category value, for example `pizza restaurant`. With several categories the results are balanced across them. Empty means every category. |
| `minConfidence` | 0.8 | Overture's own existence score. Raise it for cleaner data, lower it for more rows. |
| `minLeadScore` | 0 | Keep only rows with a lead score at or above this value. A high value returns fewer rows. |
| `dropMobileNumbers` | true | Remove mobile numbers in GB, IE, DE, AT, CH, FR, ES, IT, NL, BE, PT, AU and NZ. A business whose only number is a mobile is left out. |
| `maxItems` | 100 | 1 to 5,000 rows per run. Split a big city into several `bbox` runs to get more. |
| `includeClosed` | false | Include places Overture marks as permanently or temporarily closed. |

Always applied: the business must have a phone number, duplicates (same name and phone number) are removed, and chain outlets (places that Overture links to a brand) are skipped, because a chain runs its own website. The Actor checks the remaining cost limit before sending each batch of results.

### Business categories

| Say this | Matches Overture categories (sub-categories included) | Lead score weight |
|---|---|---|
| dentist | dental_clinic, general_dentistry, orthodontics, cosmetic_dentistry, pediatric_dentistry, endodontics, periodontics, oral_and_maxillofacial_surgery | 30 |
| plumber | plumbing | 30 |
| restaurant | restaurant (every cuisine) | 30 |
| lawyer | attorney_or_law_firm | 30 |
| accountant | accountant, bookkeeper, tax_service | 30 |
| real estate agent | real_estate_agent | 30 |
| gym | gym, fitness_studio | 20 |
| hair salon | hair_salon | 30 |
| barber | barber | 20 |
| beauty salon | beauty_salon | 20 |
| nail salon | nail_salon | 20 |
| spa | spa, day_spa, medical_spa | 20 |
| electrician | electrician | 30 |
| auto repair | automotive_repair, auto_body_shop | 30 |
| car dealer | auto_dealer | 20 |
| hotel | hotel | 20 |
| lodging | lodging (hotels, motels, hostels, bed and breakfasts) | 20 |
| cafe | cafe, coffee_shop | 10 |
| bakery | bakery | 10 |
| insurance agency | insurance_agency | 20 |
| chiropractor | chiropractic | 20 |
| doctor | doctors_office | 20 |
| veterinarian | veterinarian, veterinary_care | 20 |
| pharmacy | pharmacy | 10 |
| bank | bank_or_credit_union | 10 |
| roofer | roofing | 30 |
| hvac | hvac_service | 30 |
| cleaning service | cleaning_service, home_cleaning, office_cleaning, carpet_cleaning | 30 |
| landscaper | landscaping | 30 |
| contractor | contractor | 30 |
| painter | painting | 20 |
| locksmith | key_and_locksmith | 20 |
| pest control | pest_control_service | 20 |
| marketing agency | marketing_agency | 20 |
| photographer | photography_service | 20 |
| florist | florist | 10 |
| yoga studio | yoga_studio | 10 |

Common alternatives such as `lawyers`, `attorney`, `realtor`, `mechanic` or `vet` are understood too.

### What it does and does not do

- **Does:** return businesses that have a phone number and no website of their own in Overture, inside the city you choose, best confidence first, without duplicates, without chain outlets, without places Overture marks as closed, and without email addresses, social media links or contact person names.
- **Several categories are balanced.** If you ask for more than one category, the rows alternate between the categories, best confidence first inside each one, so one big category cannot fill the whole list. A category with few matches gives its rows and the others fill the rest up to `maxItems`.
- **"No website" is a record check, not a live check.** See "How often is no website wrong?" above. Some listed businesses do have a site, and a few have only a very old or dead one. Look at each business for 30 seconds before you call.
- **Some chain outlets remain.** Only places that Overture links to a brand are skipped. A branch of a salon or restaurant chain without a brand link can still be listed, and the chain usually has a website. Skip names you recognise.
- **Closed businesses can still appear.** Overture often has no opening status, so a business that closed recently may be in the list. Phone numbers can also be old or wrong.
- **Fewer rows than you ask for is normal.** Businesses with a website are the majority in many categories, so a small town or a strict `minLeadScore` can return less than `maxItems`. In our test, hair salons gave 107 rows in Austin, 46 in Manchester and 155 in Toronto, while plumbers gave only 7, 2 and 5. For trades, list several categories or use a larger area, and lower `minConfidence` for more rows. Empty results are free.
- **No email addresses.** The Actor does not collect or guess emails.
- **Not a Google Maps replacement.** There are no reviews, ratings, opening hours or photos. Coverage depends on Overture: some small businesses are missing everywhere, and the share of places with a recorded website differs by country.
- **Personal data note.** The output holds business names, addresses and business phone numbers. It never holds email addresses, social media addresses or contact person names. A phone number of a one-person business can still be personal data. Mobile numbers are dropped by default in the countries listed above, but you remain responsible for GDPR, PECR, CAN-SPAM, TCPA or local marketing rules and for having a legal basis or permission before you contact anyone.
- **City areas.** The area is the Overture boundary of the city, which can differ from what you call "downtown" or from a postal city. Use `bbox` for exact control.

### Use it with Make, Zapier or n8n

Run the Actor from any automation tool and read the dataset rows.

- **Make:** add the Apify module "Run an Actor", choose this Actor, paste the JSON input, then add "Get Dataset Items" with the run's default dataset.
- **Zapier:** use the Apify app action "Run Actor" and then "Fetch Dataset Items".
- **n8n:** use the Apify node, operation "Run actor and get dataset", with this Actor and the JSON input.
- **API:** `POST https://api.apify.com/v2/acts/atesen-software~no-website-business-leads/run-sync-get-dataset-items` with your Apify token in the `Authorization: Bearer` header and the JSON input as the body. Keep the token in a secret variable, never in a shared scenario.

### FAQ

**Does the business really have no website?** Overture has no website recorded for it, and the Actor makes no live check. The measured share of rows that Overture itself contradicts is in "How often is no website wrong?". Always check by hand before the first call.

**How fresh is the data?** Overture publishes a new release about once a month. Each run looks up the newest release; the release name is in every row and in the summary.

**How long does a run take?** Usually 5 to 30 seconds for one city. The Actor reads only the part of the Overture files that covers your area; nothing is downloaded in full.

**How many businesses can I get?** Up to 5,000 per run. A big city has more places than that, so use several runs with different categories or smaller `bbox` areas.

**Why is a business I know missing?** Overture is a merged open dataset, not a complete directory. It may have a website recorded for that business, the confidence may be below `minConfidence`, or the number may be a mobile number that was dropped.

**What do I pay?** The Actor charges for business rows after saving them to the dataset. See the Pricing tab for the price and set a maximum cost per run. Invalid input and empty results incur no result charges. An interrupted export can still contain billable results. After a hard stop, `SUMMARY` shows the counts confirmed at the last checkpoint and the size of any batch awaiting confirmation. Check the dataset and Apify usage before starting a new run.

**Is it legal to use the list?** The data license allows commercial use with attribution. Contacting businesses is regulated in many countries, so check the rules that apply to you.

# Actor input Schema

## `city` (type: `string`):

City, town or village, for example Austin, Manchester or Toronto. Use it together with Country. Only places inside the city boundary in Overture Maps are kept (a circle of 8 km around the centre when the city has no boundary). Ignored when you fill in Bounding box.

## `country` (type: `string`):

Two-letter country code of the city, for example US, GB, CA, DE, FR, AU.

## `region` (type: `string`):

Only needed when several cities share a name. Use the state or region code, for example TX or US-TX.

## `bbox` (type: `array`):

Map area as \[minLongitude, minLatitude, maxLongitude, maxLatitude], for example \[-79.65, 43.58, -79.30, 43.80] for Toronto. Use it instead of City and Country. At most 2.5 degrees on a side.

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

Plain business types such as hair salon, plumber, restaurant, dentist, electrician, auto repair, lawyer, accountant, real estate agent, gym. See the README for the full list. Other names are tried as Overture category values. Leave empty to get every category. With several categories the results are balanced across them.

## `minConfidence` (type: `number`):

Overture's own 0 to 1 score that the place really exists. Higher means fewer rows and cleaner data. 0.8 is a good starting point.

## `minLeadScore` (type: `integer`):

Keep only businesses with a lead score at or above this value (0 to 100). The score adds Overture confidence, a phone number, the commercial weight of the category and a social page. The formula is in the README. 0 keeps everything.

## `dropMobileNumbers` (type: `boolean`):

In countries where mobile numbers can be recognised (for example GB, DE, FR, ES, IT, NL, AU) remove them. A mobile number often belongs to a one-person business, which makes it personal data. A business whose only number is a mobile is then left out.

## `maxItems` (type: `integer`):

Stop after this many businesses. You are charged only for the rows written.

## `includeClosed` (type: `boolean`):

By default places that Overture marks as permanently or temporarily closed are left out.

## Actor input object example

```json
{
  "city": "Austin",
  "country": "US",
  "categories": [
    "hair salon"
  ],
  "minConfidence": 0.8,
  "minLeadScore": 0,
  "dropMobileNumbers": true,
  "maxItems": 50,
  "includeClosed": false
}
```

# Actor output Schema

## `businesses` (type: `string`):

The lead list: name, address, phone, lead score and more

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

Overture release, area used, rows returned and skipped, the website check note and the attribution text

# 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 = {
    "city": "Austin",
    "country": "US",
    "categories": [
        "hair salon"
    ],
    "maxItems": 50
};

// Run the Actor and wait for it to finish
const run = await client.actor("atesen-software/no-website-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 = {
    "city": "Austin",
    "country": "US",
    "categories": ["hair salon"],
    "maxItems": 50,
}

# Run the Actor and wait for it to finish
run = client.actor("atesen-software/no-website-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 '{
  "city": "Austin",
  "country": "US",
  "categories": [
    "hair salon"
  ],
  "maxItems": 50
}' |
apify call atesen-software/no-website-business-leads --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,atesen-software/no-website-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/BLbUyqsMMzKP92cx8/builds/zgpckMtMo2ouy7LkB/openapi.json
