# Google Maps Scraper: Places, Emails & Phones (`deepmine/google-maps-scraper`) Actor

Google Maps scraper: search places by keyword and location, Maps URL or place ID. Address, phone, website, rating, star histogram, opening hours, categories, owner info, up to 15 reviews and 100 photos, plus emails and social profiles from each website. No login.

- **URL**: https://apify.com/deepmine/google-maps-scraper.md
- **Developed by:** [DeepMine](https://apify.com/deepmine) (community)
- **Categories:** Lead generation, Travel, E-commerce
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.35 / 1,000 places

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 Scraper: Places, Emails & Phones

Scrape **Google Maps places** by **search term and location** (`dentist` in `Boise, ID`), by **Google Maps URL** (place, search or short links) or by **place ID / CID**. Every place comes with its **full details**: address parts, phone, website, rating and the **star histogram**, **opening hours** (plus delivery / takeout hours), categories, attributes (accessibility, amenities...), the owner's description and posts, **review topics**, **photos**, reservation and order links, and hotel offers and scores. Add **up to 15 reviews** and **up to 100 photos** per place, and turn on **website contacts** for **emails, phones and Facebook, Instagram, LinkedIn, X, YouTube and TikTok profiles** from each business website. No login, no browser, no proxy setup.

| Name | Category | Rating | Reviews | Phone | Neighborhood |
|---|---|---|---|---|---|
| [Manhatta](https://www.google.com/maps/search/?api=1\&query=Manhatta) | New American restaurant | 4.7 | 4,121 | (212) 230-5788 | Manhattan |
| [The Fulton by Jean-Georges](https://www.google.com/maps/search/?api=1\&query=The%20Fulton%20by%20Jean-Georges) | Restaurant | 4.1 | 1,385 | (718) 821-5411 | Manhattan |
| [Le Jardin Bistro NYC](https://www.google.com/maps/search/?api=1\&query=Le%20Jardin%20Bistro%20NYC) | French restaurant | 4.7 | 349 | (212) 228-0909 | Manhattan |

<sub>Collected 2026-10-18 (search "restaurant" in "New York, USA").</sub>

### What you can do

- **Search** any term in any city, neighborhood, ZIP code, state or country. The scraper takes Google's own best-ranked results first, then searches every ZIP / postal code inside the area and covers the rest with a map grid that goes deeper where places are dense, so big searches aren't stuck at Google's ~200 results per query. The area is the location's own boundary (OpenStreetMap), so "Chicago, IL" stays in Chicago and doesn't fill up with suburbs; for a metro area, list its towns or draw a custom area.
- **Look up places you already have**: Google Maps place links, `maps.app.goo.gl` short links, `?cid=` links, place IDs (`ChIJ...`), CIDs or FIDs. Maps search links (`/maps/search/dentist/@43.61,-116.2,13z`) run as searches.
- **Filter before you pay**: category words, name match, minimum rating, with or without a website, skip closed places. Places a filter leaves out are never charged.
- **Build lead lists**: turn on *Emails and social profiles from websites* to read each place's website (home page plus up to 2 contact pages). Places with an email also land in a separate **📧 Places with emails** dataset.
- **Drop-in for compass/crawler-google-places**: the same input keys (`searchStringsArray`, `locationQuery`, `maxCrawledPlacesPerSearch`, `startUrls`, `placeIds`, `scrapeContacts`, `maxReviews`...) and the same output field names and shapes.

### Pricing

Pay per result, no start fee:

- **$0.45 per 1,000 places** on the Starter plan ($0.49 Free, $0.39 Scale, $0.35 Business), each with its full details. Reviews (up to 15) and photos (up to 100) are included in that price.
- **Website contacts** (opt-in): **$0.49 per 1,000 places** whose website gave at least one email, phone or social profile. A place without a website, or whose site gave nothing, isn't charged it.

Each place is charged once per run, even when several search terms find it.

### Input

| Field | What it does |
|---|---|
| 🔍 Search terms | What you'd type in Google Maps (`dentist`, `coffee shop`) |
| 📍 Location | City, neighborhood, ZIP, state or country |
| 💯 Number of places per search term | Cap per term (empty = every place in the area) |
| 📧 Emails and social profiles from websites ($) | Website contacts add-on |
| 🎛️ Filters | Categories, name match, minimum rating, website, skip closed |
| 🔗 Google Maps URLs / 🗃️ Place IDs | Places or searches you already have |
| 📡 Location by parts / 🛰️ Custom search area | Country, city, state, county, postal code; or a GeoJSON polygon / point + radius |
| ⭐ Reviews per place | 0-15 reviews per place, newest first or most relevant first (included in the price) |
| 🖼️ Photos per place | Up to 6 from the place's photo strip; more (up to 100) from its photo gallery, with size, upload date and owner / visitor (included in the price) |

### Output

One row per place. Views: **📊 Overview** (photo, name, category, rating, reviews, phone, website, address, Google Maps link, search, rank), **📈 Stats** (rating, reviews per star, photos), **📍 Location** (address parts, coordinates, plus code, time zone) and **📧 Contacts** (emails, site phones and social profiles; with website contacts on).

Fields, in row order: `title`, `subTitle`, `description`, `ownerDescription`, `price`, `categoryName`, `address`, `neighborhood`, `street`, `city`, `postalCode`, `state`, `countryCode`, `website`, `phone`, `phoneUnformatted`, `claimThisBusiness`, `location`, `locatedIn`, `parentPlaceUrl`, `floor`, `plusCode`, `plusCodeGlobal`, `menu`, `totalScore`, `permanentlyClosed`, `temporarilyClosed`, `placeId`, `categories`, `fid`, `cid`, `reviewsCount`, `reviewsDistribution`, `imagesCount`, `imageCategories`, `reserveTableUrl`, `googleFoodUrl`, `hotelStars`, `hotelDescription`, `checkInDate`, `checkOutDate`, `hotelPrice`, `hotelAds`, `hotelAmenities`, `hotelReviewSummary`, `similarHotelsNearby`, `popularTimesLiveText`, `popularTimesLivePercent`, `popularTimesHistogram`, `openingHours`, `openingHoursStatus`, `wasOpenAtScrapeTime`, `additionalOpeningHours`, `peopleAlsoSearch`, `placesTags`, `reviewsTags`, `additionalInfo`, `gasPrices`, `questionsAndAnswers`, `url`, `language`, `imageUrl`, `imageUrls`, `images`, `kgmid`, `businessProfileId`, `tableReservationLinks`, `tableReservationProviders`, `restaurantData`, `orderBy`, `bookingLinks`, `ownerUpdates`, `ownerName`, `ownerId`, `ownerProfileUrl`, `additionalPhones`, `domain`, `timezone`, `reviews`, then with website contacts on `emails`, `phones`, `phonesUncertain`, `whatsapps`, `linkedIns`, `twitters`, `instagrams`, `facebooks`, `youtubes`, `tiktoks`, `pinterests`, `discords`, `yelps`, `tripadvisors`, and last `searchString`, `rank`, `searchPageUrl`, `inputStartUrl`, `inputPlaceId`, `isAdvertisement`, `scrapedAt`.

`reviews` holds up to 15 reviews per place (text, stars, date, reviewer, local-guide flag, the reviewer's ratings for food / service / atmosphere and context like price per person, photos, link). That is the most signed-out Google Maps shows anyone: the 10 most relevant and the 5 newest reviews of a place. So this scraper can't page through all of a place's reviews, sort them by rating or filter them by date; the *Which reviews first* option picks newest first (the 5 newest, then the most relevant) or most relevant first (the 10 most relevant, then the newest). Signed-out Google Maps doesn't show popular times, price levels or "people also search", so those fields stay empty; `questionsAndAnswers` isn't available either. They are kept so pipelines built on compass's format keep working. `imageUrls` lists the photo strip Google shows on the place (about 6), or, with more than 6 photos asked for, the place's photo gallery, which also fills `images` (photo ID, URL, width and height, video link, upload date, owner or visitor upload, whether it came with a review). `imagesCount` is Google's total photo count; the gallery Google lists can hold fewer (in a 100-dentist test, places with 37-54 photos listed 20-28), and you get what it lists.

# Actor input Schema

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

What you would type in Google Maps, e.g. <strong>dentist</strong> or <strong>coffee shop</strong>. Each term is searched in the location below. A term may name its own place (<strong>pizza in Austin, TX</strong>).

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

City, neighborhood, ZIP code, state or country, e.g. <strong>Boise, ID</strong> or <strong>Berlin, Germany</strong>. Results stay inside the location's own boundary (a city search doesn't spill into its suburbs). Large areas are searched ZIP code by ZIP code and tile by tile automatically. Empty = Google picks the area your term names.

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

Places each search term returns at most, e.g. 500. Empty = every place Google Maps has for it in the location.

## `scrapeContacts` (type: `boolean`):

Reads each place's website (home page plus up to 2 contact pages) for emails, phones and Facebook, Instagram, LinkedIn, X, YouTube, TikTok and other profiles. Charged only for places whose website gave a contact.

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

Language of names, categories, hours and reviews, as Google Maps shows them.

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

Keep only places with a category containing one of these words, e.g. <strong>dentist</strong>, <strong>orthodontist</strong>. Empty = every category. Places left out are not charged.

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

Keep only places whose name contains the search term, or is exactly the search term.

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

Keep only places rated at least this. Places without a rating are left out when this is set.

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

Keep only places with a website (for lead lists), or only places without one.

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

Leave out places marked temporarily or permanently closed.

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

Place links (<code>https://www.google.com/maps/place/...</code>, <code>maps.app.goo.gl/...</code>, <code>?cid=</code> links) and search links (<code>https://www.google.com/maps/search/dentist/@43.61,-116.2,13z</code>). A search link runs as one more search term.

## `placeIds` (type: `array`):

Google place IDs (<code>ChIJdzf8kEZZwokRXtSOY0-Kwaw</code>), CIDs (<code>12448382918606115934</code>) or FIDs (<code>0x89c2594690fc3777:0xacc18a4f638ed45e</code>).

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

Used with the fields below when 📍 Location is empty; also sets the Google country, e.g. <strong>de</strong>. Two letters.

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

e.g. <strong>Pittsburgh</strong>.

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

e.g. <strong>Massachusetts</strong>.

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

e.g. <strong>King County</strong>.

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

e.g. <strong>10001</strong>. Combine with 🗺️ Country.

## `customGeolocation` (type: `object`):

A GeoJSON Polygon or MultiPolygon (\[longitude, latitude] order), or a Point with <code>radiusKm</code>. Overrides the location. Only places inside are kept.

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

Adds reviews with text, stars, date, reviewer and ratings. Signed-out Google Maps shows at most the 10 most relevant and the 5 newest reviews of a place, so up to 15 per place (fewer when the place has fewer). Included in the place price. 0 = none.

## `reviewsSort` (type: `string`):

Newest: the 5 newest reviews, then the most relevant. Most relevant: the 10 most relevant, then the newest. Signed-out Google Maps offers no other order or date filter.

## `maxImages` (type: `integer`):

Photo URLs in imageUrls. Up to 6 come from the photo strip on the place page; more than 6 reads the place's photo gallery and also fills images (each photo's size, upload date, owner or visitor, video link). Included in the place price. The total photo count is always in imagesCount. 0 = none.

## `scrapeReviewsPersonalData` (type: `boolean`):

Off: reviews keep their text, stars and dates but not the reviewer's name, ID, profile link or photo.

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

Leave as is: Apify datacenter proxy works for Google Maps. A call every datacenter IP refused is retried once on a residential IP.

## Actor input object example

```json
{
  "searchStringsArray": [
    "restaurant"
  ],
  "locationQuery": "New York, USA",
  "maxCrawledPlacesPerSearch": 50,
  "scrapeContacts": false,
  "language": "en",
  "searchMatching": "all",
  "placeMinimumStars": "",
  "website": "allPlaces",
  "skipClosedPlaces": false,
  "maxReviews": 0,
  "reviewsSort": "newest",
  "maxImages": 6,
  "scrapeReviewsPersonalData": true,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

## `places` (type: `string`):

No description

## `withEmails` (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 = {
    "searchStringsArray": [
        "restaurant"
    ],
    "locationQuery": "New York, USA",
    "maxCrawledPlacesPerSearch": 50
};

// Run the Actor and wait for it to finish
const run = await client.actor("deepmine/google-maps-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": ["restaurant"],
    "locationQuery": "New York, USA",
    "maxCrawledPlacesPerSearch": 50,
}

# Run the Actor and wait for it to finish
run = client.actor("deepmine/google-maps-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": [
    "restaurant"
  ],
  "locationQuery": "New York, USA",
  "maxCrawledPlacesPerSearch": 50
}' |
apify call deepmine/google-maps-scraper --silent --output-dataset

```

## MCP server setup

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