# Local Business & POI Data (Overture Maps, No Scraping) (`opendata-desk/business-places`) Actor

One call returns up to 50,000 local business listings (POI data) for a city name, circle (max 25 km) or bounding box: name, category, address, coordinates, website, phone and licence attribution, from open Overture Maps data. $2 per 1,000 places plus a $0.02 start at the default 2 GB.

- **URL**: https://apify.com/opendata-desk/business-places.md
- **Developed by:** [TH Kim](https://apify.com/opendata-desk) (community)
- **Categories:** Lead generation, Travel
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.00 / 1,000 place returneds

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 & POI Data (Overture Maps, No Scraping)

**One call returns up to 50,000 local business listings (POI data)** for a city name, a circle (up to 25 km) or a
bounding box (up to 2,500 km²): name, category, address, coordinates, website, phone, brand, confidence and licence
attribution. **Price: $2 per 1,000 places** ($0.002 each, website and phone included) plus a $0.02 start at the default
2 GB. A run with no area or an unknown place name fails before any place is charged. If no place matches your
categories, the run returns an empty dataset and its status message says why.

The data comes from **[Overture Maps](https://overturemaps.org) Places**, an openly licensed dataset built from Meta,
Microsoft, Foursquare, AllThePlaces and other contributors. Nothing is scraped, so you can use the results
commercially as long as you keep the attribution.

Use it for local market sizing, site selection, franchise or store-network planning, local-SEO audits, lead lists
and category counts by area.

### Quick start

```json
{ "location": "Berlin, DE", "radiusMeters": 2000, "categories": ["dentist"], "maxResults": 100 }
```

This returns up to 100 dentists within 2 km of central Berlin, nearest first. Coordinates work too:
`{ "latitude": 52.52, "longitude": 13.405, "radiusMeters": 2000, "categories": ["dentist"] }`.

### What you get

One dataset item per place:

| Field | Example |
|---|---|
| `name` | "Joe's Pizza" |
| `primaryCategory`, `basicCategory`, `otherCategories`, `categoryHierarchy` | `pizza_restaurant`, `restaurant`, `[...]`, `["food_and_drink","restaurant","pizza_restaurant"]` |
| `address`, `locality`, `region`, `postcode`, `countryCode` | "7 Carmine St", "New York", "NY", "10014", "US" |
| `latitude`, `longitude`, `distanceMeters` | 40.7306, -74.0021, 412 |
| `website`, `phone` (optional) | "https://…", "+12125551234" |
| `brandName`, `brandWikidataId` | chain name and Wikidata id, if any |
| `operatingStatus`, `confidence` | `open`, 0.93 |
| `overtureId`, `overtureRelease`, `sourceDatasets` | GERS id, "2026-09-23.1", `["meta","Foursquare"]` |
| `attribution` | licence text required for this record |

The full field list, with a title and an example for every field, is in the dataset schema (Output tab). The run's
output links point to the full items (every field, including `attribution`).

A run summary is saved as `OUTPUT` in the default key-value store (also linked from the run's output):

- `location`: which place a name resolved to (name, region, country, coordinates, population, GeoNames id), whether
  the name was ambiguous, and the runner-up matches.
- `areaSource` (`location`, `latitude/longitude` or `bbox`) and the searched `area`.
- `categoryMatches` (places found per requested category) and `unmatchedCategories`.
- Overture release used, counts, timings and the attribution line. On a failed run, `error` says why; on an empty
  run, `warning` does.

The run's status message sums up the result in one line (for example `100 places from Overture Maps 2026-09-23.1.`).
Apify's MCP server passes it to AI agents with the run.

### Input

- **Area** (required, no default). In order of precedence:

  1. `bbox` `[minLon, minLat, maxLon, maxLat]` (up to 2,500 km²; results sorted by confidence), or
  2. `latitude` + `longitude` + `radiusMeters` (results sorted by distance), or
  3. `location`: a city or town name such as "Berlin, DE", "Austin, TX, US", "Paris, France" or "München". It is
     looked up offline in a bundled [GeoNames](https://www.geonames.org) list of about 171,000 cities and towns with
     roughly 1,000+ people. The circle is centred on the place, with `radiusMeters` (default 1,000 m, up to 25 km).
     Add a region or country after a comma when a name is ambiguous. Otherwise the most populous match is used, and
     `OUTPUT.location` says which place that was and lists the others. A match on an alternate name ("Frisco" for San
     Francisco) must be ten times more populous to beat a match on a main name (Frisco, TX). An unknown name fails
     the run before anything is queried, and no places are charged.

  If you give more than one, the one higher in this list is used and `OUTPUT.ignoredAreaInputs` names the others.
  A run with no area fails at once (no places are charged; the Apify platform's start event still applies).
- **categories** (optional): Overture taxonomy terms such as `pizza_restaurant` or `dental_clinic`, or aliases:
  restaurant, cafe, coffee, bar, dentist, gym, fitness, hotel, lawyer, salon, hair\_salon, plumber, pharmacy,
  supermarket, grocery, car\_repair, real\_estate, doctor, veterinarian. Case, spaces, hyphens and plurals are
  normalised ("Dentists" = dentist, "coffee shops" = coffee\_shop). A category also matches its sub-categories
  ("restaurant" includes every kind of restaurant). Browse the terms in the
  [Overture taxonomy explorer](https://docs.overturemaps.org/guides/places/taxonomy-explorer/). Categories that match
  no place are listed in `OUTPUT.unmatchedCategories`; if none matches, the dataset is empty, no places are charged, and
  the run's status message and `OUTPUT.warning` say why.
- **maxResults**: 1 to 50,000 (default 100).
- **minConfidence**: 0 to 1 (default 0). Permanently closed places are always left out.
- **includeContactFields**: website and phone (default on).
- **overtureRelease**: default `2026-09-23.1`, or `latest`. Overture hosts each release for about
  60 days; if the requested release is gone, the newest one is used and the run summary says so.

### Privacy

- No email addresses, ever.
- No phone numbers for places in the EU, EEA or UK (or when the country is unknown).
- No reviews, no photos, no personal profiles. This returns business places, not people.

### Pricing (pay per event)

| Event | Price |
|---|---|
| Actor start (`apify-actor-start`) | $0.01 per GB of run memory: $0.02 per run at the default 2 GB |
| Place returned (`place`) | $0.002 per place, website and phone included |

So at the default memory, 1,000 places cost at most $0.02 + $2.00 = $2.02, contact fields included. There is no
separate charge for websites or phones. The Actor stops when your run's spending limit is
reached. (Event names as in `src/pricing.js`; no "+usage" option.)

### Coverage and limits

- Coverage is good for businesses with an online footprint and weaker for small or new places;
  freshness follows Overture's monthly releases. There are no ratings, reviews, opening hours or
  photos.
- Categories come from Overture's taxonomy and can differ from Google's.
- Point-of-interest counts in dense cities are high; use categories or a smaller area.
- Place names cover towns with about 1,000+ people (and regional seats). Street addresses and postcodes are not
  looked up; use coordinates for those.

### Data licence and attribution

This Actor queries the public Overture Maps GeoParquet release on AWS S3
(`s3://overturemaps-us-west-2/release/<release>/theme=places/type=place/`). Places has no single
licence; each source keeps its own. If you publish or share the data, keep the `attribution`
field (or reproduce the lines below for the sources you use), as set out at
<https://docs.overturemaps.org/attribution/>:

- Overture Maps Foundation, overturemaps.org
- Data from Meta. Available under CDLA Permissive 2.0
- Data from Microsoft. Available under CDLA Permissive 2.0
- Data from PinMeTo. Available under CDLA Permissive 2.0
- Data from Krick. Available under CDLA Permissive 2.0
- Data from RenderSEO. Available under CDLA Permissive 2.0
- Data from DAC. Available under CDLA Permissive 2.0
- Data from BrightQuery. Available under CDLA Permissive 2.0
- Copyright 2024 Foursquare Labs, Inc. All rights reserved. Available under Apache 2.0
- Data from AllThePlaces. Available under CC0 1.0

Place-name lookup: GeoNames (https://www.geonames.org), CC BY 4.0
(<https://creativecommons.org/licenses/by/4.0/>). The bundled list is a reduced copy of GeoNames' `cities1000`,
region and country files; the changes are listed in `THIRD_PARTY.md`. GeoNames provides its data "as is", without
warranty.

This Actor is not affiliated with or endorsed by the Overture Maps Foundation, GeoNames or their contributors.

### FAQ

**Is this a Google Maps scraper?** No. It never touches Google. It reads an open dataset published
for reuse.

**How fresh is it?** Each record carries `overtureRelease`. Overture publishes monthly.

**Can I get a city by name?** Yes: pass `location`, for example "Austin, TX, US". The run summary says which place
was used.

**Why did my run fail with "An area is required"?** There is no default area, so a call without `location`,
coordinates or `bbox` stops before anything is queried and no places are charged.

# Actor input Schema

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

City or town, optionally with region and country, e.g. "Berlin, DE", "Austin, TX, US" or "Paris, France". Looked up offline in a bundled GeoNames list (towns with about 1,000+ people); the search circle is centred on the place with radiusMeters. An ambiguous name uses the most populous match, and the OUTPUT record says which place was used. latitude/longitude or bbox override it.

## `radiusMeters` (type: `integer`):

Search radius around the place or the latitude/longitude centre, 10 to 25000 meters. Results are sorted by distance from the centre.

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

Latitude of the circle centre in WGS84 degrees (-90 to 90). Use with longitude and radiusMeters. Overrides location.

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

Longitude of the circle centre in WGS84 degrees (-180 to 180).

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

\[minLon, minLat, maxLon, maxLat] in WGS84 degrees, max 2,500 km². Takes precedence over the circle and location. Results are sorted by confidence.

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

Optional. Overture taxonomy terms (e.g. "pizza\_restaurant", "dental\_clinic") or aliases: restaurant, cafe, coffee, bar, dentist, gym, fitness, hotel, lawyer, salon, hair\_salon, plumber, pharmacy, supermarket, grocery, car\_repair, real\_estate, doctor, veterinarian. Case, spaces and plurals are normalised ("Dentists" = dentist). A place matches if any term is anywhere in its category hierarchy ("restaurant" includes all restaurant types). Categories with no matching place are listed in the OUTPUT record; if none matches, the run returns no places and its status message says why. Empty = all places.

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

Maximum number of places to return (1 to 50000). You are charged per place returned.

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

Drop places whose Overture existence confidence (0 to 1) is below this. 0 keeps all. Permanently closed places are always excluded.

## `includeContactFields` (type: `boolean`):

Adds website and phone fields at no extra charge. Phone numbers are never returned for places in the EU, EEA or UK, or when the country is unknown. Emails are never returned.

## `overtureRelease` (type: `string`):

Overture Maps release id such as "2026-09-23.1", or "latest". Overture hosts each release for about 60 days; if the requested one is gone, the newest release is used and the run output says so.

## Actor input object example

```json
{
  "location": "Austin, TX, US",
  "radiusMeters": 1000,
  "categories": [
    "restaurant"
  ],
  "maxResults": 50,
  "minConfidence": 0,
  "includeContactFields": true,
  "overtureRelease": "2026-09-23.1"
}
```

# Actor output Schema

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

All place records with every field, including the licence attribution that must be kept when the data is shared.

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

Which place a location name resolved to, the area searched, categories that matched no place, the Overture release, counts and the attribution line. On a failed run it holds the error.

# 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, US",
    "radiusMeters": 1000,
    "categories": [
        "restaurant"
    ],
    "maxResults": 50
};

// Run the Actor and wait for it to finish
const run = await client.actor("opendata-desk/business-places").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, US",
    "radiusMeters": 1000,
    "categories": ["restaurant"],
    "maxResults": 50,
}

# Run the Actor and wait for it to finish
run = client.actor("opendata-desk/business-places").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, US",
  "radiusMeters": 1000,
  "categories": [
    "restaurant"
  ],
  "maxResults": 50
}' |
apify call opendata-desk/business-places --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,opendata-desk/business-places"
        }
    }
}
```

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/0sT8hZOr27iu4KkAV/builds/g1iyKRRbm1w2S15Ed/openapi.json
