# Google Maps Leads Scraper: Emails, Socials & Website Audit (`automationnation/google-maps-leads`) Actor

Scrape business leads from Google Maps in any country: phone, website, emails and social profiles, plus a website audit, a HOT/WARM/COLD lead score and a ready-to-send outreach email per lead. Filter for businesses without a website or new listings. Input: location + business type.

- **URL**: https://apify.com/automationnation/google-maps-leads.md
- **Developed by:** [Nathan Carter](https://apify.com/automationnation) (community)
- **Categories:** Lead generation, AI
- **Stats:** 5 total users, 2 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $24.00 / 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.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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 Leads Scraper

**Google Maps Leads Scraper is an Apify Actor that turns a Google Maps search into ready-to-contact business leads in any country.** For each business you get the phone, website, email and social profiles, a website audit, a HOT / WARM / COLD lead score with the reason, and a short outreach email written about that business. It costs $0.03 per lead.

#### Example result

"dentist" in Austin, TX, from a real run on 6 October 2026: 5 leads in about 2.5 minutes (contact details are omitted here, but the dataset includes them):

| Business | Phone | Email | Website | Lead score |
|---|---|---|---|---|
| Blunn Creek Family Dentistry | ✓ | ✓ | ✓ | COLD |
| ATX Family Dental | ✓ | ✓ | ✓ | COLD |
| South Austin Dentist | ✓ | – | – | WARM (no website: a lead for web agencies) |

Each lead also includes the rating and review count, social profiles, a website audit, an opening-date estimate and the reasons behind its HOT/WARM/COLD score.

#### Quick facts

- **What you get, one row per business:**
  - name, address, phone (international format), website, email
  - Facebook, Instagram, TikTok and LinkedIn profiles
  - Google rating and reviews, opening date estimate, unclaimed-listing flag
  - website audit score (0–10) with the issues found, and a Google profile score
  - HOT / WARM / COLD lead score with the reason
  - an AI-written outreach email, LinkedIn message and SMS
- **Any country:** search "Austin, TX", "Berlin" or "Sydney NSW"; set the country for local phone formatting and IPs (tested in the US and Germany). UK leads also get the Companies House director.
- **Built for outreach:** filters for businesses **without a website**, **unclaimed listings** and **recently opened** businesses.
- **Repeat runs:** incremental mode returns only businesses you haven't seen before, for scheduled lead feeds.
- **Delivery:** Google Sheets, HubSpot, Slack, email or any webhook, built in.
- **Price:** $0.03 per lead ($0.024 on Gold and above); $0.08 per lead found with the no-website or unclaimed filters. Businesses that don't match are free.
- **AI agents:** connect `https://mcp.apify.com?tools=automationnation/google-maps-leads`.

### Who is it for?

- **Web design, SEO and marketing agencies** finding local businesses with no website, a weak website or an unclaimed Google profile.
- **Sales teams and SDRs** who need local business leads with a contact route and a reason to reach out.
- **Suppliers and service businesses** (POS, signage, insurance, cleaning, accounting) reaching new openings.
- **Local SEO teams** auditing Google Business Profiles across a city.

### How it works

1. **Searches Google Maps** for each business type in each location, the way a person would.
2. **Reads each listing:** name, address, phone, website, rating, reviews, hours, category and whether it's unclaimed.
3. **Finds emails and social profiles** on the business website (homepage, contact and about pages). Hunter.io is an optional fallback.
4. **Audits the web presence:** a website score with specific issues (no mobile layout, no booking, no contact form…) and a Google profile completeness score.
5. **Scores the lead** HOT / WARM / COLD from newness, reviews and website quality, with the reason spelled out.
6. **Writes outreach copy** for HOT and WARM leads with built-in AI: an email, a LinkedIn message and an SMS that mention something real about the business.

### Find businesses without a website

Switch on **Only businesses without a website** to get local businesses that have no website on Google Maps (a Facebook or Instagram page doesn't count). Each comes with phone, address, rating, reviews and an outreach message pitching a website. Most businesses have a website, so finding each one means checking about ten listings: these leads cost $0.08 and runs take longer.

```json
{ "cities": ["Austin, TX"], "country": "us", "category": "hair salon", "noWebsiteOnly": true, "maxResults": 50 }
```

### Output example

One lead found with **Only businesses without a website** (Denver, hair salons):

```json
{
  "leadScore": "WARM",
  "leadScoreReason": "no website",
  "name": "BarberX Barbershop",
  "category": "barber",
  "address": "3320 Brighton Blvd, Denver, CO 80216",
  "phone": "+13034329923",
  "website": "",
  "profileScore": 6,
  "profileIssues": "no_website, no_hours, no_description",
  "rating": "4.8",
  "reviewCount": 563,
  "likelyNeeds": "website build with online booking; Google Business profile optimization (missing hours, description); appointment management system",
  "sentimentSummary": "Overwhelmingly positive with loyal repeat customers praising staff quality, though one recent payment policy complaint suggests operational friction.",
  "emailTemplate": "Hi there,\n\nI noticed BarberX doesn't have a website yet—that's leaving money on the table. Customers like the ones raving about Lauren and Jade can't easily book online or share you with friends. We build booking-ready websites specifically for barbershops so your regulars can book anytime, and new customers find you first.\n\nWould a 15-minute call to see how this could work for BarberX make sense?\n\nSam\nMile High Web Studio",
  "smsTemplate": "Hey—Sam from Mile High Web Studio. We build booking websites for Denver barbershops. Do you handle online appointments now, or mainly walk-ins?",
  "mapsUrl": "https://www.google.com/maps/place/BarberX+Barbershop/…"
}
```

Leads from established businesses with a good website come back as COLD, without outreach copy, so you can skip them.

### How to use it

1. Click **Try for free**.
2. Add **locations** (for example `Austin, TX`) and set the **country** (`us`).
3. Pick a **business type**, or add your own search terms such as `dentist` or `yoga studio`.
4. Optionally add filters (no website, unclaimed, recently opened, review counts) and your details for the outreach copy.
5. Click **Start**. Download the leads as CSV, Excel or JSON, or send them to Sheets, HubSpot, Slack or a webhook.

#### Input example

```json
{
  "cities": ["Austin, TX", "Dallas, TX"],
  "country": "us",
  "category": "hair salon",
  "maxResults": 100,
  "noWebsiteOnly": false,
  "scrapeEmails": true,
  "yourName": "Sam",
  "yourBusiness": "Lone Star Web Studio",
  "yourService": "booking-ready websites for salons"
}
```

### How much does it cost?

You pay only for leads saved to your dataset; businesses removed by your filters are free.

| Leads | Free & Bronze plans | Silver plan | Gold plan and above |
|---|---|---|---|
| 100 leads | $3 | $2.70 | $2.40 |
| 1,000 leads | $30 | $27 | $24 |
| 100 leads with "no website" or "unclaimed" on | $8 | $7.20 | $6.40 |

Compute, proxies, email finding and AI outreach copy are included. Set a **maximum cost per run** in the run options; the Actor stops at your limit and keeps every lead saved up to then.

### Use it with AI agents (MCP)

Add `https://mcp.apify.com?tools=automationnation/google-maps-leads` to Claude, ChatGPT, Cursor or another MCP client. Then ask, for example: "Find 20 dentists in Denver without a website and draft an outreach email for each."

### Integrations and API

```bash
curl -X POST "https://api.apify.com/v2/acts/automationnation~google-maps-leads/run-sync-get-dataset-items?token=YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"cities":["Austin, TX"],"country":"us","category":"hair salon","maxResults":10}'
```

Python and JavaScript: the `apify-client` package with Actor ID `automationnation/google-maps-leads`. Schedule weekly runs with incremental mode for a fresh-leads feed.

### FAQ

**Which countries does it support?**
Any country Google Maps covers. Set `country` to the two-letter code so phone numbers are formatted correctly and searches use local IPs when needed.

**Can it find businesses without a website?**
Yes: switch on **Only businesses without a website**.

**How long does a run take?**
About 10–15 minutes per 100 leads, because every lead gets its website checked, an audit and outreach copy.

**Is it legal to scrape Google Maps?**
It collects public business information. Use it in line with the privacy and marketing laws that apply to you (for example GDPR, CAN-SPAM or PECR), especially for cold email.

**Do I get company directors?**
For UK businesses (country `gb`), yes, from Companies House, with a confidence check. For the UK there's also the dedicated [Google Maps Leads Scraper UK](https://apify.com/automationnation/uk-business-leads).

**Guides:** [Code examples (Python, JavaScript, MCP)](https://retracn.github.io/automationnation-actors/google-maps-leads/)

### More from AutomationNation

- **[Google Maps Leads Scraper UK](https://apify.com/automationnation/uk-business-leads)**: UK leads with Companies House directors and postcode search.
- **[AI Visibility Tracker](https://apify.com/automationnation/ai-visibility-tracker)**: whether Google AI Overviews, Gemini and Claude mention and cite your brand.
- **[Google Jobs Scraper](https://apify.com/automationnation/google-jobs-scraper)**: job listings with salaries and employer apply links in 26 countries.

Questions or a missing field? Open an issue on the Actor's **Issues** tab. Fixes usually ship within a day.

# Changelog

This Actor's version history is a separate document: https://apify.com/automationnation/google-maps-leads/changelog.md

# Actor input Schema

## `cities` (type: `array`):

Cities or areas to search, e.g. \["Austin, TX", "Berlin, Germany"]. Add the state or country when a name is ambiguous. Each location is searched separately.

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

Two-letter country code for the locations (us, gb, ca, au, de, fr, es, …). Sets Google's region (results come back as Google shows them in that country), phone number formatting and the residential proxy country. UK (gb) leads also get Companies House directors.

## `category` (type: `string`):

Preset business type to search for. 'All Categories' searches every preset. Ignored when Custom search terms are set.

## `customSearchTerms` (type: `array`):

Optional. Search any business type instead of the presets, exactly as you would type it into Google Maps, e.g. \["accountant", "dentist", "wedding venue"]. Overrides Business type.

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

Maximum number of businesses (leads) to return across all cities and search terms. Each saved lead is one billable result. Start small (5–20) to test your filters.

## `dateRangeDays` (type: `integer`):

Optional. Set 30, 60 or 90 to keep only businesses whose opening date (Google's "Opened…" label, or the newest review on listings with fewer than 15 reviews) is within that many days. Businesses with no detectable opening date are kept. 0 = no date filter.

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

Skip businesses with fewer reviews than this. 0 includes brand-new listings.

## `maxReviews` (type: `integer`):

Skip businesses with more reviews than this, e.g. 30 to target new businesses still building their reputation. 0 = no limit.

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

Keep only businesses that list a website on Google Maps.

## `noWebsiteOnly` (type: `boolean`):

Keep only businesses with no website on Google Maps (a social-media page doesn't count as a website). Leads for web-design and digital agencies; the outreach copy pitches a website. Ignored if "Only businesses with a website" is also on.

## `requireUnclaimed` (type: `boolean`):

Keep only businesses that haven't claimed their Google Business Profile — often the easiest outreach targets.

## `scrapeEmails` (type: `boolean`):

Visit each business website (homepage plus /contact, /contact-us and /about) and extract the best email address. Adds a few seconds per lead.

## `hunterApiKey` (type: `string`):

Optional. Used only when no email is found on the website, to look one up on Hunter.io. Free keys at hunter.io.

## `anthropicApiKey` (type: `string`):

Optional — Claude is built in. Add your own key from console.anthropic.com only if you want dedicated capacity for very large runs.

## `geminiApiKey` (type: `string`):

Optional — used as the AI fallback. Add your own key from aistudio.google.com only for very large runs.

## `yourName` (type: `string`):

Signs the outreach email, LinkedIn and SMS drafts, e.g. "Sam".

## `yourBusiness` (type: `string`):

Your company name, e.g. "Northern Web Studio".

## `yourService` (type: `string`):

One line on what you sell, e.g. "websites and local SEO for new restaurants". The AI ties each message to this.

## `yourEmail` (type: `string`):

Contact email to include in the drafts.

## `yourPhone` (type: `string`):

Phone number to include in the SMS draft.

## `incrementalMode` (type: `boolean`):

Skip businesses returned by your earlier runs, so a weekly schedule only delivers new leads. History is kept per History name and forgets places after 180 days.

## `incrementalStateName` (type: `string`):

Optional label for the run history used by incremental mode, e.g. "manchester-gyms". Use a different label for each schedule so they don't share history. Blank = "default".

## `competitors` (type: `array`):

Optional. Google Maps listings to check for rating changes, new reviews and new negative reviews since the last run. Each entry: { "name": "Joe's Bistro", "mapsUrl": "https://maps.google.com/..." }. Up to 50.

## `deliverEmail` (type: `boolean`):

Send the leads as a CSV attachment after each run, using the SMTP settings below.

## `smtpHost` (type: `string`):

SMTP server hostname, e.g. smtp.gmail.com.

## `smtpPort` (type: `integer`):

Usually 587 (STARTTLS) or 465 (SSL).

## `smtpUser` (type: `string`):

SMTP login username.

## `smtpPass` (type: `string`):

SMTP login password or app password.

## `toEmail` (type: `string`):

Recipient email address for the CSV.

## `fromEmail` (type: `string`):

Sender address (defaults to the SMTP username).

## `deliverSheets` (type: `boolean`):

Append the leads to a Google Sheet after each run, using a service account.

## `serviceAccountJson` (type: `string`):

Full service account credentials JSON from Google Cloud Console. Share the sheet with the service account's email.

## `spreadsheetId` (type: `string`):

The ID from the sheet URL: /spreadsheets/d/{ID}/edit

## `sheetName` (type: `string`):

Tab to append to.

## `deliverWebhook` (type: `boolean`):

POST the leads to the webhook URL below. Setting a Webhook URL also turns this on.

## `webhookUrl` (type: `string`):

Zapier catch hook, Make or n8n webhook, or any HTTPS endpoint.

## `webhookFormat` (type: `string`):

JSON objects or CSV rows.

## `webhookPerRecord` (type: `boolean`):

Send one POST per lead instead of one combined payload. Needed for Zapier catch hooks and most CRMs.

## `deliverHubSpot` (type: `boolean`):

Create a HubSpot contact for each lead that has an email or phone. Needs a private app token with contacts write scope.

## `hubspotToken` (type: `string`):

HubSpot → Settings → Integrations → Private Apps.

## `deliverSlack` (type: `boolean`):

Post the top leads and any competitor alerts to a Slack channel.

## `slackWebhookUrl` (type: `string`):

Create one at api.slack.com/messaging/webhooks.

## `slackChannel` (type: `string`):

Override the channel, e.g. #leads. Blank = the webhook's default.

## `proxyConfiguration` (type: `object`):

Proxy used to load Google Maps. Automatic (default) starts with Apify datacenter IPs and switches to residential IPs in your country only if Google starts blocking — the most reliable and cheapest setup. Pick the Residential group to always use residential IPs in your country.

## Actor input object example

```json
{
  "cities": [
    "Austin, TX"
  ],
  "country": "us",
  "category": "restaurant",
  "customSearchTerms": [],
  "maxResults": 3,
  "dateRangeDays": 0,
  "minReviews": 0,
  "maxReviews": 0,
  "requireWebsite": false,
  "noWebsiteOnly": false,
  "requireUnclaimed": false,
  "scrapeEmails": true,
  "yourName": "",
  "yourBusiness": "",
  "yourService": "",
  "yourEmail": "",
  "yourPhone": "",
  "incrementalMode": false,
  "incrementalStateName": "",
  "competitors": [],
  "deliverEmail": false,
  "smtpHost": "",
  "smtpPort": 587,
  "toEmail": "",
  "fromEmail": "",
  "deliverSheets": false,
  "spreadsheetId": "",
  "sheetName": "Leads",
  "deliverWebhook": false,
  "webhookFormat": "json",
  "webhookPerRecord": false,
  "deliverHubSpot": false,
  "deliverSlack": false,
  "slackChannel": "",
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

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

No description

## `overview` (type: `string`):

No description

## `summary` (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 = {
    "cities": [
        "Austin, TX"
    ],
    "maxResults": 3
};

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

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

```

## MCP server setup

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