# Businesses Without Website: No Website Leads for Web Design (`solidfetch/overture-places-leads`) Actor

Businesses without a website, by city or trade (dentists, plumbers, hair salons): phone, e-mail, socials and address from Overture Maps open data. A Google Maps no website leads alternative with no Google Maps scraping. Filter to no website or with a phone. Pay per place.

- **URL**: https://apify.com/solidfetch/overture-places-leads.md
- **Developed by:** [Solid Fetch](https://apify.com/solidfetch) (community)
- **Categories:** Lead generation
- **Stats:** 2 total users, 1 monthly users, 96.3% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.00 / 1,000 places

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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

## Businesses Without Website: Local Leads from Overture Maps

Find local businesses without a website, with phone numbers, in any city or country. The actor reads Overture Maps, an open map dataset, and returns one row per place with phone, website, e-mail and social profiles where Overture lists them, address and coordinates. Keep only businesses with no website, with a phone number, or in trades such as dentists, plumbers or hair salons. It does not scrape Google Maps and needs no proxy and no login. There are no reviews or ratings, and "no website" means that no source listed one, so check a lead before you pitch.

### What people use it for

- **Cold outreach for web agencies.** Find businesses that have a phone number but no website, for example every dentist in Warsaw without one, and offer them a site.
- **Local market research.** Count the cafes, gyms or law firms in a city, see which chains are present, and export the list with coordinates for a map.
- **Sales lists for a region.** Pull all plumbers or electricians in a country (up to about the size of France) in one run, sorted by how confident Overture is that the place exists.
- **Cleaning up your own CRM.** Match your contacts against Overture IDs, addresses and phone numbers.

### How to use it

1. Pick the area: a country and a city, a country alone, or a map rectangle (`bbox`).
2. Pick categories. Plain words work (`dentist`, `plumber`, `lawyer`, `mechanic`, `hairdresser`) as well as Overture category names (`dental_clinic`, `plumbing`, `hair_salon`). Leave it empty for every kind of place.
3. Choose the website filter and whether a phone number is required, then run it and download the results as JSON, CSV or Excel.

```json
{
    "country": "PL",
    "city": "Warsaw",
    "categories": ["dentist"],
    "requireWebsite": "false",
    "requirePhone": true,
    "maxPlaces": 500
}
```

#### How the area is found

For a city, the actor looks up the city's boundary in the Overture divisions data and returns only places inside it, not the suburbs that fall into the same rectangle. In a Warsaw test, 7 dentists in Józefów, Kobyłka, Marki and Raszyn were inside Warsaw's bounding box but outside the city, and the actor left them out. City names work in English or the local language, with or without accents (`Krakow`, `Kraków`, `Cracow`). When several places share a name, the actor takes the one with the most people, using the population in the Overture divisions data (a locality counts as a city by its size, so a hamlet called `München` in Brandenburg does not beat Munich), and a district or region is taken as the city only when a locality of the same name has about the same population (Munich and the district of Munich, Kraków and the Kraków county). Names without a population fall back to the biggest area. The status message, the log and the `RUN_SUMMARY` record in the key-value store always say which place was searched, with its region and country (`Saved 20 places from München, Bavaria, DE`), and name up to three other places with the same name. Add the region after a comma to pick another one: `Portland, OR` or `Portland, ME`, or use `bbox`.

A few big cities have no boundary in Overture (London is one). For those, the actor asks [OpenStreetMap Nominatim](https://nominatim.openstreetmap.org/) for the boundary. It sends one search per run (retried at most three times if Nominatim fails) with a User-Agent that names this actor, as the Nominatim usage policy asks. City-states such as Berlin, Hamburg and Vienna are found as regions.

A country alone covers the whole country and keeps places whose address is in that country. Places without a country in their address are left out of such a search. Countries larger than 200 square degrees of latitude and longitude (the United States, Spain with the Canary Islands, Norway) and countries that cross the 180th meridian (New Zealand, Fiji, Russia) are too large for one run, so use cities or several `bbox` areas there.

### Input

| Field | Description |
|---|---|
| `country` | Two-letter code (`PL`, `DE`, `GB`, and `UK` also works) or English name. Needed with `city`. Alone, it searches the whole country. |
| `city` | City, town or district name. Add a region code after a comma when the name is common: `Portland, OR` (the code, not `Oregon`). |
| `bbox` | Instead of a city: `[west, south, east, north]` in degrees, for example `[13.3, 52.48, 13.48, 52.56]`. A `country` next to it keeps only addresses in that country. |
| `categories` | Business types. A category includes its subcategories: `restaurant` also returns `pizza_restaurant` and `sushi_restaurant`. When no category is recognised, the run stops with suggestions before any place is charged. An unknown category next to known ones is skipped with a warning. |
| `requireWebsite` | `"false"` keeps only places without a website, `"true"` only places with one, `"ignore"` keeps both. Send these as strings, also from the API: the platform rejects `true` or `false` without quotes. |
| `requirePhone` | `true` skips places without a phone number. |
| `minConfidence` | Overture's score from 0 to 1 that the place exists. Default 0.6. Below that there are many closed places and junk records. |
| `maxPlaces` | Stop after this many places. The most confident places come first. Default 1,000. |
| `includeSuppliers` | Default `false`. When you search a trade (`plumber`, `electrician`, `dentist`), shops, suppliers and wholesalers of it (hardware stores, building supply stores, electrical wholesalers) are left out, because Overture files some of them next to the trade. Set `true` to keep them. Does nothing when no category is set, or for a supplier category you name yourself. |
| `includePersonalEmails` | Default `false`. E-mails at free-mail providers (gmail, yahoo, hotmail, outlook, live, wp.pl, o2.pl, onet.pl, interia.pl, gmx, web.de, icloud, aol, and similar) mostly belong to a person, for example a sole practitioner, so they are left out of `emails`. E-mails on a business domain are always kept. Set `true` to keep the personal ones too. The number of hidden e-mails is in the log and in `RUN_SUMMARY` (`hiddenEmails`). |
| `maxSourceAgeYears` | Default `5`. Skip places whose provider last updated them more than this many years before the Overture release. Places with no update date are kept. `0` means no limit. |
| `release` | Overture release such as `2026-09-23.1`. Leave empty for the latest. |

An unknown field name stops the run before any place is charged, with a hint when it looks like a known one (`maxplaces` or `maxItems` for `maxPlaces`, `category` for `categories`).

Places that Overture marks as permanently closed are always left out. Places left out by `maxSourceAgeYears` or `includeSuppliers` are not saved and not charged; the log and the status message say how many, for example "Left out: 12 shops and suppliers, 3 with source data older than 5 years".

If a run returns fewer than 10 places (or, when you set `maxPlaces` yourself, fewer than a quarter of it), the log shows a warning and the status message adds a note that Overture coverage is thin there, with what to try: a wider area, more categories, places with websites, a higher `maxSourceAgeYears`.

### Output

A real row from a run on the 2026-09-23.1 release (dentists in Warsaw without a website):

```json
{
    "name": "Medicover Stomatologia",
    "category": "dental_clinic",
    "categoryPath": ["health_care", "outpatient_care_facility", "dental_clinic"],
    "phones": ["+48668555881"],
    "phoneE164": "+48668555881",
    "websites": [],
    "emails": [],
    "socials": ["https://www.facebook.com/102560565824482"],
    "noWebsiteReason": "only social media pages",
    "address": "plac Konstytucji 6",
    "locality": "Warszawa",
    "postcode": "00-550",
    "region": "14",
    "country": "PL",
    "addressMismatch": false,
    "lat": 52.22266,
    "lon": 21.016958,
    "confidence": 0.987,
    "operatingStatus": null,
    "brand": "Medicover Stomatologia",
    "sourceDatasets": ["meta"],
    "sourceUpdatedAt": "2026-09-14T00:00:00.000Z",
    "release": "2026-09-23.1",
    "overtureId": "b6dfc650-9ad0-4117-abb6-ad102a600d1c"
}
```

| Field | Description |
|---|---|
| `name`, `brand` | Business name and, for chains, the brand. |
| `category`, `categoryPath` | Overture category and its parents, from the broadest to the narrowest. |
| `phones`, `websites`, `emails`, `socials` | Contact details as Overture has them. Empty lists when there are none. |
| `phoneE164` | The first phone that is a valid number, in international E.164 format (`+441612490066`), worked out with the country of the place's address. Overture's raw `phones` are mixed formats (`08008799977`, `+441612490066`) and stay as they are. Empty when no phone is a valid number. |
| `noWebsiteReason` | For a place with no website: `no website listed in any source`, or `only social media pages` when Overture has social profiles (Facebook, Instagram) for it. Empty when the place has a website. |
| `address`, `locality`, `postcode`, `region`, `country` | First address of the place. |
| `addressMismatch` | `true` when the place's address names a region other than the searched city's, although Overture put the point inside the city (a dentist in Holliston, Massachusetts, placed in Manhattan). The place is kept and charged like any other, so you can drop these rows. Only checked for city searches and only when both regions are written as letter codes (`NY` against `MA`), so it can miss a mismatch but does not flag regions that are just spelled differently. |
| `lat`, `lon` | Position in degrees. |
| `confidence` | Overture's score from 0 to 1. |
| `operatingStatus` | `open`, `temporarily_closed` or empty. Many places have no status. |
| `sourceDatasets`, `sourceUpdatedAt` | Which providers gave the record (`meta`, `Microsoft`, `Foursquare`, `PinMeTo`, `BrightQuery` and others) and when a provider last updated it. |
| `release`, `overtureId` | Overture release and the place's stable ID. |

What the results looked like in our test runs on the 2026-09-23.1 release:

| Search | Places | With phone | With e-mail |
|---|---|---|---|
| Dentists in Warsaw without a website | 61 | 59 | 29 |
| Cafes in Kraków with a phone | 182 | 182 | 99 |
| Plumbers in Berlin | 153 | 152 | 28 |
| Hair salons in London without a website | 612 | 610 | 137 |
| Dentists in all of Poland without a website, with a phone | 810 | 810 | 475 |

The e-mail column was counted before free-mail addresses were hidden by default; with the default `includePersonalEmails: false` it is lower.

In these tests, run from a home connection in Poland, a city search took between 25 seconds and 2.5 minutes and the Poland-wide search between 1 and 3 minutes, depending on network speed and the CPU share.

### Ready-made searches

Open one of these, change the input and run it:

- [Dentists without a website in a city](https://apify.com/solidfetch/overture-places-leads/examples/dentists-without-website)
- [Restaurants with a phone number in a city](https://apify.com/solidfetch/overture-places-leads/examples/restaurants-with-phone)
- [Plumbers lead list for a city](https://apify.com/solidfetch/overture-places-leads/examples/plumbers-lead-list)
- [Cafes with a phone number in a city](https://apify.com/solidfetch/overture-places-leads/examples/cafes-with-phone)

### Send results to Make, Zapier, n8n or a CRM

Long runs do not need to keep a Make or Zapier scenario waiting:

1. Start the actor or one of its saved tasks on a schedule, or from your scenario with the asynchronous "Run Actor" step.
2. Trigger the next step on the finished run. In Make use the Apify module "Watch Actor Runs", in Zapier the Apify trigger for a finished actor run, in n8n the Apify node.
3. Read the rows with "Get Dataset Items" using the run's dataset ID.

For your own endpoint, open the actor's Integrations tab and add an HTTP webhook on "Run succeeded". Apify retries failed deliveries, and the payload contains `resource.defaultDatasetId`, which you can read at `https://api.apify.com/v2/datasets/<datasetId>/items?format=json`. Add `&format=csv` for a spreadsheet, or `&flatten=<field>` to turn nested objects into flat columns.

### Pricing

You pay per place saved: $1.50 per 1,000 places on the free plan, $1.30 on Bronze, $1.20 on Silver and $1.00 on Gold and above, plus $0.001 per run. Platform usage is included. A run that finds nothing, or fails before it saves a place, costs only the run fee (a run that fails later is charged for the places it saved), and the run stops on its own at the maximum cost you set. The $5 of monthly free credit covers about 3,000 places.

### FAQ

**How fresh is the data?** Overture publishes a new release about once a month, and the actor uses the latest one unless you name another. Each provider updates its records on its own schedule, so some records are years old: `sourceUpdatedAt` shows when the provider last touched a place. By default the actor drops places last updated more than 5 years before the release (`maxSourceAgeYears`). In the recorded Warsaw extract that removes 1 of 1,412 confident places, and in a border-area extract 50 of 1,860; with 3 years it would be 20 and 75. Set it to 0 to keep everything. Overture also keeps only recent releases online (three on 2026-10-03), so an old `release` value stops working after a few months.

**How is this different from a Google Maps scraper?** There are no reviews, ratings, photos or opening hours. In exchange you get a stable ID, a confidence score, the data source for every place, whole-country searches, and runs that do not break when Google changes its pages. Coverage differs by country, so compare a sample with Google Maps for your area before a large campaign.

**Does "without a website" mean the business has no website?** It means none of Overture's sources gave a website for it. Some of these businesses do have a site that the sources missed: the Medicover clinic in the example above belongs to a chain whose dental pages are at medicover.pl. Check a lead before you pitch a new site. In the Warsaw test, 60 of the 61 dentists without a website had a Facebook page.

**Can I use the phone numbers and e-mails for cold outreach?** In the EU and the UK, the phone number or e-mail of a sole trader (for example a dental practice named after the dentist) can be personal data under GDPR, and many countries require prior consent for marketing calls or e-mails. You are responsible for checking the rules where you sell. The actor returns only what Overture publishes and adds nothing from other sites. E-mails at free-mail providers (gmail, yahoo, wp.pl and similar) are hidden by default because they usually belong to a person (`includePersonalEmails` brings them back). Phone numbers are not filtered: they are the business listing's number, but some small businesses, a one-person plumber for example, list a mobile that is also the owner's private number.

When a run fails, an error report with the error message and the shape of the input (which fields are set, how long the lists are), never your input values or your results, is sent to the developer to fix bugs.

**Why do I get fewer places than I expected?** Places with a website are the best documented in Overture, so a search for places without one can be thin in some cities (the run warns when it returns fewer than 10). Try a lower `minConfidence`, a broader category (`restaurant` instead of `pizza_restaurant`), or remove the phone filter. The log says how many matching places were left out because they lie outside the city boundary, and the status message says when `maxPlaces` cut the list.

**Can I run it on a schedule?** Yes. Save the input as a task and schedule it monthly, after each Overture release.

### Use it from code or AI agents

```bash
curl -X POST "https://api.apify.com/v2/acts/solidfetch~overture-places-leads/run-sync-get-dataset-items?token=<YOUR_TOKEN>" \
  -H "Content-Type: application/json" \
  -d '{"country": "DE", "city": "Berlin", "categories": ["plumber"], "maxPlaces": 100}'
```

The actor is pay per event with limited permissions, so it works through the Apify MCP server in Claude, Cursor and other AI agents, and with Apify integrations for Make, n8n, Zapier and Google Sheets.

### Data sources and license

Place data: © Overture Maps Foundation, [overturemaps.org](https://overturemaps.org/). The Places theme combines sources under their own licenses: Meta, Microsoft, PinMeTo, Krick, RenderSEO, DAC and BrightQuery under [CDLA Permissive 2.0](https://cdla.dev/permissive-2-0/), Foursquare (Copyright 2024 Foursquare Labs, Inc. All rights reserved) under Apache 2.0 with its [notice](https://opensource.foursquare.com/places-notice-txt/), and AllThePlaces under CC0 1.0. The `sourceDatasets` field names the providers of each place. See [Overture attribution](https://docs.overturemaps.org/attribution/) for the full terms. If you publish the data, credit Overture Maps Foundation and the sources.

City boundaries come from the Overture divisions theme (© OpenStreetMap contributors, geoBoundaries, Esri Community Maps contributors, Land Information New Zealand; ODbL), and, for cities without a boundary there, from OpenStreetMap Nominatim. Boundaries are used only to filter places and are not included in the output.

This is an independent tool and is not affiliated with the Overture Maps Foundation, OpenStreetMap or any data provider.

If this actor saved you time, a short review on the actor page helps other people find it.

# Actor input Schema

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

Two-letter country code (PL, DE, GB) or English name. With a city, the actor searches that city. Alone, it searches the whole country, for countries up to about the size of France.

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

City, town or district name in English or the local language, for example Warsaw, Kraków, München. Only places inside the city boundary are returned. When several places share the name, add the region after a comma: Portland, OR.

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

Instead of a city: four numbers, west longitude, south latitude, east longitude, north latitude. Example for central Berlin: 13.3, 52.48, 13.48, 52.56. Leave empty when you use a city.

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

Business types. Overture category names such as dental_clinic, cafe, plumbing, hair_salon, or plain words such as dentist, plumber, lawyer, mechanic. A category includes its subcategories: restaurant covers pizza_restaurant, sushi_restaurant and others. Leave empty for every category.

## `requireWebsite` (type: `string`):

Keep only businesses without a website (good for web design outreach), only businesses with one, or both.

## `requirePhone` (type: `boolean`):

Skip places that have no phone number.

## `includeSuppliers` (type: `boolean`):

When you search a trade such as plumber or electrician, shops, suppliers and wholesalers of that trade (hardware stores, building supply stores, electrical wholesalers) are left out by default. Turn on to keep them. Has no effect when no category is set.

## `includePersonalEmails` (type: `boolean`):

E-mails at free-mail providers (gmail, yahoo, hotmail, outlook, wp.pl, o2.pl, onet.pl, interia.pl, gmx, web.de, icloud, aol and similar) usually belong to a person, for example a sole practitioner, so they are hidden by default. Business-domain e-mails are always kept. Turn on to keep the personal ones as well.

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

Overture's score from 0 to 1 that the place exists. Below 0.6 there are many closed places and junk records.

## `maxPlaces` (type: `integer`):

Stop after this many places. The places with the highest confidence come first.

## `maxSourceAgeYears` (type: `number`):

Skip places whose data provider last updated them more than this many years before the Overture release. Old records are often closed or have changed phones. Places with no update date are kept. 0 means no limit.

## `release` (type: `string`):

Leave empty to use the latest monthly release. Overture keeps only the last few releases online.

## Actor input object example

```json
{
  "country": "PL",
  "city": "Warsaw",
  "categories": [
    "dentist"
  ],
  "requireWebsite": "false",
  "requirePhone": false,
  "includeSuppliers": false,
  "includePersonalEmails": false,
  "minConfidence": 0.6,
  "maxPlaces": 200,
  "maxSourceAgeYears": 5
}
```

# Actor output Schema

## `leads` (type: `string`):

No description

## `locations` (type: `string`):

No description

# 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 = {
    "country": "PL",
    "city": "Warsaw",
    "categories": [
        "dentist"
    ],
    "requireWebsite": "false",
    "maxPlaces": 200
};

// Run the Actor and wait for it to finish
const run = await client.actor("solidfetch/overture-places-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 = {
    "country": "PL",
    "city": "Warsaw",
    "categories": ["dentist"],
    "requireWebsite": "false",
    "maxPlaces": 200,
}

# Run the Actor and wait for it to finish
run = client.actor("solidfetch/overture-places-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 '{
  "country": "PL",
  "city": "Warsaw",
  "categories": [
    "dentist"
  ],
  "requireWebsite": "false",
  "maxPlaces": 200
}' |
apify call solidfetch/overture-places-leads --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,solidfetch/overture-places-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/bhtgReHt7gRe3w5cm/builds/7FDJDKHBoOVGbqj37/openapi.json
