# Google Maps B2B Leads Scraper + Verified Emails ($3/1k) (`blessiticus/google-maps-leads-scraper-with-emails`) Actor

Scrape Google Maps businesses with phone numbers, websites, social profiles, owner names, and live SMTP-verified work emails. 0% bounce rate guarantee ($3 per 1,000 leads). Save 70%+ vs Apollo & Hunter.

- **URL**: https://apify.com/blessiticus/google-maps-leads-scraper-with-emails.md
- **Developed by:** [Mohammad Palekar](https://apify.com/blessiticus) (community)
- **Categories:** Lead generation, Marketing, Business
- **Stats:** 8 total users, 2 monthly users, 99.2% runs succeeded, 0 bookmarks
- **User rating**: 5.00 out of 5 stars

## Pricing

from $3.00 / 1,000 lead scrapeds

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 B2B Leads Scraper + Verified Emails ($3/1k)

[![Apify Actor](https://img.shields.io/badge/Apify-Actor-orange?logo=apify)](https://apify.com/blessiticus/google-maps-leads-scraper-with-emails)
[![Price](https://img.shields.io/badge/Price-%243%20%2F%201%2C000%20Leads-brightgreen)](https://apify.com/blessiticus/google-maps-leads-scraper-with-emails)
[![Free Tier](https://img.shields.io/badge/Free%20Tier-100%20Leads%20%2F%20Run-blue)](https://apify.com/blessiticus/google-maps-leads-scraper-with-emails)
[![Live SMTP Handshake](https://img.shields.io/badge/SMTP%20Verification-Live%20250%20OK-blue)](https://apify.com/blessiticus/google-maps-leads-scraper-with-emails)
[![Bounce Rate](https://img.shields.io/badge/Bounce%20Rate-%3C%201%25%20Guaranteed-success)](https://apify.com/blessiticus/google-maps-leads-scraper-with-emails)
[![Integrations](https://img.shields.io/badge/Integrations-Clay%20%7C%20Make%20%7C%20n8n%20%7C%20Zapier-blueviolet)](https://apify.com/blessiticus/google-maps-leads-scraper-with-emails)

Extract high-converting B2B local business leads from Google Maps complete with **Business Name, Category, Phone, Address, Website, Social Links (LinkedIn, Facebook, Instagram), Owner / Founder Names, and Live SMTP-Verified Work Emails**.

> \[!NOTE]
> 🎁 **Free Tier Included**: Extract up to **100 leads per run completely free** on trial accounts to test our multi-vector email discovery and live verification with zero upfront commitment!

Stop wasting hours downloading Google Maps places only to discover that 80% have no emails or bounce when you launch cold outreach. This Actor combines high-speed Google Maps extraction with an **automatic multi-vector website contact crawler** and **real-time SMTP mailbox verification (250 OK)** so every single lead is 100% campaign-ready out of the box.

***

> \[!TIP]
> **Already have an existing lead list to clean or find emails for?**
>
> - [**Email Verifier Pro**](https://apify.com/blessiticus/email-verifier-pro): Clean bulk email lists with live SMTP handshakes at **$0.85 per 1,000 emails**.
> - [**B2B Work Email Finder**](https://apify.com/blessiticus/b2b-work-email-finder-5-1k-find-emails-linkedin-or-domain): Find verified work emails from prospect Names & Company Domains at **$5 per 1,000 verified emails found**.

***

### Table of Contents

- [Features](#features)
- [Use Cases](#use-cases)
- [How It Works](#how-it-works)
- [Step-by-Step Guide](#step-by-step-guide)
- [Input Configuration](#input-configuration)
- [Output Data & Schema](#output-data--schema)
- [Integrations & API Examples](#integrations--api-examples)
- [Pricing & Free Tier](#pricing--free-tier)
- [Frequently Asked Questions (FAQ)](#frequently-asked-questions-faq)
- [Support & Feedback](#support--feedback)

***

### Features

| Feature | This Actor | Standard Google Maps Scrapers | Outscraper / PhantomBuster |
| :--- | :---: | :---: | :---: |
| **Price per 1,000 Leads** | **$3.00** | $3.50 – $5.00 | $10.00 – $30.00 |
| **Free Tier Allowance** | **100 Leads / Run** | 10 – 25 Leads | Limited / Trial only |
| **Live SMTP Mailbox Verification** | **✅ Real 250 OK Check** | ❌ None (or regex guess) | ❌ Stale database |
| **10x Lead Yield Engine** | **✅ Auto Metro Expansion** | ❌ Trapped at 100 cap | ❌ Manual suburb lists |
| **Multi-Vector Owner Detection** | **✅ 5-Stage Engine** | ❌ No | ❌ Add-on fee |
| **Cloudflare Email Deobfuscation** | **✅ Decodes `__cf_email__`** | ❌ Fails / Misses | ❌ Fails |
| **Fallback Executive Inboxes** | **✅ Tests `owner@`, `office@`** | ❌ Gives up | ❌ No |
| **Permutations for Missing Emails** | **✅ Generated & Verified** | ❌ Gives up | ❌ No |
| **Social Media Profiles** | **✅ LinkedIn, FB, IG, X, YT** | ❌ Basic or none | ✅ Extra credits |
| **Bounce Rate for Cold Email** | **< 1% Guaranteed** | ❌ 15% – 35% Bounces | ❌ 10% – 20% Bounces |
| **Extraction Latency** | **⚡ ~15ms DOM parser** | ❌ Slow 4GB RAM runs | ❌ Slow batch queues |

***

### Use Cases

- **Cold Email Outreach & B2B Sales Prospecting**: Generate laser-targeted prospect lists of local business owners with verified email addresses that will never bounce or burn your sending domain reputation.
- **Local Agency Client Acquisition**: Digital marketing, SEO, web design, and advertising agencies can easily find local businesses with low reviews, missing websites, or outdated web presences.
- **Recruitment & Staffing**: Target medical practices, dental clinics, accounting firms, and legal offices to reach decision-makers directly.
- **CRM Enrichment & Directory Building**: Populate your HubSpot, Salesforce, Pipedrive, or custom directories with complete business listings, phone numbers, addresses, and social links.
- **Market Research & Competitor Mapping**: Analyze competitor density, service offerings, review counts, and ratings across entire metropolitan areas.

***

### How It Works

Most Google Maps scrapers only do a naive regex search on the homepage HTML. If an email is hidden behind Cloudflare, obfuscated, or replaced with a contact form, competitors give up.

Our Actor uses an end-to-end **Multi-Vector Intelligence Pipeline** to achieve industry-leading email yield and decision-maker accuracy:

```text
                      Google Maps Places Extracted (~15ms DOM Parser)
                                            │
                                            ▼
                 ┌──────────────────────────────────────────────────────┐
                 │        STAGE 1: MULTI-VECTOR DISCOVERY ENGINE        │
                 ├──────────────────────────────────────────────────────┤
                 │ 1. Business Title Mining: "Dave's AC" → "Dave"       │
                 │ 2. Schema.org JSON-LD: Parses "founder", "employee"  │
                 │ 3. Cloudflare Decryptor: Unlocks __cf_email__ tags   │
                 │ 4. LinkedIn Link Mining: /in/{slug} → Executive Name │
                 │ 5. Deep Subpages: /team, /about, /doctors, /contact  │
                 └──────────────────────────┬───────────────────────────┘
                                            │
                                            ▼
                 ┌──────────────────────────────────────────────────────┐
                 │       STAGE 2: DECISION-MAKER PERMUTATION ENGINE     │
                 ├──────────────────────────────────────────────────────┤
                 │ When owner/founder is found:                         │
                 │ Generates corporate email permutations:              │
                 │ [dave@domain.com, d.miller@domain.com, etc.]         │
                 └──────────────────────────┬───────────────────────────┘
                                            │
                                            ▼
                 ┌──────────────────────────────────────────────────────┐
                 │     STAGE 3: EXECUTIVE INBOX RESCUE (NO EMAIL ON SITE)│
                 ├──────────────────────────────────────────────────────┤
                 │ If site only has a contact form (no plaintext email):│
                 │ Tests standard SMB inboxes live:                     │
                 │ [owner@, contact@, info@, office@, service@, admin@] │
                 └──────────────────────────┬───────────────────────────┘
                                            │
                                            ▼
                 ┌──────────────────────────────────────────────────────┐
                 │       STAGE 4: LIVE 250 OK SMTP MAILBOX HANDSHAKE    │
                 ├──────────────────────────────────────────────────────┤
                 │ Real-time socket check directly with mail exchanger: │
                 │ - Confirms recipient mailbox physically exists       │
                 │ - Detects catch-all & disposable domains             │
                 │ - Zero bounce rate guarantee (< 1%)                  │
                 └──────────────────────────────────────────────────────┘
```

1. **High-Speed DOM Extraction**: Evaluates Google Maps place cards directly in the browser runtime in ~15ms per batch, extracting titles, categories, reviews, phones, addresses, and website URLs.
2. **Business Title Entity Mining**: Local service businesses frequently incorporate the founder's name in their title (`Dave's Heating and Cooling`, `Dr. Sarah Jenkins Orthodontics`, `Carlos Mendez Plumbing`). Our NLP parser extracts the executive's name automatically.
3. **Schema.org JSON-LD Structured Data**: Modern WordPress, Wix, and Squarespace sites embed structured JSON-LD with `@type: "LocalBusiness"`, `"founder"`, and `"employee"` tags. We parse these structured signals with zero false positives.
4. **Cloudflare Email Deobfuscation**: Millions of local websites use Cloudflare to hide email addresses behind `data-cfemail` attributes. Our scraper decrypts them on the fly.
5. **Personal LinkedIn Profile Link Mining**: When a company links to their executive's personal profile (`linkedin.com/in/{slug}`), we parse the slug to extract the verified executive name.
6. **Smart Priority Subpage Crawling**: We crawl up to 4 high-priority subpages scored by link priority (`/team`, `/about-us`, `/our-team`, `/leadership`, `/doctors`, `/staff`, `/contact`, `/privacy`).
7. **Executive Inbox Rescue Engine**: When a business uses a contact form and never writes their email in plaintext, our engine tests high-priority executive inboxes (`owner@`, `contact@`, `info@`, `office@`, `service@`) live via SMTP. If an active mailbox exists, we capture it instantly!

***

### Step-by-Step Guide

Follow these steps to extract your first lead list in under 2 minutes:

1. **Select Target Country & City**: Use the pre-populated dropdowns to pick your target country (e.g. `United States 🇺🇸`) and major metro area (e.g. `Miami, FL`), or select `Other / Custom City` and type any custom location worldwide.
2. **Enter Business Niche**: Enter one or more categories in `searchTerms` (e.g., `HVAC contractors`, `Plumbers`, `Roofing companies`, `Dental clinics`).
3. **Keep 10x Lead Yield Enabled**: Ensure `autoExpandMetro` is checked (`true`). The engine will automatically generate suburb queries and industry synonyms to collect hundreds of leads across the entire metropolitan area.
4. **Click "Start"**: The Actor launches, streams progress messages in real time, and immediately pushes each verified lead into your dataset.
5. **Download Your Data**: Once complete, export your clean lead list in CSV, Excel, JSON, or XML format from the **Dataset** tab, or push leads directly to your CRM via Webhook.

***

### Input Configuration

#### Parameter Reference

| Parameter | Type | Default | Description |
| :--- | :---: | :---: | :--- |
| `country` | String (select) | `"US"` | Target country. Tunes regional business directories and search locale (`US`, `GB`, `CA`, `AU`, `DE`, `FR`, `GLOBAL`). |
| `targetCity` | String (select) | `"Miami, FL"` | Pre-configured metro dropdown (NYC, LA, Chicago, Miami, Dallas, London, Toronto, Sydney, etc.) or `CUSTOM`. |
| `customCity` | String | `""` | Custom city, town, or zip code when `CUSTOM` is selected above (e.g. `Boise, ID`, `Manchester, UK`). |
| `searchTerms` | Array of Strings | `["HVAC contractors"]` | Business categories or keywords to search. Also accepts direct Google Maps URLs! |
| `autoExpandMetro` | Boolean | `true` | **Recommended**. Automatically splits metros into suburbs and generates keyword synonyms to bypass Google's 100-result viewport cap. |
| `maxPlacesPerSearch` | Integer | `100` | Maximum number of places to collect ($0.003/lead). Set to `0` for unlimited leads. |
| `extractContacts` | Boolean | `true` | **Included free ($0)**. Crawls websites for emails, phones, social links, and owner names. |
| `verifyEmails` | Boolean | `true` | **+$0.002 per verified email found**. Executes live SMTP handshakes (250 OK) to guarantee 0% bounce rate. Toggle off if you only want scraped leads. |
| `onlyWithWebsite` | Boolean | `false` | When enabled, listings without a website are excluded from output. |
| `onlyWithEmail` | Boolean | `false` | When enabled, only leads with a verified deliverable email are saved. |
| `startUrls` | Array of Strings | `[]` | Direct Google Maps search links, coordinate zoom links, place URLs, or shortlinks. |
| `locations` | Array of Strings | `[]` | Additional custom cities or areas to search in addition to `targetCity`. |
| `concurrency` | Integer | `5` | Number of business websites to crawl and verify in parallel (1 to 15). |

#### Example 1: Easy Setup (Country & City Dropdown)

```json
{
  "country": "US",
  "targetCity": "Miami, FL",
  "searchTerms": ["HVAC contractors"],
  "autoExpandMetro": true,
  "maxPlacesPerSearch": 100,
  "extractContacts": true,
  "verifyEmails": true
}
```

#### Example 2: Direct Google Maps URLs

Paste exact Google Maps links directly into `startUrls` (supports coordinate zoom URLs, search links, and place links):

```json
{
  "startUrls": [
    "https://www.google.com/maps/search/HVAC+contractors/@25.7616798,-80.1917902,12z",
    "https://www.google.com/maps/search/plumbers+in+downtown+miami/",
    "https://maps.app.goo.gl/sampleShortlink"
  ],
  "maxPlacesPerSearch": 100,
  "extractContacts": true,
  "verifyEmails": true
}
```

***

### Output Data & Schema

All scraped leads are streamed into the default dataset. You can view them in the Apify Console as an interactive table, or download the full export as **CSV, Excel (XLSX), JSON, HTML, or XML**.

#### Output Field Reference

| Field | Type | Description |
| :--- | :---: | :--- |
| `title` | String | Official business name registered on Google Maps |
| `category` | String | Primary Google business category (e.g. `HVAC contractor`) |
| `phone` | String | Formatted international telephone number |
| `website` | String | Canonical URL of the business website |
| `domain` | String | Clean website domain root (e.g. `miamicoolingpros.com`) |
| `rating` | Number | Google Maps star rating score (1.0 to 5.0) |
| `reviewsCount` | Integer | Total count of public user reviews on Google Maps |
| `address` | String | Full physical street address |
| `city` | String | City name extracted from the listing address |
| `state` | String | State / province code extracted from the address |
| `googleMapsUrl` | String | Direct permanent link to the listing on Google Maps |
| `placeId` | String | Unique Google Place ID identifier |
| `email` | String | Discovered deliverable work or executive email address |
| `email_status` | String | Deliverability status: `valid`, `risky`, `invalid` |
| `confidence` | String | Discovery source (e.g. `high (owner permutation verified)`, `website plaintext`) |
| `is_catch_all` | Boolean | Whether the target domain is configured as a catch-all mailbox |
| `smtp_response` | String | Raw socket response code from the recipient mail server (`250 OK`) |
| `owner_name` | String | Identified business owner, founder, or executive name |
| `linkedin` | String | Company or executive LinkedIn profile URL |
| `facebook` | String | Official Facebook company page URL |
| `instagram` | String | Official Instagram profile URL |
| `twitter` | String | Official X / Twitter handle URL |
| `youtube` | String | Official YouTube channel URL |
| `scrapedAt` | String | ISO 8601 UTC timestamp of when the lead was extracted |

#### Sample JSON Output

```json
{
  "title": "Miami Cooling & Heating Pros",
  "category": "HVAC contractor",
  "phone": "+1-305-555-0199",
  "website": "https://miamicoolingpros.com",
  "domain": "miamicoolingpros.com",
  "rating": 4.9,
  "reviewsCount": 184,
  "address": "1200 Brickell Ave, Miami, FL 33131",
  "city": "Miami",
  "state": "FL",
  "googleMapsUrl": "https://www.google.com/maps/place/...",
  "placeId": "ChIJN1t_tDeuEmsRUsoyG83frY4",
  "searchQuery": "HVAC contractors in Miami, FL",
  
  "email": "john.miller@miamicoolingpros.com",
  "email_status": "valid",
  "confidence": "high (owner permutation verified)",
  "is_catch_all": false,
  "smtp_response": "250 OK — Mailbox exists",
  "owner_name": "John Miller",
  
  "linkedin": "https://www.linkedin.com/company/miami-cooling-pros",
  "facebook": "https://www.facebook.com/miamicoolingpros",
  "instagram": "https://www.instagram.com/miamicoolingpros",
  "twitter": "",
  "youtube": "",
  "scrapedAt": "2026-10-05T12:00:00.000Z"
}
```

***

### Integrations & API Examples

You can run this Actor programmatically or plug it directly into automated outbound workflows.

#### Node.js / JavaScript SDK

Install the official client:

```bash
npm install apify-client
```

```javascript
import { ApifyClient } from 'apify-client';

const client = new ApifyClient({
    token: 'YOUR_APIFY_TOKEN',
});

const input = {
    country: 'US',
    targetCity: 'Miami, FL',
    searchTerms: ['HVAC contractors'],
    autoExpandMetro: true,
    maxPlacesPerSearch: 50,
    extractContacts: true,
    verifyEmails: true,
};

// Run the Actor and wait for completion
const run = await client.actor('blessiticus/google-maps-leads-scraper-with-emails').call(input);

// Fetch items from the default dataset
const { items } = await client.dataset(run.defaultDatasetId).listItems();
for (const lead of items) {
    console.log(`🏢 ${lead.title} | 📞 ${lead.phone} | ✉️ ${lead.email} (${lead.email_status})`);
}
```

#### Python SDK

Install the official client:

```bash
pip install apify-client
```

```python
from apify_client import ApifyClient

client = ApifyClient("YOUR_APIFY_TOKEN")

run_input = {
    "country": "US",
    "targetCity": "Miami, FL",
    "searchTerms": ["HVAC contractors"],
    "autoExpandMetro": True,
    "maxPlacesPerSearch": 50,
    "extractContacts": True,
    "verifyEmails": True,
}

## Run the Actor and stream results
run = client.actor("blessiticus/google-maps-leads-scraper-with-emails").call(run_input=run_input)

for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(f"🏢 {item.get('title')} | 📞 {item.get('phone')} | ✉️ {item.get('email')} ({item.get('email_status')})")
```

#### Apify CLI & cURL (REST API)

Run directly via cURL:

```bash
curl -X POST "https://api.apify.com/v2/acts/blessiticus~google-maps-leads-scraper-with-emails/runs?token=YOUR_APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "country": "US",
    "targetCity": "Miami, FL",
    "searchTerms": ["Dentists"],
    "maxPlacesPerSearch": 25,
    "extractContacts": true,
    "verifyEmails": true
  }'
```

#### Clay.com Table Integration

1. In Clay, add an **HTTP API** enrichment column to your table.
2. Select Method: `POST`
3. Endpoint URL:
   ```text
   https://api.apify.com/v2/acts/blessiticus~google-maps-leads-scraper-with-emails/run-sync-get-dataset-items?token=YOUR_APIFY_TOKEN
   ```
4. Request Body:
   ```json
   {
     "country": "US",
     "targetCity": "Miami, FL",
     "searchTerms": ["Dentists"],
     "maxPlacesPerSearch": 25,
     "extractContacts": true,
     "verifyEmails": true
   }
   ```

***

### Pricing & Free Tier

This Actor operates on transparent **Pay-Per-Event (PPE)** pricing. You only pay for what you extract:

| Event | Price | Description |
| :--- | :---: | :--- |
| **Lead Scraped** | **$0.003 / lead** ($3.00 per 1,000) | Charged per business place extracted from Google Maps. |
| **Website & Social Scraping** | **$0.00 (Included Free)** | Crawls website for emails, phone numbers, and social links at no extra cost. |
| **Email Found & Verified** | **+$0.002 / email** ($2.00 per 1,000) | Charged only when a deliverable work email is found and verified via live SMTP (250 OK). |
| **Free Tier Allowance** | **100 Leads / Run Free** | Test email yield, data accuracy, and delivery with zero upfront commitment. |

> \[!NOTE]
> **Store Discounts**: Additional tiered discounts are automatically applied if you are subscribed to a paid Apify plan.

***

### Frequently Asked Questions (FAQ)

#### How do you extract emails when a business only has a contact form?

Most competitors give up when there is no `mailto:` link on the homepage. Our Actor extracts founder names from business titles (`Dave's Heating` → `Dave`), parses Schema.org JSON-LD for employees/founders, and if no email is written in plaintext, our **Executive Rescue Engine** tests standard executive mailboxes (`owner@`, `contact@`, `info@`, `office@`, `service@`) live via SMTP. If an active mailbox exists, we capture it instantly!

#### How does the Free Tier work?

Every user on the Apify platform can extract up to **100 leads per run completely free** on trial runs! This gives you plenty of free quota to test email yield, data accuracy, and verify deliverability before scaling up.

#### What does 250 OK SMTP Verification mean?

We connect directly to the business mail exchanger and perform a handshake protocol (`HELO` / `MAIL FROM` / `RCPT TO`). If the mail server replies `250 OK`, the mailbox physically exists. If it replies `550 User not found`, we discard it so your outreach emails never bounce.

#### How do I bypass Google's 100-result viewport limit to get 1,000+ leads?

Google Maps enforces a platform-level ceiling: for any **single search query or map viewport**, Google only displays a maximum of **~100–120 places** before displaying *"You've reached the end of the list"*.
To extract **500 to 2,000+ leads** across a metro area:

1. **Leave `autoExpandMetro` enabled (default)**: The backend automatically splits the metropolitan area into surrounding municipalities and expands your niche into related synonyms.
2. **Add Custom Locations**: In `locations`, add surrounding suburbs or postal codes (e.g. `Coral Gables, FL`, `Fort Lauderdale, FL`, `Doral, FL`).
3. **Use Direct Zoom URLs**: Zoom into specific districts on Google Maps and paste those URLs into `startUrls`.

#### Can I scrape multiple cities at once?

Yes! Simply provide multiple locations in the `locations` input (e.g. `Miami, FL`, `Orlando, FL`, `Tampa, FL`). The Actor automatically iterates through each location and aggregates all leads into a single dataset.

#### Can I scrape without verifying emails?

Yes. If you only want local business information (names, phones, addresses, ratings, websites, and social links) and do not need SMTP mailbox validation, set `verifyEmails: false`. You will only be billed the base rate of $0.003 per lead ($3/1k).

***

### Support & Feedback

If you encounter any issues, need custom adaptations, or have questions about scaling your lead generation workflows:

- Submit an issue on the **Issues** tab in the Apify Console.
- Leave a review or feedback on the Actor's Apify Store page.
- Our team monitors runs and updates scraping algorithms regularly to keep up with Google Maps UI updates.

# Actor input Schema

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

Select target country. Automatically tunes regional business directories and geolocation.

## `targetCity` (type: `string`):

Select your target metropolitan area from top business hubs. The backend automatically expands this into surrounding suburbs and municipalities to 10x your lead count.

## `customCity` (type: `string`):

Type any custom city, town, or zip code worldwide (e.g. 'Boise, ID', 'Manchester, UK', 'Vancouver, BC'). Leave empty if using the Metro Dropdown above.

## `searchTerms` (type: `array`):

Business niche or keyword to search (e.g. 'HVAC', 'Plumbers', 'Roofing', 'Dentists', 'Lawyers'). The engine automatically expands it into related industry categories.

## `autoExpandMetro` (type: `boolean`):

When enabled (recommended), the backend automatically breaks the target city into surrounding suburbs, municipalities, and keyword variations in the backend to bypass Google's 100-result limit and extract 500-2,000+ leads.

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

Maximum number of places to collect ($0.003/lead = $3/1k leads). Set to 0 or leave empty for ALL available leads. Free tier trial capped at 100 leads.

## `extractContacts` (type: `boolean`):

Automatically crawl the business website to discover emails, phone numbers, social links, and owner/founder names. Included in the base $3/1k lead price (no extra charge).

## `verifyEmails` (type: `boolean`):

Perform real-time SMTP handshakes (250 OK) to guarantee 0% bounce rate (< 1%). Adds +$0.002 per verified deliverable email found ($2 per 1,000 verified emails). You are ONLY charged when an email is successfully found. Toggle OFF if you only want scraped leads without email verification ($3/1k only).

## `onlyWithWebsite` (type: `boolean`):

Filter out listings that do not have a business website registered on Google Maps.

## `onlyWithEmail` (type: `boolean`):

Save only records where a valid corporate email was successfully discovered and verified. Leads without a verified email are discarded.

## `startUrls` (type: `array`):

Paste direct Google Maps URLs. Supports: 1) Zoom/Coordinate area URLs ('https://www.google.com/maps/search/HVAC/@25.76,-80.19,12z'), 2) Search URLs ('https://www.google.com/maps/search/plumbers+in+miami/'), 3) Single place links ('https://www.google.com/maps/place/...'), 4) Shortlinks ('https://maps.app.goo.gl/...').

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

Leave empty if using Target City above, or enter custom cities/states/zip codes here.

## `concurrency` (type: `integer`):

Number of business websites to crawl and verify in parallel.

## Actor input object example

```json
{
  "country": "US",
  "targetCity": "Miami, FL",
  "searchTerms": [
    "HVAC contractors"
  ],
  "autoExpandMetro": true,
  "maxPlacesPerSearch": 100,
  "extractContacts": true,
  "verifyEmails": true,
  "onlyWithWebsite": false,
  "onlyWithEmail": false,
  "startUrls": [],
  "locations": [],
  "concurrency": 5
}
```

# Actor output Schema

## `defaultDatasetUrl` (type: `string`):

URL to the dataset containing the scraped leads and verified emails

# 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 = {
    "searchTerms": [
        "HVAC contractors"
    ],
    "startUrls": [],
    "locations": []
};

// Run the Actor and wait for it to finish
const run = await client.actor("blessiticus/google-maps-leads-scraper-with-emails").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 = {
    "searchTerms": ["HVAC contractors"],
    "startUrls": [],
    "locations": [],
}

# Run the Actor and wait for it to finish
run = client.actor("blessiticus/google-maps-leads-scraper-with-emails").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 '{
  "searchTerms": [
    "HVAC contractors"
  ],
  "startUrls": [],
  "locations": []
}' |
apify call blessiticus/google-maps-leads-scraper-with-emails --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,blessiticus/google-maps-leads-scraper-with-emails"
        }
    }
}
```

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/NuakMxyAyThIlVXzA/builds/bViFybQppP4gC0N29/openapi.json
