# Google Maps Scraper: Business Leads, Phones & Market Report (`precious_bathmat/google-maps-business-leads`) Actor

Scrape Google Maps businesses for any search and location: name, phone, website, address, rating, reviews, hours, category, coordinates. Deep search finds 4x more than one search. Lead flags (no website, few reviews) and a market report per search. No login.

- **URL**: https://apify.com/precious\_bathmat/google-maps-business-leads.md
- **Developed by:** [Mariam Ahmed](https://apify.com/precious_bathmat) (community)
- **Categories:** Lead generation, Marketing
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $20.00 / 1,000 search reports

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

## Google Maps Scraper: Business Leads, Phones & Market Report

Scrape **Google Maps** for any business type in any city and get a clean **lead list**: name, **phone**, **website**, address, **rating**, **review count**, opening hours, categories, coordinates and the Google Maps link. No login, no API key.

On top of the raw list you get what the other Google Maps scrapers leave to you:

- **Lead flags** on every business: **no website**, only a Facebook or directory page, **fewer than 10 reviews**, rated under 4.0, no phone, no hours
- **Deep search** that splits a city into a grid and finds **4 to 6 times more businesses** than Google's usual ~150 per search
- A **market report per search**: how many businesses, average rating, median reviews, **share without a website**, top competitors and the best prospects

### What does this Google Maps scraper do?

```
plumbers in Nairobi · 100 businesses                 dentists in Austin, TX · 100 businesses
 average rating 4.73, median 4 reviews                average rating 4.86, median 420 reviews
 55 without a website, 3 social-only                  0 without a website
 65 with fewer than 10 reviews                        → a mature market, few easy prospects
 → a market full of web-design and SEO prospects
```

1. Enter **what to search** ("plumbers", "dentists", "italian restaurants") and **where** ("Austin, TX", "Westlands, Nairobi", "SW1A 1AA"). Every search runs in every location.
2. Choose the **depth**: normal (up to ~150 per search, like Google Maps), deep (3×3 grid) or deeper (5×5 grid).
3. Optionally keep only **leads**, a minimum rating or review count, or certain categories.
4. You get **one row per business** and **one market report per search**.

```mermaid
flowchart LR
    A[Searches ×<br/>locations] --> B{Depth}
    B -->|normal| C[One search<br/>up to ~150]
    B -->|deep / deeper| D[3×3 or 5×5 grid<br/>over the location]
    C --> E[Businesses<br/>phone, website, rating,<br/>reviews, hours, lead flags]
    D --> E
    E --> F[Market report<br/>per search]
```

### Who is it for?

- **Web designers, SEO and marketing agencies**: find local businesses with **no website**, a Facebook-only page or **few reviews**, with their phone numbers
- **Sales teams**: build call lists of every business of a type in a territory
- **Franchise and expansion planners**: compare how crowded and how well-rated a market is before opening
- **Local SEO**: see who ranks, how many reviews the leaders have, and what it takes to compete

### What data do you get?

**Business** (dataset, one row each)

| Field | What it tells you |
|---|---|
| `name`, `category`, `categories`, `description` | What the business is |
| `phone`, `phoneInternational` | How to call it |
| `website`, `websiteDomain`, `websiteType` | Its site, and whether it is its **own** site, a **social** page or a **directory** listing |
| `rating`, `reviews` | Reputation |
| `address`, `neighborhood`, `city`, `countryCode`, `latitude`, `longitude`, `serviceAreaBusiness` | Where it is |
| `openingHours`, `openNow`, `timezone` | When it is open |
| `leadFlags` | `noWebsite`, `socialOnly`, `directoryOnly`, `fewReviews`, `lowRating`, `noPhone`, `noHours` |
| `placeId`, `cid`, `googleMapsUrl` | Google's ids and the Maps link |
| `search`, `location`, `rank` | Which search found it and where it ranked |

**Market report** (`MARKET_REPORTS`, one per search): `businesses`, `averageRating`, `medianRating`, `medianReviews`, `ratingBands`, `withOwnWebsitePercent`, `withoutWebsite`, `socialOrDirectoryOnly`, `withPhonePercent`, `leadFlagCounts`, `topCategories`, `mostReviewed`, `bestRated`, `prospectsWithoutOwnWebsite`.

### Example: 30 September 2026

Six searches (plumbers and dentists × Austin, Nairobi, London), **600 businesses in 96 seconds**:

| Search | Avg rating | Median reviews | Own website | No website | Fewer than 10 reviews |
|---|---|---|---|---|---|
| plumbers in Austin, TX | 4.81 | 149 | 96% | 2 | 0 |
| plumbers in London | 4.82 | 77.5 | 95% | 4 | 4 |
| plumbers in Nairobi | 4.73 | 4 | 42% | **55** | **65** |
| dentists in Austin, TX | 4.86 | 420 | 100% | 0 | 0 |
| dentists in Nairobi | 4.82 | 50 | 87% | 13 | 19 |

**Deep search**: "plumbers" in Chicago with the 5×5 grid found **930 businesses** in about 4 minutes, **291 of them without a website**, against about 150 from a single Google Maps search.

**Leads only**: restaurants in Westlands, Nairobi, with "Leads only" and at least 1 review, kept 73 of 150; 63 of the 150 had no website.

### Pricing

**$0.02 per search report** (one search in one location) and **$0.002 per business** saved, i.e. **$2 per 1,000 businesses**.

100 businesses cost **$0.22**. The six-search example above cost **$1.32**, and the 930-business deep search **$1.88**. "Leads only" and the other filters mean you pay only for the rows you keep.

### Good to know

- **Normal search = what Google Maps shows**: up to about 150 businesses per search. For more, use **deep** or **deeper**, or add several neighborhoods or postcodes as locations.
- **Locations** can be cities, neighborhoods, postcodes, states or countries. A bare postcode is completed with the **country** setting. If Google does not recognise a location, the text search is used and the run summary says so.
- **Service-area businesses** (many plumbers, cleaners, movers) hide their address on Google. Their `address` and `city` are empty and `serviceAreaBusiness` is true; they are often the best leads.
- Google sometimes sends a lighter answer without review counts or full hours. The Actor fetches those pages again; if it persists, `reviews` and `openingHours` are **empty, never a false zero**, and `partialDetails` is true.
- **Business listings only**: no reviews, reviewer names or personal profiles are collected.
- Grid searches can reach a little beyond the location's edges; use `city` to trim.

### Input

| Field | Meaning |
|---|---|
| **What to search** | Business types or keywords |
| **Locations** | Cities, neighborhoods, postcodes… |
| **Search depth** | Normal, deep (3×3), deeper (5×5) |
| **Maximum businesses per search** | 1 to 3,000 (default 200) |
| **Leads only** | Only businesses with a lead flag |
| **Minimum rating / reviews** | Filters for the saved rows |
| **Categories to keep** | e.g. "plumber" drops supply stores |
| **Language / Country** | e.g. en / us, es / mx, en / ke |
| **Skip duplicates** | Each business once across searches |

### Integrations

Export to CSV, Excel, JSON or Google Sheets, or send the leads to your CRM through the Apify API, webhooks, Make, Zapier and n8n. **Schedule it** weekly to catch new businesses in your territory.

# Actor input Schema

## `searches` (type: `array`):

Business types or keywords, as you would type them in Google Maps: "plumbers", "dentists", "italian restaurants". Without a location below, include it here: "dentists in Chicago".

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

Cities, neighborhoods, postcodes, states or countries: "Austin, TX", "Westlands, Nairobi", "SW1A 1AA". Every search runs in every location.

## `searchDepth` (type: `string`):

Normal: one search, up to about 150 businesses, as Google Maps shows. Deep: the location is split into a 3x3 grid (about 4x more businesses). Deeper: a 5x5 grid, for big cities and full coverage.

## `maxPlacesPerSearch` (type: `integer`):

Stop each search (one keyword in one location) after this many businesses (1 to 3,000).

## `leadsOnly` (type: `boolean`):

Save only businesses with a lead flag: no website, only a social media or directory page, fewer than 10 reviews, or rated under 4.0. The market report still covers every business.

## `minRating` (type: `number`):

Save only businesses rated at least this (0 to 5). 0 = no filter.

## `minReviews` (type: `integer`):

Save only businesses with at least this many reviews. 0 = no filter.

## `categoryFilter` (type: `array`):

Optional: save only businesses whose Google category contains one of these words, e.g. "plumber" drops handymen and supply stores from a plumbers search.

## `language` (type: `string`):

Language of categories, hours and descriptions: en, es, fr, de, pt…

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

Two-letter country code Google uses for the search, e.g. us, gb, ke, in. Also completes bare postcodes.

## `skipDuplicates` (type: `boolean`):

Save each business once, even if several searches find it.

## Actor input object example

```json
{
  "searches": [
    "plumbers"
  ],
  "locations": [
    "Austin, TX"
  ],
  "searchDepth": "normal",
  "maxPlacesPerSearch": 200,
  "leadsOnly": false,
  "minRating": 0,
  "minReviews": 0,
  "language": "en",
  "country": "us",
  "skipDuplicates": true
}
```

# Actor output Schema

## `businesses` (type: `string`):

One row per business: name, category, phone, website, rating, reviews, address, hours, coordinates, lead flags, Google Maps link.

## `reports` (type: `string`):

Per search: number of businesses, ratings, reviews, share with a website, lead counts, top competitors, prospects without a website.

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

Searches, problems and the limits of 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 = {
    "searches": [
        "plumbers"
    ],
    "locations": [
        "Austin, TX"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("precious_bathmat/google-maps-business-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 = {
    "searches": ["plumbers"],
    "locations": ["Austin, TX"],
}

# Run the Actor and wait for it to finish
run = client.actor("precious_bathmat/google-maps-business-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 '{
  "searches": [
    "plumbers"
  ],
  "locations": [
    "Austin, TX"
  ]
}' |
apify call precious_bathmat/google-maps-business-leads --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,precious_bathmat/google-maps-business-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/lD7IaYVLfhvBJ3NaY/builds/sFtoDYDZ9TEoA1KyR/openapi.json
