# Local Business Leads - places by category & area (no Maps API) (`bachiembmt/local-business-leads-overture-maps`) Actor

Local business leads by city, bbox or radius from Overture Maps open data: name, category, address, coordinates, website, phone, socials, confidence. A cheap Google Maps alternative. No API key, no proxy, no scraping. Filter by category, keyword, website/phone.

- **URL**: https://apify.com/bachiembmt/local-business-leads-overture-maps.md
- **Developed by:** [Ha Phan Thanh Hai](https://apify.com/bachiembmt) (community)
- **Security:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.50 / 1,000 place scrapeds

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 - places by category & area (no Maps API)

Get local business leads (restaurants, dentists, plumbers, salons, hotels, ...) for any city, radius or bounding box from the **Overture Maps Places** open dataset. No Google Maps API key, no scraping, no proxies, no browser: the actor reads the public Overture dataset directly, so runs are fast and cheap.

Each lead has: name, category, address, coordinates, website, business phone, social links, brand, confidence score and data sources.

### Use cases

- Build prospecting lists for B2B sales ("dentists with a website in Berlin").
- Local SEO / market mapping: count competitors per category and area.
- Enrich CRMs or maps with open, redistributable place data.

### Input

| Field | Meaning |
|---|---|
| `city` | City name, geocoded with Open-Meteo (default `Hanoi`). |
| `radiusKm` | Half-width of the search square (default 2). Keep <= 15 for fast runs. |
| `lat`, `lng` | Alternative to city. |
| `bbox` | `[minLng, minLat, maxLng, maxLat]` - overrides everything else. |
| `categories` | Overture category ids. A parent id also matches children (`restaurant` includes `pizza_restaurant`). Empty = all. |
| `keywords` | Name must contain any of these words. |
| `requireWebsite`, `requirePhone` | Keep only places that have them. |
| `minConfidence` | 0-1; 0.7+ filters most dead/odd entries. |
| `maxResults` | Best confidence first (default 20). |

```json
{ "city": "Berlin", "radiusKm": 5, "categories": ["dental_clinic"], "requireWebsite": true, "minConfidence": 0.7, "maxResults": 100 }
```

#### Common category ids

| Use | Id | Use | Id |
|---|---|---|---|
| Restaurants | `restaurant` | Dentists | `dental_clinic` (alias `dentist`) |
| Cafes | `cafe`, `coffee_shop` | Plumbers | `plumbing` (alias `plumber`) |
| Bars | `bar` | Electricians | `electrician` |
| Hotels | `hotel` | Lawyers | `attorney_or_law_firm` (alias `lawyer`) |
| Hair salons | `hair_salon` | Real estate | `real_estate_agent` |
| Beauty | `beauty_salon` | Doctors | `doctors_office` |
| Gyms | `gym` | Pharmacies | `pharmacy` |
| Grocery | `grocery_store` | Car repair | `automotive_repair` |
| Accountants/tax | `tax_service` | Architects | `architect` |

The full list is the [Overture taxonomy](https://docs.overturemaps.org/schema/reference/places/place/).

### Output example

```json
{
  "id": "815af368-a492-478a-8f03-b63e4cbfd6cd",
  "name": "Cloud Nine Restaurant Hanoi",
  "category": "restaurant",
  "alternateCategories": [],
  "address": {"freeform": "27 P. Hang Be", "locality": "Quan Hoan Kiem", "region": null, "postcode": "100000", "country": "VN"},
  "lat": 21.033088, "lng": 105.853867,
  "website": "http://cloudninerestaurants.com/",
  "phone": "+842439290011",
  "socials": ["https://www.facebook.com/1985610115067306"],
  "brand": null,
  "confidence": 0.998,
  "sources": ["Overture", "meta"],
  "overtureRelease": "2026-10-21.0",
  "attribution": "Overture Maps Foundation, Places theme (CDLA-Permissive-2.0; ...)"
}
```

The latest Overture release is detected automatically on every run.

### Pricing

Pay per event: **$1.50 per 1,000 places** (`place` event, $0.0015). Google-Maps-based lead scrapers typically charge about $5 per 1,000.

### Data quality (measured on release 2026-10-21.0)

| Query | Places | with website | with phone | with street address |
|---|---|---|---|---|
| Hanoi, restaurants, 2 km | 2,000 (cap) | 39% | 89% | 97% |
| Berlin, dental clinics, 2 km | 268 | 74% | 96% | 100% |
| Austin, plumbing, 5 km | 26 | 77% | 92% | 96% |
Coverage is best in cities and weaker in small towns. No reviews, opening hours or emails. Data can be months old; check `confidence`.

### Limitations

- Overture is an aggregate of open datasets (Meta, Microsoft, Foursquare, OSM-derived, ...). It is not Google Maps: no ratings or reviews.
- Phone numbers are the business numbers as published in the dataset. You are responsible for lawful use (GDPR, anti-spam rules); sole traders' numbers may be personal data in the EU.

### License and attribution

Overture Maps Places is published under **CDLA-Permissive-2.0** (individual source datasets carry their own permissive licenses, e.g. Meta CC0, Foursquare Apache-2.0). Attribution is required: *"Data from Overture Maps Foundation, Places theme, https://overturemaps.org/attribution"*. It is included in every output item. This actor is not affiliated with Overture Maps Foundation.

### FAQ

**Why 0 results?** Category ids must match the Overture taxonomy (`dental_clinic`, not `dentist` - aliases exist for a few). Widen the radius or lower `minConfidence`.
**Memory?** Runs in 512 MB (peak RSS about 0.5 GB); 1 GB is the default.
**Speed?** 15-35 s per query, mostly network reads of the public dataset.

# Actor input Schema

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

City name, geocoded with the free Open-Meteo API; the search area is a square of +/- radius around it. Ignored if lat/lng or bbox is given.

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

Half-width of the search square around the city or lat/lng. Keep it <= 15 for a fast run.

## `lat` (type: `number`):

Optional centre latitude (use with lng).

## `lng` (type: `number`):

Optional centre longitude (use with lat).

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

Optional \[minLng, minLat, maxLng, maxLat]. Overrides city and lat/lng.

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

Overture category ids (restaurant, dental_clinic, plumbing, hair_salon...). A parent id also matches its sub-categories (restaurant includes pizza_restaurant). Aliases: dentist, plumber, lawyer. Empty = all categories.

## `keywords` (type: `array`):

Optional: keep only places whose name contains any of these words (case-insensitive).

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

Only places with a website.

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

Only places with a published business phone number.

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

Overture confidence 0-1 that the place exists and is open. 0.7+ is a good quality filter.

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

Best-confidence places first.

## Actor input object example

```json
{
  "city": "Hanoi",
  "radiusKm": 2,
  "categories": [
    "restaurant"
  ],
  "requireWebsite": false,
  "requirePhone": false,
  "minConfidence": 0,
  "maxResults": 20
}
```

# Actor output Schema

## `places` (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 = {
    "city": "Hanoi",
    "categories": [
        "restaurant"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("bachiembmt/local-business-leads-overture-maps").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": "Hanoi",
    "categories": ["restaurant"],
}

# Run the Actor and wait for it to finish
run = client.actor("bachiembmt/local-business-leads-overture-maps").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": "Hanoi",
  "categories": [
    "restaurant"
  ]
}' |
apify call bachiembmt/local-business-leads-overture-maps --silent --output-dataset

```

## MCP server setup

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

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/3hfph2bGBRnLRdQOU/builds/sPfGOwveK1OVuTiyC/openapi.json
