# 📧 Google Maps Email And Phone Number Scraper (`citrine_venus/google-maps-email-and-phone-number-scraper`) Actor

Find business emails and phone numbers behind Google Maps places: scrape listings, then crawl each website for emails, phones, socials and contact pages. Email verification, dedupe, generic-address filters. No API key needed.

- **URL**: https://apify.com/citrine\_venus/google-maps-email-and-phone-number-scraper.md
- **Developed by:** [Data Minds](https://apify.com/citrine_venus) (community)
- **Categories:** Lead generation, SEO tools, Travel
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $5.00 / 1,000 results

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.

Learn more: https://docs.apify.com/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## 📧 Google Maps Email And Phone Number Scraper — Business Email Finder & Contact Extractor

**Google Maps Email And Phone Number Scraper** is a production-grade [Apify Actor](https://docs.apify.com/platform/actors) that answers one question fast: **how do I contact this business?** Give it a business type and an area — `dentist` in `Denver, Colorado` — and it returns one clean contact row per business: **best email address**, every email found, the **Google phone number**, every phone published on the website, and **LinkedIn / Instagram / Facebook / X / YouTube / TikTok / Pinterest / Discord** profiles — streamed into your Apify **Dataset** as they are found.

> 💡 **Need a custom version, private integration, or a tailored contact-enrichment pipeline?** Email **<hello.dataminds@gmail.com>**.

Built for **cold email outreach**, **cold calling**, **lead enrichment**, **recruiting**, **partnership scouting** and **CRM hygiene** — anyone who needs **business emails and phone numbers** rather than a full business dump.

***

### 📑 Table of contents

- [What is Google Maps Email And Phone Number Scraper?](#-what-is-google-maps-email-and-phone-number-scraper)
- [Main features](#-main-features)
- [Who is this Actor for?](#-who-is-this-actor-for)
- [How the contact hunt works](#%EF%B8%8F-how-the-contact-hunt-works)
- [Contact rules you control](#%EF%B8%8F-contact-rules-you-control)
- [Email verification explained](#-email-verification-explained)
- [Output format (Dataset)](#-output-format-dataset)
- [Example output (JSON)](#-example-output-json)
- [Quick start](#-quick-start)
- [Input parameters reference](#%EF%B8%8F-input-parameters-reference)
- [Integrations & automation](#-integrations--automation)
- [Frequently asked questions (FAQ)](#-frequently-asked-questions-faq)
- [Troubleshooting](#%EF%B8%8F-troubleshooting)
- [Help, support & custom builds](#-help-support--custom-builds)
- [Is scraping business contacts legal?](#%EF%B8%8F-is-scraping-business-contacts-legal)
- [SEO keywords targeted](#-seo-keywords-targeted)

***

### 📧 What is Google Maps Email And Phone Number Scraper?

Google Maps lists the phone number of a business, but never the email address — that lives on the business website, usually two clicks deep on a contact page. Collecting that by hand is the slowest part of building any outreach list.

This Actor closes the gap and hands you a **contact-first table**:

- **Finds the businesses** matching your search in the area you choose.
- **Takes the phone number** Google publishes and keeps it in both display and dialable form.
- **Opens the business website**, plus its contact and about pages, and extracts **every email address and phone number** published there.
- **Picks the best one for you** — `primaryEmail` prefers an address on the company's own domain, `primaryPhone` prefers the verified Google number.
- **Cleans the list** — drop free mailboxes, drop generic `info@` inboxes, remove duplicates across the entire run, cap emails per business.
- **Verifies deliverability on request** — disposable, free-mail and role checks plus a mail-server probe. No third-party key.
- **Streams every row live** to your dataset — export to **JSON**, **CSV**, **Excel**, **XML**, or pull it through the [Apify API](https://docs.apify.com/api/v2).

***

### ✨ Main features

- 📧 **Email finder** — homepage + contact/about pages, junk-domain filtering, image-file filtering.
- 🥇 **Best contact picked for you** — `primaryEmail` and `primaryPhone` are ready to paste into a sequence.
- ☎️ **Three phone sources, kept apart** — Google's listed number, `tel:` links from the site, and loose text matches in a separate `otherPhones` column so you always know how confident to be.
- 🔗 **8 social networks** discovered and deduplicated.
- 🧹 **Contact hygiene** — business-emails-only mode, generic-inbox skipping, run-wide deduplication, per-business caps.
- ✅ **Only-with-email / only-with-phone modes** — a row is saved only when it is actually actionable.
- 🧪 **Built-in verification** — free / role / disposable flags, MX lookup and an SMTP deliverability probe.
- 🎯 **Prospect filters** — category keywords, name matching, minimum rating, website presence, closed places, big chains.
- 🏪 **Optional full business profile** — attach every Google Maps field under `businessDetails` when you need more than contacts.
- 🚦 **Blocking handled for you** — the run adapts on its own when a site pushes back, with no configuration required.
- 📦 **Live dataset writes** and **seven prebuilt views** — Contact Overview, Emails, Phones, Socials, Verification, Business & Location, Source & IDs.

***

### 👥 Who is this Actor for?

- 📬 **Cold email teams** — build a clean, deduplicated address list in minutes.
- 📞 **Cold calling & telesales** — phone-first lists with the verified Google number plus website numbers.
- 🧲 **Lead-gen agencies** — deliver contact data per niche and city on demand.
- 🧑‍💼 **Recruiters** — reach local employers directly instead of through a portal.
- 🤝 **Partnership & BD teams** — find the right inbox for outreach at scale.
- 🗃️ **RevOps / CRM teams** — fill in missing emails, phones and socials on existing accounts.
- 🧑‍💻 **Developers** — a simple **business email API** with no scraping stack to maintain.

***

### ⚙️ How the contact hunt works

1. **Search** — each term is looked up in your chosen area, page after page, deduplicated by place.
2. **Filter early** — rating, category, website presence and closed status are applied before any website is opened.
3. **Read the listing** — business name, category, address, rating and the Google phone number.
4. **Crawl the website** — homepage plus up to 10 contact/about pages per business.
5. **Extract & clean** — emails, phones and socials are collected, filtered by your rules, then deduplicated.
6. **Verify (optional)** — every surviving address gets a quality verdict.
7. **Save immediately** — each contact row lands in your dataset the moment it is ready.

***

### 🎛️ Contact rules you control

| Rule | What it does |
|---|---|
| 📧 **Only keep businesses with an email** | Rows without an address are dropped; the search is automatically limited to businesses that publish a website |
| ☎️ **Only keep businesses with a phone** | Rows without any phone number are dropped |
| 🏢 **Business emails only** | Skips gmail.com, yahoo.com, outlook.com and friends |
| 🙋 **Skip generic inboxes** | Skips `info@`, `sales@`, `support@`, `contact@` and similar role addresses |
| ♻️ **Remove duplicate emails** | The same address is never returned twice in one run |
| 🔢 **Max emails per business** | Caps how many addresses each row keeps |
| 📄 **Extra pages per website** | How deep to look for a contact page (0–10) |
| 🏬 **Skip big chain websites** | Chains rarely publish a reachable inbox |

***

### 🧪 Email verification explained

Turn on **Verify email addresses** and each address gets a verdict:

| Field | Meaning |
|---|---|
| `quality` | `good`, `bad` or `unknown` — the summary you can filter on |
| `result` | `ok`, `invalid`, `disposable` or `unknown` |
| `subResult` | Why — `accepted_email`, `rejected_email`, `no_mx_record`, `disposable_domain`, `smtp_unreachable` |
| `free` | The domain is a free mailbox provider |
| `role` | The address is a role inbox rather than a person |
| `email` | The address the verdict belongs to |
| `error` | Empty unless the check itself failed, then the reason |

> ℹ️ Cloud networks routinely block outbound mail ports. When that happens the verdict is `unknown` — deliberately, rather than guessing a false `good`.

***

### 📤 Output format (Dataset)

One row per business, contact fields first. The Output tab ships with **seven prebuilt views**:

| View | What it shows |
|---|---|
| ✨ **Contact Overview** | Business, best email, best phone, website, counts, city, Maps link |
| 📧 **Emails** | Domain, best email, every email, count, has-email flag |
| ☎️ **Phone Numbers** | Best phone, Google phone, dialable format, website phones, other numbers |
| 🔗 **Social Profiles** | LinkedIn, Instagram, Facebook, X, YouTube, TikTok, Pinterest, Discord |
| 🧪 **Email Verification** | Per-address verdicts and the deliverable count |
| 🏪 **Business & Location** | Category, rating, address parts, coordinates, photo |
| 🧭 **Source & IDs** | Rank, search term, place ID, CID, Maps link, collected timestamp |

#### Field groups in every row

| Group | Fields |
|---|---|
| **Business** | `businessName`, `categoryName`, `website`, `domain`, `address`, `city`, `state`, `postalCode`, `countryCode`, `location`, `totalScore`, `permanentlyClosed`, `temporarilyClosed`, `imageUrl` |
| **Email** | `primaryEmail`, `emails`, `emailCount`, `hasEmail` |
| **Phone** | `primaryPhone`, `googlePhone`, `googlePhoneUnformatted`, `websitePhones`, `otherPhones`, `phoneCount`, `hasPhone` |
| **Social** | `socialProfilesCount`, `linkedIns`, `instagrams`, `facebooks`, `twitters`, `youtubes`, `tiktoks`, `pinterests`, `discords` |
| **Verification** | `emailsVerification`, `verifiedEmailCount` |
| **Source** | `rank`, `searchString`, `placeId`, `cid`, `url`, `scrapedAt` |
| **Optional** | `businessDetails` — the complete Google Maps profile when you switch it on |

A **run summary** — totals, per-search counts and contact coverage — is stored in the key-value store as `run-summary`.

***

### 🧪 Example output (JSON)

```json
{
  "rank": 2,
  "searchString": "dentist",
  "businessName": "Icon Dental",
  "categoryName": "Dentist",
  "website": "https://icondentaldenver.com/",
  "domain": "icondentaldenver.com",
  "primaryEmail": "info@icondentaldenver.com",
  "emails": ["info@icondentaldenver.com"],
  "emailCount": 1,
  "hasEmail": true,
  "primaryPhone": "+17206452153",
  "googlePhone": "(720) 645-2153",
  "googlePhoneUnformatted": "+17206452153",
  "websitePhones": ["17206452153", "7206452153"],
  "otherPhones": ["720-645-2153", "720.645.2167"],
  "phoneCount": 3,
  "hasPhone": true,
  "socialProfilesCount": 2,
  "linkedIns": [],
  "instagrams": ["https://www.instagram.com/icon_dental_denver/"],
  "facebooks": ["https://www.facebook.com/IconDentalDenver/"],
  "twitters": [],
  "youtubes": [],
  "tiktoks": [],
  "pinterests": [],
  "discords": [],
  "address": "Icon Dental, 1425 Market St Ste. 100, Denver, CO 80202",
  "city": "Denver",
  "state": "Colorado",
  "postalCode": "80202",
  "countryCode": "US",
  "location": { "lat": 39.7485634, "lng": -105.0004756 },
  "totalScore": 4.6,
  "permanentlyClosed": false,
  "temporarilyClosed": false,
  "placeId": "ChIJ…",
  "cid": "0x876c78…",
  "url": "https://www.google.com/maps?cid=…",
  "imageUrl": "https://lh5.googleusercontent.com/…",
  "emailsVerification": [],
  "verifiedEmailCount": 0,
  "scrapedAt": "2026-07-30T09:14:22.104Z"
}
```

***

### 🚀 Quick start

#### Run in Apify Console

1. Log in at [console.apify.com](https://console.apify.com) → **Actors**.
2. Open **Google Maps Email And Phone Number Scraper**.
3. Enter a **business search term** (`dentist`) and a **location** (`Denver, Colorado`).
4. Set **Businesses per search term** to `10` for a first test.
5. *(Optional)* switch on **Only keep businesses with an email** and **Business emails only**.
6. Click **Start** and watch each contact row appear live in the log.
7. Open the **Output** tab, switch between the seven views, and export to JSON / CSV / Excel.

#### Run via API

```bash
curl -X POST "https://api.apify.com/v2/acts/YOUR_ACTOR_ID/runs?token=YOUR_APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "searchStringsArray": ["dentist"],
    "locationQuery": "Denver, Colorado",
    "maxCrawledPlacesPerSearch": 25,
    "onlyWithEmail": true,
    "excludeFreeEmails": true
  }'
```

Fetch the results once the run finishes:

```bash
curl "https://api.apify.com/v2/datasets/YOUR_DATASET_ID/items?token=YOUR_APIFY_TOKEN&format=csv"
```

#### Python client

```python
from apify_client import ApifyClient

client = ApifyClient("YOUR_APIFY_TOKEN")
run = client.actor("YOUR_ACTOR_ID").call(run_input={
    "searchStringsArray": ["law firm", "accountant"],
    "locationQuery": "Chicago, Illinois",
    "maxCrawledPlacesPerSearch": 50,
    "onlyWithEmail": True,
    "excludeGenericEmails": False,
    "verifyEmails": True,
})

for row in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(row["businessName"], row["primaryEmail"], row["primaryPhone"])
```

***

### 🛠️ Input parameters reference

#### 🚀 Who are you looking for?

| Parameter | Type | Default | Description |
|---|---|---|---|
| `searchStringsArray` | array | — | **Required.** Business search terms, one per line |
| `locationQuery` | string | — | Free-text area, e.g. `Denver, Colorado` |
| `maxCrawledPlacesPerSearch` | integer | `20` | Businesses looked up per term |
| `startUrls` | array | `[]` | Google Maps place URLs — full, `?cid=…`, `?place_id=…` or short links (bulk supported) |

#### 📧 Contact rules

| Parameter | Type | Default | Description |
|---|---|---|---|
| `onlyWithEmail` | boolean | `false` | Keep only businesses with an email |
| `onlyWithPhone` | boolean | `false` | Keep only businesses with a phone |
| `excludeFreeEmails` | boolean | `false` | Company-domain addresses only |
| `excludeGenericEmails` | boolean | `false` | Skip `info@`, `sales@`, `support@`… |
| `dedupeEmails` | boolean | `true` | Never return the same address twice |
| `maxEmailsPerPlace` | integer | `10` | Cap addresses kept per business |
| `contactMaxSubpages` | integer | `3` | Extra contact/about pages per website |
| `verifyEmails` | boolean | `false` | Quality-check every address |
| `skipBigChains` | boolean | `true` | Skip global chain websites |

#### 🎯 Business filters · 🗣️ Language & region · 📡 Area

| Parameter | Type | Default | Description |
|---|---|---|---|
| `categoryFilterWords` | array | `[]` | Keep only matching categories |
| `searchMatching` | string | `all` | `all`, `only_includes`, `only_exact` |
| `placeMinimumStars` | string | — | `two` … `fourAndHalf` |
| `website` | string | `allPlaces` | `allPlaces`, `withWebsite`, `withoutWebsite` |
| `skipClosedPlaces` | boolean | `false` | Drop closed businesses |
| `language` / `countryCode` | string | `en` / `us` | Google view used for the search |
| `city` / `state` / `county` / `postalCode` | string | — | Precise area targeting |

#### 📦 Output · 🌍 Network · ⚡ Speed

| Parameter | Type | Default | Description |
|---|---|---|---|
| `includeBusinessDetails` | boolean | `false` | Attach the full Maps profile as `businessDetails` |
| `proxyConfiguration` | object | direct | Optional proxy configuration for the run. |
| `browserFallback` | boolean | `true` | Give stubborn requests one extra, more thorough attempt. |
| `maxConcurrency` | integer | `5` | Websites opened in parallel (1–20) |
| `requestDelaySeconds` | number | `0.8` | Pause between requests |
| `maxRetries` | integer | `3` | Attempts per request before it is skipped. |

***

### 🔌 Integrations & automation

- ⏰ **Schedules** — refresh a niche list weekly and only push new addresses to your sequencer.
- 🔔 **Webhooks** — notify your service when a run finishes.
- 🔄 **Make, Zapier & n8n** — send contacts to HubSpot, Pipedrive, Instantly, Lemlist, Airtable or Sheets.
- 🗄️ **Direct API access** — dataset items as JSON, JSONL, CSV, XLSX, XML or RSS.

***

### ❓ Frequently asked questions (FAQ)

#### How do I find a business email address from Google Maps?

Google Maps never shows emails. This Actor follows each listing's website link, opens the contact and about pages, and extracts the addresses published there — then picks the best one for you.

#### What is `primaryEmail` exactly?

The first address on the business's own domain. If there is none, the first non-free address. If everything is free-mail, the first address found.

#### Why are there three phone columns?

Confidence. `googlePhone` is the number Google publishes, `websitePhones` come from `tel:` links (very reliable), and `otherPhones` are numbers matched in page text (useful, occasionally a fax or a partner's number).

#### How do I get only company emails, not Gmail addresses?

Turn on **Business emails only** (`excludeFreeEmails`).

#### How do I avoid `info@` addresses?

Turn on **Skip generic inboxes** (`excludeGenericEmails`). Note that many small businesses publish nothing else, so expect fewer rows.

#### Are emails deduplicated across the whole run?

Yes, when `dedupeEmails` is on — useful for franchises and multi-location businesses that share one inbox.

#### Does verification guarantee delivery?

No verification does. It rules out disposable domains, missing mail servers and rejected recipients; anything it cannot probe is reported as `unknown` instead of guessed.

#### Can I also get the full business profile?

Turn on **Attach the full business profile** and every row gains a `businessDetails` object with the complete Google Maps record — categories, description, hours, attributes, coordinates and more.

#### Do I need a proxy?

No. Leave the proxy input empty and the run handles blocking on its own. Set one only when you want a specific country or route.

#### Is this the same as your Leads Scraper?

Same collection engine, different shape. Use **Google Maps Leads Scraper** when you want the full business record; use this one when you want a tight contact table ready for outreach.

***

### 🛠️ Troubleshooting

| Symptom | Fix |
|---|---|
| **No rows saved** | `onlyWithEmail` is strict — switch it off, or raise `contactMaxSubpages` so contact pages get opened. |
| **Few emails found** | Set `website: withWebsite`, raise `contactMaxSubpages`, and turn off `excludeGenericEmails`. |
| **All emails are `info@`** | That is what most small sites publish. Turning on `excludeGenericEmails` trades volume for named inboxes. |
| **Verification returns `unknown`** | Outbound mail ports are blocked in most cloud networks; the address is still valid-looking, it simply could not be probed. |
| **Duplicate businesses across terms** | They are already deduplicated by place ID — identical names are usually genuinely different branches. |
| **Run feels slow** | Lower `contactMaxSubpages`, raise `maxConcurrency`, turn off `verifyEmails`. |
| **Fewer businesses than requested** | The area may hold fewer matches; broaden the location or add related terms. |

***

### 💬 Help, support & custom builds

- 🐛 **Found a bug or need a new field?** Open an issue on the Actor's **Issues** tab.
- 📧 **Custom scrapers, private integrations, bulk pipelines:** **<hello.dataminds@gmail.com>**
- ⭐ **Enjoying it?** Leave a review — it genuinely helps.

***

### ⚖️ Is scraping business contacts legal?

This Actor collects **publicly published** business contact details — the same information any visitor can read on a company website. Scraping public data is generally lawful in the EU and the US, but you remain responsible for how you use it:

- Do not collect data behind authentication or paywalls.
- Respect the target site's terms of service and reasonable request rates.
- Handle personal data (a named person's email, for instance) in line with **GDPR**, **CCPA** and local law.
- Follow **CAN-SPAM**, **CASL** and equivalent rules before sending marketing email, and always offer an opt-out.

See Apify's guide on the [legality of web scraping](https://blog.apify.com/is-web-scraping-legal/) for background. This is not legal advice.

***

### 🔍 SEO keywords targeted

google maps email scraper · google maps phone number scraper · business email finder · email extractor from google maps · b2b contact scraper · lead contact enrichment · cold email list builder · google maps contact details · company email finder · local business phone numbers · email verification tool · social media profile scraper · sales prospecting data · google places contact extractor · outreach list builder · email finder API · business directory scraper · phone number extractor · maps lead contacts · verified business emails

# Actor input Schema

## `searchStringsArray` (type: `array`):

🗺️ For example `dentist`, `wedding photographer`, `roofing contractor`, `law firm`. Each term is searched on its own.

## `locationQuery` (type: `string`):

📌 Free-text area — `Denver, Colorado`, `Barcelona, Spain`, `Brooklyn, NY`. Leave blank to search without a location.

## `maxCrawledPlacesPerSearch` (type: `integer`):

🎁 How many businesses to look up per term. Every one of them gets its website opened for contact details.

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

📎 Paste Google Maps place links to pull contacts for specific businesses. Bulk input supported.

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

✅ Drop every business where no email address could be found. Turning this on automatically limits the search to businesses that publish a website.

## `onlyWithPhone` (type: `boolean`):

📞 Drop every business with no phone number at all.

## `excludeFreeEmails` (type: `boolean`):

🚫 Skip free mailboxes (gmail.com, yahoo.com, outlook.com…) and keep company-domain addresses only.

## `excludeGenericEmails` (type: `boolean`):

📥 Skip role addresses such as info@, sales@, support@ when you only want named mailboxes.

## `dedupeEmails` (type: `boolean`):

🧹 Never return the same address twice in one run — handy for franchises sharing one inbox.

## `maxEmailsPerPlace` (type: `integer`):

📧 Cap how many addresses are kept per business.

## `contactMaxSubpages` (type: `integer`):

🔍 How many contact/about pages to open beyond the homepage. More pages find more addresses.

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

✅ Check every address — disposable domain, free-mail, role inbox, mail-server lookup and a deliverability probe. No third-party key needed.

## `skipBigChains` (type: `boolean`):

🏬 Global chains rarely publish a reachable inbox — skip them and spend the time on real prospects.

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

🌐 Language for business names and categories.

## `countryCode` (type: `string`):

🧭 Country view used for the search.

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

🏙️ City name — for example `Seattle`.

## `state` (type: `string`):

🗺️ State, province or region.

## `county` (type: `string`):

📐 County or district.

## `postalCode` (type: `string`):

📮 ZIP / postal code — the tightest area filter.

## `categoryFilterWords` (type: `array`):

🏷️ Keep a business only when one of these words appears in its Google categories or description.

## `searchMatching` (type: `string`):

🔍 How strictly the business name must match your term.

## `placeMinimumStars` (type: `string`):

⭐ Skip businesses rated below this.

## `website` (type: `string`):

🌐 Emails live on websites — `only places WITH a website` gives the highest hit rate.

## `skipClosedPlaces` (type: `boolean`):

🚪 Leave out anything marked permanently or temporarily closed.

## `includeBusinessDetails` (type: `boolean`):

📋 Adds a `businessDetails` object with every Google Maps field — categories, description, hours, attributes, coordinates and more.

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

🚦 Runs start on a direct connection and switch to a datacenter and then a residential route automatically if Google pushes back. Pick your own route here to override that.

## `browserFallback` (type: `boolean`):

🧭 Retry stubborn requests inside a real browser session as a last resort.

## `maxConcurrency` (type: `integer`):

🏎️ How many business websites to open at the same time.

## `requestDelaySeconds` (type: `number`):

🕰️ A small pause keeps the run polite and stable.

## `maxRetries` (type: `integer`):

🛡️ Attempts before the run switches to the next network route.

## Actor input object example

```json
{
  "searchStringsArray": [
    "dentist"
  ],
  "locationQuery": "Denver, Colorado",
  "maxCrawledPlacesPerSearch": 20,
  "startUrls": [],
  "onlyWithEmail": false,
  "onlyWithPhone": false,
  "excludeFreeEmails": false,
  "excludeGenericEmails": false,
  "dedupeEmails": true,
  "maxEmailsPerPlace": 10,
  "contactMaxSubpages": 3,
  "verifyEmails": false,
  "skipBigChains": true,
  "language": "en",
  "countryCode": "us",
  "city": "",
  "state": "",
  "county": "",
  "postalCode": "",
  "categoryFilterWords": [],
  "searchMatching": "all",
  "placeMinimumStars": "",
  "website": "allPlaces",
  "skipClosedPlaces": false,
  "includeBusinessDetails": false,
  "proxyConfiguration": {
    "useApifyProxy": false
  },
  "browserFallback": true,
  "maxConcurrency": 5,
  "requestDelaySeconds": 0.8,
  "maxRetries": 3
}
```

# Actor output Schema

## `contacts` (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 = {
    "searchStringsArray": [
        "dentist"
    ],
    "locationQuery": "Denver, Colorado",
    "maxCrawledPlacesPerSearch": 20,
    "proxyConfiguration": {
        "useApifyProxy": false
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("citrine_venus/google-maps-email-and-phone-number-scraper").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 = {
    "searchStringsArray": ["dentist"],
    "locationQuery": "Denver, Colorado",
    "maxCrawledPlacesPerSearch": 20,
    "proxyConfiguration": { "useApifyProxy": False },
}

# Run the Actor and wait for it to finish
run = client.actor("citrine_venus/google-maps-email-and-phone-number-scraper").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 '{
  "searchStringsArray": [
    "dentist"
  ],
  "locationQuery": "Denver, Colorado",
  "maxCrawledPlacesPerSearch": 20,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}' |
apify call citrine_venus/google-maps-email-and-phone-number-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,citrine_venus/google-maps-email-and-phone-number-scraper"
        }
    }
}

```

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/V7kBaKlQszLJUvPAf/builds/CMxJqmFiB9P8SiaKT/openapi.json
