# Google Maps Email Extractor - Leads with Emails & Phones (`kamerozkan/google-maps-email-extractor`) Actor

Gym owner emails, chiropractor email lists and other local business leads from Google Maps, with the emails, phones and social links each business publishes on its own website. Keyword and city search in 30 countries, one flat row per place. No login, no browser.

- **URL**: https://apify.com/kamerozkan/google-maps-email-extractor.md
- **Developed by:** [Kamer Ozkan](https://apify.com/kamerozkan) (community)
- **Categories:** Lead generation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.40 / 1,000 place with contacts

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 Email Extractor - Leads with Emails & Phones

Get **Google Maps leads with emails** in one run: every local business Google lists for your search (name, category, rating, exact review count, address, phone, website, coordinates) plus the **emails, phones and social links the business publishes on its own website**. Search by trade and city in 30 countries and export a ready-to-use lead list to CSV, Excel or your CRM: **gym owner emails**, a **chiropractor email list**, dentists, contractors or any other trade.

### What does Google Maps Email Extractor do?

Type what you would search on Google Maps, for example `dentist in Austin TX` or `Steuerberater Berlin`. The actor reads Google's local results (20 places per page, sponsored listings skipped) and then visits each business website: the homepage plus its own contact, imprint and about pages. It collects the business emails, phone numbers and company social profiles it finds there and returns **one flat row per place**.

It needs no login, no Google account, no browser and no proxy setup on your side. Google results come through Apify's Google SERP proxy, which is included in the price. Website visits are plain HTTP requests to the public pages of each business.

### Who is it for?

- **Lead generation agencies**: build email and call lists of local businesses by trade and city, in one step instead of two tools.
- **B2B sales teams**: find businesses in your territory with a published email, phone and LinkedIn company page.
- **Marketing and web agencies**: spot businesses with no website, a weak rating or few reviews and reach them by email.
- **Recruiters and suppliers**: list every practice, office or shop of a type in a region with its contact channels.

### What data can you get?

| Field | Example |
|---|---|
| `name`, `category`, `categories` | ATX Family Dental, Dentist |
| `rating`, `reviewsCount` | 4.9, 914 (exact count) |
| `address`, `phone` | 1700 S 1st St, Austin, TX 78704, (512) 717-3147 |
| `website` | https://www.atxfamilydental.com/ |
| `email` | info@atxfamilydental.com (best email, own domain first) |
| `emails` | all emails found on the website, up to 20 |
| `websitePhones` | phone numbers published on the website |
| `linkedin`, `facebook`, `instagram`, `twitter`, `youtube`, `tiktok`, `pinterest`, `github`, `xing` | company profile links found on the website |
| `contactPages` | the contact, imprint and about pages that were read |
| `websiteStatus` | `ok`, `no website`, `error: ...` or why a site was not crawled |
| `openingStatus` | Closed · Opens 8 AM (at the time of the run) |
| `latitude`, `longitude` | 30.248223, -97.75597 |
| `placeId`, `cid`, `kgmid`, `googleMapsUrl` | Google identifiers and a Google Maps link |
| `query`, `country`, `position` | the search, the country and the rank in Google's results |

Empty values are `null` or `[]`; the actor never guesses an email. Not every business publishes an email: in our QA run for `dentist in Austin TX`, 15 of 40 places (38%) had an email on their website, and all 40 had a phone from Google. Turn on **Only places with an email** to receive (and pay for) only those.

### How much does it cost?

You pay per delivered place: **$3.00 per 1,000 places** ($0.003 per place) on the Free plan, with Store discounts on paid Apify plans: Bronze $2.70, Silver $2.55, Gold and above $2.40 per 1,000 places. The email and social enrichment, the Google SERP proxy and platform usage are included; there is nothing else to buy.

Worked example: 25 searches (one trade in 25 cities) with 40 places each = 1,000 places = 1,000 x $0.003 = **$3.00** on the Free plan. With **Only places with an email** turned on, places without an email are skipped and not charged, so you pay only for the leads you can email.

Set "Max places per query", "Max places in total" or a maximum cost per run to cap spending.

### How to use it

1. Click **Try for free**.
2. Enter one or more **Search queries**: a business type plus a place, such as `roofing contractor Phoenix AZ`.
3. Choose the **Country** and, if you want, a **Language**.
4. Set **Max places per query** (one results page holds 20 places).
5. Optional: turn on **Only places with an email**, or raise **Pages per website** for large sites.
6. Click **Start**, then download the leads as CSV, Excel or JSON, or read them through the API.

Tip: Google lists a limited number of places per search. For full coverage of a large city, split it into neighbourhoods or ZIP codes (`dentist 78704`, `dentist 78731`) and deduplicate on `placeId`.

### Ready-made lead lists

Open one, change the cities to yours and run it:

| Lead list | Ready-to-run search |
| --- | --- |
| Gym owner emails | [Gyms and fitness studios with an email (US cities)](https://apify.com/kamerozkan/google-maps-email-extractor/examples/gym-owner-emails-from-google-maps) |
| Chiropractor email list | [Chiropractic clinics with an email (US cities)](https://apify.com/kamerozkan/google-maps-email-extractor/examples/chiropractor-email-list-from-google-maps) |
| Roofing contractors | [Leads with emails by trade and city](https://apify.com/kamerozkan/google-maps-email-extractor/examples/google-maps-leads-with-emails-by-trade-and-city) |
| German businesses | [Business emails from Google Maps Germany](https://apify.com/kamerozkan/google-maps-email-extractor/examples/business-emails-from-google-maps-germany) |

### Input example

```json
{
  "queries": ["dentist in Austin TX", "orthodontist in Austin TX"],
  "countryCode": "us",
  "maxPlacesPerQuery": 40,
  "onlyPlacesWithEmails": false,
  "maxPagesPerSite": 3
}
```

### Output example

A row from a QA run on 2026-10-12 (`dentist in Austin TX`), shortened to the main fields (values unchanged):

```json
{
  "query": "dentist in Austin TX",
  "country": "US",
  "position": 7,
  "name": "Austin Dental Company | Steiner Ranch",
  "category": "Dentist",
  "rating": 5,
  "reviewsCount": 953,
  "address": "3810 N Quinlan Park Rd Ste 140, Austin, TX 78732",
  "phone": "(512) 710-4783",
  "website": "https://www.austindentalco.com/",
  "email": "info@austindentalco.com",
  "emails": ["info@austindentalco.com"],
  "websitePhones": ["+15127104783", "18552150587"],
  "facebook": "https://www.facebook.com/austindentalco",
  "instagram": "https://www.instagram.com/austindentalco",
  "contactPages": [
    "https://www.austindentalco.com/make-an-appointment",
    "https://www.austindentalco.com/about-us/our-team"
  ],
  "websiteStatus": "ok",
  "latitude": 30.375126,
  "longitude": -97.88604,
  "placeId": "ChIJH6UXiss3W4YR2edl26hwYxA",
  "googleMapsUrl": "https://www.google.com/maps?cid=1180911397838907353"
}
```

### Integrations and API

Run it from your code with the Apify API or the `apify-client` package, schedule it in Apify, or connect it to Make, n8n, Zapier, Google Sheets, HubSpot or a webhook.

```python
from apify_client import ApifyClient

client = ApifyClient("<YOUR_APIFY_TOKEN>")
run = client.actor("kamerozkan/google-maps-email-extractor").call(run_input={
    "queries": ["dentist in Austin TX"],
    "countryCode": "us",
    "maxPlacesPerQuery": 40,
    "onlyPlacesWithEmails": True,
})
for lead in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(lead["name"], lead["email"], lead["phone"], lead["website"])
```

### FAQ

**Where do the emails come from?** Only from the business's own website (homepage, contact, imprint and about pages). The actor does not guess addresses from name patterns and does not buy data from third parties.

**Why do some places have no email?** Many small businesses publish only a phone number or a contact form. Some websites block automated visits or do not answer; their row says why in `websiteStatus`. The actor never tries to pass bot checks.

**Am I charged for places without an email?** By default every delivered place is charged, because it still carries the Google data (phone, website, rating, address). With **Only places with an email** turned on, places without an email are not delivered and not charged.

**How fast is it?** Google's local result pages are slow to answer, and every website is visited, so 40 places take about two minutes. Websites are visited in parallel.

**What if my run timeout is too short for my input?** The actor watches the run's time limit. About a minute before it, it stops reading Google, delivers the places it already has (sites not visited in time say `not crawled: run time limit reached` in `websiteStatus`) and ends as a successful run with a "Partial" status message. Raise the timeout in the run options or split your queries to get the rest.

**What about chains with one website?** Places that share the same website are crawled once and get the same contacts.

**Is it legal to collect this data?** It collects business contact details that companies publish themselves. Personal LinkedIn profiles are not returned. You are responsible for how you use the data, including direct marketing rules such as GDPR, CAN-SPAM or the German UWG.

### Support and feedback

- Found a bug or missing a field? Open an issue on the **Issues** tab of this Actor. We reply within
  48 hours and ship most fixes within a few days.
- Have an idea for a feature? Issues are the fastest way to get it built.
- If the Actor saves you time, a short review on this page helps other users find it.

# Actor input Schema

## `queries` (type: `array`):

What you would type into Google Maps: a business type plus a place, one query per line. Examples: dentist in Austin TX, roofing contractor Denver, Steuerberater Berlin.

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

Google country to search in. Use the country of the places you want.

## `languageCode` (type: `string`):

Language for categories and opening status, such as en, de or fr. Leave empty to use the country's main language.

## `maxPlacesPerQuery` (type: `integer`):

Stop each query after this many places. One results page holds 20 places; the actor pages further when you ask for more (up to about 200 per query, as many as Google lists).

## `maxItems` (type: `integer`):

Stop the whole run after this many delivered places. You are charged per delivered place, so this also caps the cost of the run.

## `onlyPlacesWithEmails` (type: `boolean`):

Deliver only places whose website shows at least one email. Places without an email are skipped and not charged.

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

Homepage plus the site's own contact, imprint and about pages. 3 finds most published emails; raise it for large sites.

## Actor input object example

```json
{
  "queries": [
    "dentist in Austin TX"
  ],
  "countryCode": "us",
  "maxPlacesPerQuery": 20,
  "maxItems": 1000,
  "onlyPlacesWithEmails": false,
  "maxPagesPerSite": 3
}
```

# Actor output Schema

## `results` (type: `string`):

One row per result in the default dataset.

# 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 = {
    "queries": [
        "dentist in Austin TX"
    ],
    "countryCode": "us",
    "maxPlacesPerQuery": 20
};

// Run the Actor and wait for it to finish
const run = await client.actor("kamerozkan/google-maps-email-extractor").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 = {
    "queries": ["dentist in Austin TX"],
    "countryCode": "us",
    "maxPlacesPerQuery": 20,
}

# Run the Actor and wait for it to finish
run = client.actor("kamerozkan/google-maps-email-extractor").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 '{
  "queries": [
    "dentist in Austin TX"
  ],
  "countryCode": "us",
  "maxPlacesPerQuery": 20
}' |
apify call kamerozkan/google-maps-email-extractor --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,kamerozkan/google-maps-email-extractor"
        }
    }
}
```

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/xZaPhdwSreEBHMVIY/builds/z28d71SM6bAATTsGs/openapi.json
