# Open Places Business Leads (Maps Alternative) (`plainsource/open-places-leads`) Actor

Pull business lists by city, radius or country from Overture Maps open data: 81M places with name, category, address, phone, website, email and social links, plus licence and source on every row. Monthly change tracking. No scraping; no reviews or ratings.

- **URL**: https://apify.com/plainsource/open-places-leads.md
- **Developed by:** [Plainsource](https://apify.com/plainsource) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.50 / 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.

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

Get lists of businesses and other places for any city, radius or country from the [Overture Maps Foundation](https://overturemaps.org) open places dataset. Each row has the name, category, address, coordinates, phone, website, email and social links when the data has them, plus the source dataset and licence.

Nothing is scraped from Google or any map site. Overture publishes the data as open files under permissive licences (CDLA-Permissive-2.0, Apache-2.0 and CC0), and this Actor queries those files directly. That makes it a fit for sales prospecting, local market sizing, territory planning and CRM enrichment in places where scraping a map site is not an option for you.

**Read this before you buy:** there are no reviews, star ratings, opening hours or photos in this data. If you need those, a Google Maps scraper is the right tool. This Actor competes on price, bulk volume, a clean licence and monthly change tracking.

### What's in the data

The September 2026 Overture release (`2026-09-23.1`) has 81,455,423 places. Counted across all of them:

| Field | Share of places that have it |
|---|---|
| Phone | 82% |
| Social link (mostly Facebook) | 74% |
| Website | 58% |
| Email | 37% |

Coverage is not even. Big cities in North America and Western Europe are well covered; small towns and some countries are thin (a whole-country search for plumbers in Luxembourg returned 8). Run a small search for your market first.

Overture merges several sources into one record per place and gives each a confidence score from 0 to 1. Sources include Meta, Microsoft, Foursquare OS Places, PinMeTo, DAC, BrightQuery, Krick, RenderSEO and AllThePlaces. Foursquare's open dataset is already inside Overture, so this Actor does not query it separately.

### Choosing an area

Use one of these. If you set more than one, coordinates win, then the bounding box, then the location name.

- **Location name:** a city, county, state/province or country, such as `Austin, TX`, `Toronto, ON`, `Lisbon, PT`, `Texas` or `Portugal`. Names are looked up in Overture's own boundary data, and the search is limited to the real outline of that place, not a rectangle around it. Add a region or country after a comma when a name is ambiguous. The `SUMMARY` record says which boundary was used and lists other matches.
- **Country code:** `US`, `CA`, `GB`, `MX` and so on, for a whole country.
- **Coordinates and radius:** latitude, longitude and a radius in km (up to 200). Rows then include `distanceKm`.
- **Bounding box:** `min longitude, min latitude, max longitude, max latitude`.

### Choosing business types

Type plain words: `dentist`, `plumber`, `coffee shop`, `italian restaurant`, `hair salon`, `real estate agent`. Each word is matched to Overture's category tree of 2,114 categories, and sub-types come along. `dentist` maps to `dental_clinic`, which also returns general, cosmetic and pediatric dentistry and orthodontics. You can also give Overture category IDs directly. The run summary shows what each word matched, and a word that matches nothing stops the run before any places are returned.

`Name contains` filters on the business name, e.g. `Tim Hortons` or `dental`.

### Filters

- Only places with a phone, a website, or an email in the open data.
- Minimum confidence (0.5 removes most stale or doubtful records).
- Skip chains and franchises: drops places that carry a brand, and any name that appears 3 or more times among the matches.
- Permanently closed places are left out unless you include them.

When more places match than your `Max places`, the run returns the ones with the most contact fields first (phone, website, email, social), then the highest confidence, spread across the whole area.

### Tracking new and changed places

Overture publishes a new release about once a month, with a changelog keyed by its stable place ID. Turn on **Only new or changed since the previous monthly release** to get just the places that were added, or whose name, address, phone, website, email, social links, category, brand, location or status changed. Each row then has `changeType` (`new` or `changed`) and `changedFields`.

Schedule this monthly on the same search to keep a lead list current. Changes to Overture's internal bookkeeping fields are ignored, so a schema change on their side doesn't flood you with "changed" rows. Places removed from Overture are not reported.

### Website check (optional add-on)

Off by default. When on, the Actor reads the homepage listed for each place (one page per business, nothing else on the site), skips it if the site's robots.txt disallows it, and pulls out published email addresses and social profile links. Results go into `websiteCheck` on each row and are merged into `emails` and `socialLinks`.

You are charged the `website-enriched` event only when the page adds an email address, or a social network the open data had no link for. A failed fetch, a blocked page or nothing new costs nothing extra. In a test on 300 US dental clinics, 235 homepages loaded, 13 were skipped because of robots.txt, and the rest failed (timeouts, 403s, dead domains).

### Input examples

20 coffee shops in Toronto (the default example):

```json
{ "location": "Toronto, ON", "categories": ["coffee shop"], "maxItems": 20 }
```

Independent dentists in Texas with a phone and website:

```json
{ "location": "Texas", "categories": ["dentist"], "requirePhone": true, "requireWebsite": true, "excludeChains": true, "maxItems": 5000 }
```

Plumbers and electricians within 15 km of a point, with the website check:

```json
{ "latitude": 30.2672, "longitude": -97.7431, "radiusKm": 15, "categories": ["plumber", "electrician"], "enrichFromWebsite": true, "maxItems": 500 }
```

Monthly feed of new or changed restaurants in Lisbon:

```json
{ "location": "Lisbon, PT", "categories": ["restaurant"], "onlyNewOrChanged": true, "maxItems": 10000 }
```

### Output example

One row from a real run on 2026-10-21 (Toronto coffee shops, chains skipped, website check on). The open data already had the email and Facebook page; the homepage added the Instagram link, so this row was charged the `website-enriched` event:

```json
{
  "name": "Contra Cafe",
  "category": "coffee_shop",
  "categoryPath": [
    "food_and_drink",
    "non_alcoholic_beverage_venue",
    "coffee_shop"
  ],
  "alternateCategories": [],
  "address": "1028 Shaw St",
  "city": "Toronto",
  "region": "ON",
  "postcode": "M6G 3N1",
  "country": "CA",
  "latitude": 43.6690572,
  "longitude": -79.4260803,
  "phone": "+16472933762",
  "phones": [
    "+16472933762"
  ],
  "website": "http://contracafe.ca/",
  "websites": [
    "http://contracafe.ca/"
  ],
  "email": "info@contracafe.ca",
  "emails": [
    "info@contracafe.ca"
  ],
  "socialLinks": [
    "https://www.facebook.com/105051020836598",
    "https://www.instagram.com/contra_cafe"
  ],
  "facebook": "https://www.facebook.com/105051020836598",
  "instagram": "https://www.instagram.com/contra_cafe",
  "brand": null,
  "brandWikidata": null,
  "confidence": 0.998,
  "operatingStatus": null,
  "overtureId": "f8213e92-d018-498d-8217-35c944bdf644",
  "sourceDatasets": [
    "meta"
  ],
  "sourceRecords": [
    {
      "dataset": "meta",
      "recordId": "105051020836598",
      "license": "CDLA-Permissive-2.0",
      "updatedAt": "2026-09-14T00:00:00.000Z"
    }
  ],
  "sourceUpdatedAt": "2026-09-14T00:00:00.000Z",
  "dataRelease": "2026-09-23.1",
  "licenses": [
    "CDLA-Permissive-2.0"
  ],
  "attribution": "Overture Maps Foundation (overturemaps.org), CDLA-Permissive-2.0",
  "openStreetMapUrl": "https://www.openstreetmap.org/?mlat=43.669057&mlon=-79.426080#map=19/43.669057/-79.426080",
  "websiteCheck": {
    "status": "ok",
    "emailsFound": [
      "info@contracafe.ca"
    ],
    "socialLinksFound": [
      "https://www.instagram.com/contra_cafe"
    ]
  },
  "websiteEnriched": true
}
```

Every run also writes two records to its key-value store:

- `SUMMARY`: the area and categories used, how many places matched, how many were saved, any warnings, and website-check status counts.
- `LICENSES`: the full CDLA-Permissive-2.0 text, the Foursquare notice, and the Apache-2.0 and CC0 texts. Keep this file with the data if you pass it on.

### Speed and cost

Measured on Apify with the default 2 GB of memory:

| Search | Places returned | Run time |
|---|---|---|
| Coffee shops in Toronto, max 20 | 20 | 12 s |
| All plumbers in Texas | 4,906 | 53 s |
| Dentists anywhere in the US with a website, max 300, website check on | 300 | 6 min |

Whole-country searches read more data, so they take a few minutes even for small result counts. City and radius searches usually finish in under 30 seconds.

You pay per place returned and, if you turn it on, per enriched website. See the Pricing tab for current prices. Use **Max places** and Apify's maximum cost per run to cap spend; the run stops when the cap is reached.

### Limits

- No reviews, ratings, opening hours, photos, popular times or price levels.
- Data is as fresh as the latest monthly Overture release. A place that opened last week will not be there yet.
- Coverage and accuracy vary by country and category. The confidence score helps, but some records are out of date.
- Emails and phones are what the sources published. Check your local rules (CAN-SPAM, CASL, GDPR and others) before you contact anyone.
- Overture keeps only the newest one or two releases on its public bucket, so older releases can't be queried.

### Data sources and licences

Data: Overture Maps Foundation, [overturemaps.org](https://overturemaps.org), places theme. Overture's [attribution page](https://docs.overturemaps.org/attribution/) lists each places source and its licence:

- Meta, Microsoft, PinMeTo, Krick, RenderSEO, DAC, BrightQuery: [CDLA-Permissive-2.0](https://cdla.dev/permissive-2-0/)
- Foursquare: [Apache-2.0](https://www.apache.org/licenses/LICENSE-2.0)
- AllThePlaces: [CC0-1.0](https://creativecommons.org/publicdomain/zero/1.0/)

Every row carries `sourceRecords`, `licenses` and an `attribution` string for its own sources. CDLA-Permissive-2.0 asks that its text travel with shared data, which is why each run saves the `LICENSES` record. This Actor filters and reshapes the data (field names, flattened address, chosen columns) and, with the website check on, adds emails and links from the business's own homepage. It does not change the values Overture published.

Foursquare asks that its notice be included in documentation for data delivered through an API. Here it is in full:

> Foursquare OS Places Notice
>
> © 2026 Foursquare Labs, Inc. All rights reserved.
>
> The Foursquare OS Places dataset (the "Data") is licensed under the Apache License, Version 2.0 (the "License"). You may not use, modify, or distribute the Data except in compliance with the License.
>
> As set forth more fully in the License, if you use, modify, or distribute the Data, you must:
> – provide recipients with a copy of the License.
> – if applicable, include prominent notices to the extent you've changed the Data.
> – preserve attribution to Foursquare, including preserving the full content of this NOTICE.txt file.
>
> To ensure appropriate attribution to Foursquare, we recommend the following:
> – if using/distributing the Data in flat file form as-is or after making changes/modifications: include this NOTICE.txt file, which may be modified to include an additional notice of your changes/modifications, if any.
> – if using/distributing the Data in API form as-is or after making changes/modifications: include a copy of the content from this NOTICE.txt file prominently in your developer documentation for such API, which may be modified to include an additional notice of your changes/modifications, if any.
>
> You may obtain a copy of the License at: http://www.apache.org/licenses/LICENSE-2.0. Unless required by applicable law or agreed to in writing, the Data distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
>
> See the License for the specific language governing permissions and limitations under the License.

This Actor is not made or endorsed by the Overture Maps Foundation or Foursquare. This is a summary of the licences, not legal advice.

### Questions and issues

Open an issue on the Issues tab with the input you used (or the run ID) and what you expected. A wrong or missing place is usually a source-data problem; Overture takes corrections through its source partners.

# Actor input Schema

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

A city, county, state/province or country, looked up in Overture's own boundaries. Add a region or country after a comma to pick the right one: "Austin, TX", "Toronto, ON", "Lisbon, PT", "Texas", "Portugal". The run summary shows which boundary was used. Ignored when coordinates or a bounding box are set.

## `countryCode` (type: `string`):

Two-letter ISO code (US, CA, GB, DE, MX...). On its own it searches the whole country. With a location name it only keeps matches in that country.

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

Center of a radius search, e.g. 43.6532. Set together with longitude. Takes priority over the location name.

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

Center of a radius search, e.g. -79.3832.

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

Distance from the center point. Used only with latitude and longitude. Each row then includes distanceKm.

## `boundingBox` (type: `string`):

Four numbers: min longitude, min latitude, max longitude, max latitude. Example: -79.42,43.64,-79.37,43.67. Used when no coordinates are set.

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

Plain words such as "dentist", "plumber", "coffee shop", "italian restaurant", or Overture category IDs such as "dental_clinic". Each word is matched to Overture's category tree, and sub-types are included ("dental_clinic" also returns pediatric and cosmetic dentists). The run summary lists what each word matched. Leave empty for every kind of place.

## `nameKeywords` (type: `array`):

Keep places whose name contains any of these words (not case sensitive), e.g. "Tim Hortons" or "dental".

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

About 82% of Overture places have a phone number.

## `requireWebsite` (type: `boolean`):

About 58% of Overture places have a website.

## `requireEmail` (type: `boolean`):

About 37% of Overture places list an email. The website check below can find more, but this filter runs before it.

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

Overture's 0 to 1 score for how likely the place exists as described. 0.5 removes most stale or doubtful records; 0 keeps everything.

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

Drops places that carry a brand in the data, and any name that appears 3 or more times among the matches (e.g. "Tim Hortons", "Country Style"). Useful when you only want independent businesses. The run summary says how many were skipped.

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

Off by default. Most places have no status at all, so this only drops the ones explicitly marked closed.

## `onlyNewOrChanged` (type: `boolean`):

Uses Overture's changelog (matched by Overture ID) to return places added in this release, or whose name, address, phone, website, email, social links, category, brand, location or status changed. Rows get changeType and changedFields. Schedule a monthly run with this on to track a market.

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

Upper limit on places returned (and charged) per run. When more places match, the ones with the highest confidence come first.

## `enrichFromWebsite` (type: `boolean`):

Paid add-on, off by default. Reads one page (the homepage listed in the data) per place that has a website, and respects robots.txt. You are charged the website-enriched event only when the page adds an email or social link the open data did not have. Adds roughly 1 to 10 seconds per 10 places.

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

Leave empty for the newest release. Overture keeps only the latest one or two on its public bucket, e.g. 2026-09-23.1.

## Actor input object example

```json
{
  "location": "Toronto, ON",
  "radiusKm": 5,
  "categories": [
    "coffee shop"
  ],
  "requirePhone": false,
  "requireWebsite": false,
  "requireEmail": false,
  "minConfidence": 0,
  "excludeChains": false,
  "includeClosed": false,
  "onlyNewOrChanged": false,
  "maxItems": 20,
  "enrichFromWebsite": false
}
```

# Actor output Schema

## `places` (type: `string`):

One row per business or place, with source datasets, licences and attribution.

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

Area and categories used, match counts, data release and warnings.

## `licenses` (type: `string`):

Full licence texts and the Foursquare notice that must travel with the data.

# 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": "Toronto, ON",
    "categories": [
        "coffee shop"
    ],
    "maxItems": 20
};

// Run the Actor and wait for it to finish
const run = await client.actor("plainsource/open-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 = {
    "location": "Toronto, ON",
    "categories": ["coffee shop"],
    "maxItems": 20,
}

# Run the Actor and wait for it to finish
run = client.actor("plainsource/open-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 '{
  "location": "Toronto, ON",
  "categories": [
    "coffee shop"
  ],
  "maxItems": 20
}' |
apify call plainsource/open-places-leads --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,plainsource/open-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/dKeQTGX6IdpclBNts/builds/ED8hEomQcjDxe0E3H/openapi.json
