# Local Business Leads by City & Category (Maps Alternative) (`mortenm/business-leads-overture`) Actor

Find local businesses by category and city: name, phone, website, email, address and socials from the open Overture Maps dataset. A cheap Google Maps scraper alternative: no scraping, no proxies, no blocks. Optional website check finds emails and contact forms.

- **URL**: https://apify.com/mortenm/business-leads-overture.md
- **Developed by:** [Lead Notebook](https://apify.com/mortenm) (community)
- **Categories:** Lead generation, SEO tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $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

## Local Business Leads by City & Category (Google Maps alternative)

Get a list of local businesses for any **business type** in any **city**: name, phone, website, email, full address, social profiles, coordinates, category and opening status. Type `plumber` + `Houston, TX`, or `dentist` + `Bergen, Norway`, and get back the closest businesses to the city centre first.

The data comes from **[Overture Maps](https://overturemaps.org)**, the open map dataset published monthly by the Overture Maps Foundation (founded by Amazon, Meta, Microsoft and TomTom), with places from sources such as Meta, Microsoft, Foursquare and BrightQuery. That means:

- **No scraping of Google Maps**: no proxies, no captchas, no blocked runs, no "results stopped at 120".
- **Fast and cheap**: a city search usually takes 10–40 seconds.
- **Worldwide**: 75+ million places in 200+ countries, 2,000+ business categories.
- **Optional website check** finds **emails, contact forms and booking links** on each business's own website.

### What you get for each business

| Field | Example |
|---|---|
| `name` | Acme Plumbing |
| `categoryLabel`, `category`, `alternateCategories` | Plumbing · `plumbing` · `["water_heater_installation"]` |
| `phone`, `phones` | +17135550123 (E.164) |
| `website`, `domain` | https://acmeplumbing.com/ |
| `email`, `emails` | office@acmeplumbing.com |
| `address`, `city`, `postcode`, `region`, `countryCode` | 1 Main St, Houston, 77002, TX, US |
| `latitude`, `longitude`, `distanceKm` | 29.7604, -95.3698, 1.2 km from the city centre |
| `facebook`, `instagram`, `linkedin`, `x`, `youtube`, `tiktok`, `socialProfiles` | profile URLs |
| `isChain`, `brandName` | national brand (e.g. Roto-Rooter) or independent |
| `operatingStatus`, `confidence` | open / unknown; 0–1 confidence that the listing is current |
| `matchedSearchTerm`, `matchedOn` | which of your terms matched, and whether on the main or a secondary category |
| `websiteCheck` | (optional) contacts found on the website, see below |
| `overtureId`, `overtureRelease`, `sourceDatasets`, `licenses`, `attribution` | provenance for every row |

Directory pages (Facebook, Yelp, Manta, Yellow Pages …) listed as a "website" are moved to `socialProfiles`, so `website` is the business's own site. A business with no own website is a good lead for web designers.

#### Website check (optional, `checkWebsites: true`)

The Actor visits each business's website (homepage plus the contact page by default; robots.txt respected; no browser, no logins) and adds:

- `websiteCheck.status`: `CONTACTS_FOUND`, `NO_CONTACTS_FOUND`, `PARKED_DOMAIN`, `UNREACHABLE`, `BLOCKED`, `NO_WEBSITE`, `NOT_CHECKED`
- emails and phone numbers found on the site (merged into `emails` / `phones`)
- `hasContactForm`, `contactFormUrl`, `bookingLinks`, social profiles
- `technologies` (e.g. WordPress, Wix, Housecall Pro, Calendly)
- `nameFoundOnSite`: whether the business name appears on the site. `false` often means the listed domain now belongs to someone else, or it is a lead-generation site.

### Input example

```json
{
    "categories": ["plumber", "hvac"],
    "locations": ["Houston, TX", "Austin, TX"],
    "maxResults": 200,
    "checkWebsites": true,
    "excludeChains": true
}
```

- **Business types**: everyday words (`plumber`, `dentist`, `roofer`, `lawyer`, `restaurant`, `hair salon`, `real estate agent`, `mechanic`, `chiropractor`, `accountant`, `gym` …) or exact Overture category ids (`dental_clinic`, `hvac_service`, `attorney_or_law_firm` …). The run log and `RUN_SUMMARY` show which categories each word matched.
- **Locations**: `City, State/Region, Country` or `latitude, longitude`. Without a radius, the search circle follows the city size (30 km for 2M+ inhabitants, 20 km for 500k+, 12 km for 100k+, 7 km for 20k+, otherwise 4 km). Set `radiusKm` (0.5–100) to change it.
- **Filters**: `nameKeywords`, `requireWebsite`, `requirePhone`, `requireEmail`, `excludeChains`, `includeClosed`, `minConfidence` (default 0.5), `includeAlternateCategories` (default on).
- Up to 5,000 businesses per location and 20,000 per run.

### Output example

```json
{
    "name": "Fjord Tannklinikk",
    "category": "dental_clinic",
    "categoryLabel": "Dental clinic",
    "phone": "+4755000000",
    "website": "https://fjordtannklinikk.example/",
    "email": "post@fjordtannklinikk.example",
    "address": "Eksempelgaten 1",
    "city": "Bergen",
    "postcode": "5013",
    "countryCode": "NO",
    "distanceKm": 0.41,
    "isChain": false,
    "operatingStatus": "open",
    "confidence": 0.95,
    "matchedSearchTerm": "dentist",
    "matchedOn": "category",
    "websiteCheck": { "status": "CONTACTS_FOUND", "emails": ["post@fjordtannklinikk.example"], "hasContactForm": true, "nameFoundOnSite": true, "charged": true },
    "overtureRelease": "2026-09-23.1",
    "licenses": ["CDLA-Permissive-2.0"]
}
```

(A fictional example showing the format.)

### Pricing

Pay per result, no subscription:

- **`business-lead`**: per business delivered.
- **`website-contacts`**: only when the website check is on **and** it found an email address, a contact form or a booking link on the business's website. Dead, parked, blocked and empty websites cost nothing extra.

The current prices are shown on the Pricing tab. Your **max charge per run** is respected: the Actor delivers only the rows your limit pays for and stops there (the rest is reported in `RUN_SUMMARY`). Nothing is charged for failed runs or businesses that were not delivered.

### Use cases

- **Lead generation and cold outreach**: plumbers, roofers, dentists, lawyers, restaurants … per city, with phones and emails.
- **Web design and SEO agencies**: businesses with no website, a parked domain or a site that does not mention the business.
- **Sales territory planning and market sizing**: count competitors by category and distance.
- **CRM enrichment and local SEO audits**: compare your list with what the open map data says.
- **AI agents**: a clean, structured "find businesses near X" tool with no scraping risk.

### Data quality: what to expect

- Overture is updated monthly; listings can be stale. `confidence` and `operatingStatus` help (the 0.5 default removes most stale entries). The optional website check confirms that a site is live and belongs to the business.
- Coverage is strongest in North America and Europe and varies by category. Compared with Google Maps, Overture has **no reviews or ratings**. In our tests in Houston, Overture listed more plumbers with websites than a Google Maps scrape capped at 700 results.
- A government website or email in a private business's listing or on its site (for example a plumber listed with the plumbing board's site or complaint inbox) is never used as the business's website or email; it is kept in `governmentContacts`. The same goes for a licensing board's phone number (for example the Texas plumbing board's (512) 936-5200 printed in the notice plumbers must show, or copied into a listing): it is kept in `governmentContacts`, never used as the business's phone. Public bodies such as town halls, schools and parks keep their own government websites. `requireWebsite` and `requireEmail` are checked after this cleaning.
- Listing emails exist for roughly a quarter of businesses; the website check usually finds contacts on about 60–80 % of reachable websites.
- "Not found" is not "does not exist": a business missing from the open data may still exist.

### FAQ

**Is this legal to use?** The places come from an openly licensed dataset (CDLA-Permissive-2.0 and Apache-2.0 per source record) that allows commercial use with attribution; the licence of each record is in `licenses`. Keep the `attribution` field (or credit "© Overture Maps Foundation") when you publish the data. Contacting businesses is your responsibility: follow the anti-spam and privacy rules that apply to you (e.g. CAN-SPAM, GDPR).

**Why not just scrape Google Maps?** Google's terms prohibit it, scrapers need proxies and break often, and costs add up. This Actor reads an open dataset, so runs are predictable and cheap. If you need ratings and reviews, combine it with a Google Maps tool.

**How do I get only businesses without a website?** Run without `requireWebsite` and filter the dataset on an empty `website` (or use the website check and filter `websiteCheck.status` = `PARKED_DOMAIN` / `UNREACHABLE`).

**Can I run it every month?** Yes. Use Apify Schedules; each new Overture release is picked up automatically (`overtureRelease` pins one if you need repeatable results).

**A category word does not match?** The error lists similar categories. You can always pass an exact Overture category id.

### Attribution

Places: © Overture Maps Foundation and its data sources, CDLA-Permissive-2.0 / Apache-2.0 (per record). Place names for locations: GeoNames (geonames.org), CC BY 4.0. This Actor is not affiliated with Overture Maps Foundation, Google or any listed source.

### More tools from the same developer

- [Local Business Leads Enricher](https://apify.com/mortenm/local-business-prospect-qualifier): paste business websites, get emails, phones, contact forms, services and tech stack with the source page for each.
- [Web Design Leads](https://apify.com/mortenm/web-design-leads): audit websites in bulk and find businesses with outdated, broken or non-mobile sites, with a lead score.
- [SEO Audit Leads](https://apify.com/mortenm/seo-audit-leads): bulk on-page, technical and local SEO audit of business websites with an SEO score, grade, lead level and the fixes to pitch.
- [Google Trends Trending Now + Bluesky, Wikipedia & Songs](https://apify.com/mortenm/social-trends-radar): what is trending right now across Google Trends, Bluesky, Mastodon, Wikipedia, Hacker News and Apple Music.

# Actor input Schema

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

Everyday words such as plumber, dentist, roofer, restaurant, lawyer, hair salon, HVAC, real estate agent, or exact Overture category ids such as dental_clinic. Each word is matched to Overture categories (shown in the run log and RUN_SUMMARY). Up to 20.

## `locations` (type: `array`):

Cities or towns as "City, State/Region, Country" (e.g. Houston, TX or Bergen, Norway), or "latitude, longitude". Each location is searched in a circle around its centre; see Search radius. Up to 20.

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

The closest businesses to the centre come first. Up to 5,000 per location (20,000 per run).

## `checkWebsites` (type: `boolean`):

Visit each business website (homepage plus contact page) and add emails, phone numbers, contact form, booking links, social profiles, the site's technology and whether the business name appears on the site. Charged per website where an email, contact form or booking link was found; nothing for dead, parked or empty sites. Slower: about 1-3 minutes per 100 websites.

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

Radius around each location's centre. Empty = automatic from the population (30 km for 2M+ cities, 20 km for 500k+, 12 km for 100k+, 7 km for 20k+, otherwise 4 km; 10 km for coordinates).

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

Only businesses whose name contains one of these words (case-insensitive), e.g. "plumbing". With no business types, any category whose name matches is returned.

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

Skip businesses whose listing has no website of their own (Facebook and directory pages do not count).

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

Skip businesses whose listing has no phone number.

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

Listing emails are less common than phones and websites (roughly a quarter of businesses). Use the website check to find more.

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

Skip places that belong to a known brand (a brand with a Wikidata id, e.g. Subway or Starbucks). Local multi-location businesses are kept.

## `includeAlternateCategories` (type: `boolean`):

Also return businesses whose secondary (alternate) category matches, e.g. a general contractor that also lists plumbing. The output column matchedOn tells which.

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

Include places marked permanently or temporarily closed.

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

Overture's confidence that the place exists as listed. 0.5 (default) removes most stale listings; 0 returns everything.

## `maxPagesPerSite` (type: `integer`):

1 = homepage only. 2 (default) also fetches the contact page. Up to 4.

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

Leave empty for the latest monthly release (e.g. 2026-09-23.1).

## Actor input object example

```json
{
  "categories": [
    "plumber"
  ],
  "locations": [
    "Houston, TX"
  ],
  "maxResults": 50,
  "checkWebsites": false,
  "requireWebsite": false,
  "requirePhone": false,
  "requireEmail": false,
  "excludeChains": false,
  "includeAlternateCategories": true,
  "includeClosed": false,
  "minConfidence": 0.5,
  "maxPagesPerSite": 2
}
```

# Actor output Schema

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

No description

## `contacts` (type: `string`):

No description

## `allFields` (type: `string`):

No description

## `runSummary` (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 = {
    "categories": [
        "plumber"
    ],
    "locations": [
        "Houston, TX"
    ],
    "maxResults": 50
};

// Run the Actor and wait for it to finish
const run = await client.actor("mortenm/business-leads-overture").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 = {
    "categories": ["plumber"],
    "locations": ["Houston, TX"],
    "maxResults": 50,
}

# Run the Actor and wait for it to finish
run = client.actor("mortenm/business-leads-overture").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 '{
  "categories": [
    "plumber"
  ],
  "locations": [
    "Houston, TX"
  ],
  "maxResults": 50
}' |
apify call mortenm/business-leads-overture --silent --output-dataset

```

## MCP server setup

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

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/GMdihkEnDryUHBCnd/builds/XV0sBFfeVMJBqELb5/openapi.json
