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

Google Maps scraper for business leads: search places by keyword and location, Maps URL or place ID. Phone, website, address, rating, reviews, opening hours, popular times, menu and photos, plus emails and social profiles from each website as an add-on. No login. Use it as a Google Maps API.

- **URL**: https://apify.com/deepmine/google-maps-scraper.md
- **Developed by:** [DeepMine](https://apify.com/deepmine) (community)
- **Categories:** Lead generation, Travel, E-commerce
- **Features:** Limited permissions
- **Stats:** 1 total users, 0 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

**Google Maps Scraper** turns a search like `dentist` in `Boise, ID` into a lead list: one row per business with its phone, website, address, rating, reviews and opening hours, plus the emails and social profiles its website lists.

**1,000 places with their reviews cost $0.45 on the Starter plan.** Reviews and photos are in the place price: set ⭐ Reviews per place to 15 and each place comes with about 13 (see below). Add emails and social profiles from each website for at most $0.49 more ($0.94 in all): that add-on is charged only for places whose website gave a contact. You pay per place only: no start fee, no compute or proxy bill.

| Name | Rating | Reviews | Phone | Website | Price | Emails |
|---|---|---|---|---|---|---|
| [Time Out Market New York](https://www.google.com/maps/search/?api=1\&query=Time%20Out%20Market%20New%20York\&query_place_id=ChIJ9aMCWaxbwokRZHJGmTBxFtQ) | 4.5 | 8,731 | (917) 810-4855 | [timeoutmarket.com](https://www.timeoutmarket.com/newyork/) | $$ | infonyc@timeoutmarket.com |
| [Gramercy Tavern](https://www.google.com/maps/search/?api=1\&query=Gramercy%20Tavern\&query_place_id=ChIJvSQIgqFZwokRFYQbJdzceSs) | 4.6 | 5,075 | (212) 477-0777 | [gramercytavern.com](https://www.gramercytavern.com/) | $$$$ | donations@ushgnyc.com |
| [Cecconi's DUMBO](https://www.google.com/maps/search/?api=1\&query=Cecconi%27s%20DUMBO\&query_place_id=ChIJB2xIGTFawokRSX4sCtT9djg) | 4.0 | 3,418 | (718) 650-3900 | [cecconisdumbo.com](http://cecconisdumbo.com/) | $$ | none on the site |
| [The River Café](https://www.google.com/maps/search/?api=1\&query=The%20River%20Caf%C3%A9\&query_place_id=ChIJ2QZOdTpawokRU_eN_EPJaX8) | 4.4 | 2,597 | (718) 522-5200 | [rivercafe.com](https://www.rivercafe.com/) | $$$$ | none on the site |
| [Boucherie Union Square](https://www.google.com/maps/search/?api=1\&query=Boucherie%20Union%20Square\&query_place_id=ChIJc1Vf7KFZwokR1YL2Rn9oxi8) | 4.7 | 5,520 | (212) 353-0200 | [boucherieus.com](https://www.boucherieus.com/) | $$$ | contact@boucherie.nyc (+8 more) |

<sub>Collected 2026-10-27 at 00:31 UTC (run b9x8aJlrbfs0ZGAUz, build 0.1.22 at the Actor's default 512 MB, 17 s): search "restaurant" in "New York, USA", 50 places, no reviews, 6 photos, website contacts ticked as on the form. The first five of the 50 rows, in the order the run returned them; the table shows 7 of each row's columns (the others are in the dataset, e.g. Instagram and Facebook links, which 41 and 24 of the 50 places had). All 50 places had a phone, a website and opening hours; 38 had an email, 50 "people also search for", 49 menu or services items, 43 popular times, 38 a menu link and 38 a price level. A separate run of the same search with 15 reviews asked for (build 0.1.20, 2026-10-26) gave 11 to 14 reviews per place (13 on most; 647 different reviews, 194 with the owner's reply).</sub>

**On the form**: `restaurant` in `New York, USA`, 50 places, with **website contacts ticked**, so your first run also shows emails and social profiles where the restaurants' websites list them. It costs at most $0.047 on Starter ($0.0225 for the places, up to $0.0245 for contacts) and under $0.05 on the Free plan. Untick contacts and it's $0.0225. Plan prices per 1,000 places: $0.49 Free, $0.45 Starter, $0.39 Scale, $0.35 Business; contacts $0.49 on every plan.

### Start in three steps

1. **Enter what you'd type in Google Maps** (`dentist`, `coffee shop`) and a **location** (a city, neighborhood, ZIP, state or country), or paste Google Maps links or place IDs.
2. **Choose how many places** per search, filters if you want them (category words, minimum rating, with or without a website), and keep or untick **📧 Emails and social profiles from websites** (+$0.49 per 1,000 places that have them).
3. **Run, then export.** Open the dataset's 📊 Overview view (or 📧 Contacts for the emails) and download CSV, Excel or JSON, or schedule the run.

Copy/paste input for the API (Actor id `deepmine/google-maps-scraper`), the prefilled run. Through the API, `scrapeContacts` is off unless you send `true`:

```json
{
  "searchStringsArray": ["restaurant"],
  "locationQuery": "New York, USA",
  "maxCrawledPlacesPerSearch": 50,
  "scrapeContacts": true,
  "language": "en"
}
```

### 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.
- **Every place 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.
- **What the Maps app shows on a place**: **popular times** by hour and live busyness ("A little busy", 61%), the typical visit time, **price level** ($ to $$$$), the **menu** link and menu or services items with prices, popular dishes, review highlights and the places Google lists under "People also search for". Included in the place price.

### 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 | Up to 15 reviews per place (13-14 in the 2026-10-26 checks): newest first, most relevant first, or the 5 highest or lowest rated (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) |
| 🗂️ Photos per category | Up to 10 photo links from each photo category (Menu, Food & drink, Vibe, By owner...), and the category names (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), **📧 Contacts** (emails, site phones and social profiles; with website contacts on) and **🚦 Busyness** (live busyness, how busy it usually is at this hour, typical visit, open now).

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`, `popularTimesLiveUsualPercent`, `popularTimesWaitPeaks`, `timeSpent`, `popularDishes`, `menuAndServices`, `reviewHighlights`, `editorialSummary`, `priceLevel`, `photosByCategory`, then with website contacts on `emails`, `phones`, `phonesUncertain`, `whatsapps`, `linkedIns`, `twitters`, `instagrams`, `facebooks`, `youtubes`, `tiktoks`, `pinterests`, `discords`, `yelps`, `tripadvisors`, `websiteCheck`, `contactPageUrl`, 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, the owner's reply, link). Signed-out Google Maps shows a place's 5 newest and its most relevant: on 2026-10-26 three places with 2,600 to 381,000 reviews each gave 13-14 different reviews each, the 5 newest plus the 8-9 most relevant from the web page and the Maps app's place sheet. The *Which reviews first* option picks newest first (the 5 newest, then the most relevant), most relevant first (then the newest), or the 5 highest or lowest rated (signed-out Google Maps shows 5 in those orders; they are never topped up with reviews in another order). `reviewsOrigin: "google"` keeps Google's own reviews only, and `reviewsStartDate` (a date or a span like `3 months`) keeps the ones published since then. This version can't page through all of a place's reviews: every anonymous route we tested past these (Google's review list on the web and in the Android app) asks for a signed-in or device-verified client, so a `maxReviews` above 15 gives up to 15 and the run says so. `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.

`price`, `menu`, `popularTimesHistogram`, the live popular-times fields and `peopleAlsoSearch` come from the place sheet of the Google Maps app, read for every place alongside its web record (no login). `price` is the price level as `$` (inexpensive) to `$$$$` (very expensive), or a range like `$10-20` when the place record has one, and `priceLevel` gives it in words. They stay empty where Google shows nothing for a place: a place without enough visits has no popular times, a shop no menu. `openingHours` days also carry `periods` (24-hour `open` / `close` times, `overnight` when a period ends the next day). `questionsAndAnswers` is in every row but stays empty in this version.

### Coming from compass/crawler-google-places?

Every input option of compass/crawler-google-places, and what this Actor does with it, so you can check before you switch. A compass input runs here as it is: an option this version doesn't do, or does only in part, is named in the run's log, its status line and `notDone` in the run's OUTPUT record, and so is any input name the Actor doesn't read at all (a typo, an option of another Actor). Nothing is swapped silently.

| compass option | Here |
|---|---|
| `searchStringsArray`, `locationQuery`, `maxCrawledPlacesPerSearch` | Same names, same meaning. The older `searchString` and `maxCrawledPlaces` are read too. |
| `language` | Same. Any Google language code, including all of compass's (`es-419`, `iw`...). |
| `categoryFilterWords` | Same filter. As in compass, with no search term, link or ID the categories are searched too. |
| `searchMatching`, `placeMinimumStars`, `website`, `skipClosedPlaces` | Same names and values. A value outside the choices turns that filter off and the run says so. |
| `countryCode`, `city`, `state`, `county`, `postalCode`, `customGeolocation` | Same. |
| `startUrls`, `placeIds` | Same: place links, short links, CID links, place IDs, Maps search links. |
| `scrapePlaceDetailPage`, `scrapeTableReservationProvider` | Nothing to switch: every place comes with its details and its reservation providers. |
| `scrapeContacts` | Same: emails, phones and social profile links from the website (the $0.49 per 1,000 add-on). |
| `maxReviews` | Same name. Up to 15 per place (13-14 measured on 2026-10-26, see Output); a higher number gives what Google shows signed out, and the run says so. |
| `reviewsSort` | Same values: `newest`, `mostRelevant`, `highestRanking`, `lowestRanking` (the last two: up to 5 per place). |
| `reviewsOrigin` | Same: `google` keeps Google's own reviews. |
| `reviewsStartDate` | A date (`2026-05-03`) or a span (`3 months`): keeps the reviews each place gets from then on. It can't reach older reviews than those (the run says so). |
| `scrapeReviewsPersonalData` | Same: off leaves out reviewer names, IDs, links and photos. |
| `maxImages` | Same name. Up to 100 photos per place; a higher number gives 100 and the run says so (the Google Maps Photos Scraper lists every photo). |
| `scrapeOrderOnline` | In part: order providers come as `orderBy` and `googleFoodUrl` links, without fees or delivery times. |
| `maxQuestions` | Not available yet: `questionsAndAnswers` stays empty. |
| `reviewsFilterString` | Not available: reviews aren't filtered by keyword. |
| `scrapeImageAuthors` | Not available: `images[].uploadedBy` says owner or visitor, not the name. |
| `scrapeSocialMediaProfiles` | Not available: website contacts give the profile links, not profile details. |
| `maximumLeadsEnrichmentRecords`, `leadsEnrichmentDepartments`, `verifyLeadsEnrichmentEmails` | Not available: no named decision-makers or email verification. |
| `includeWebResults`, `scrapeDirectories` | Not available: no web results, no listing of places inside malls or airports. |
| `enableCompetitorAnalysis`, `maxCompetitorsToAnalyze` | Not available. |
| `allPlacesNoSearchAction` | Not available: give search terms or categories. A run with only this stops with a message and no charge. |

Output: 83 of the 101 properties compass declares are in our rows under the same name, including `title`, `categoryName`, `address`, `phone`, `website`, `totalScore`, `reviewsCount`, `placeId`, `openingHours`, `reviews`, `price`, `menu`, `popularTimesHistogram` and `peopleAlsoSearch`, and each review has compass's review keys (`textTranslated`, `translatedLanguage`, `likesCount`, `rating` and `visitedIn` stay empty: we haven't found them in what Google shows signed out). `orderOnline` isn't a field here; order links are in `orderBy` and `googleFoodUrl`. A location with nothing to search for, or only links that aren't Google Maps places, stops the run with a message and no charge (the example search runs only for an empty input).

### Google Maps API: export places with Python, HTTP, schedules and integrations

Every run is also an API call. Use your API token from the Apify Console (Settings → API & Integrations).

**Python**, with the official [Apify client](https://docs.apify.com/api/client/python) (`pip install apify-client`): run a search and read the places from the run's dataset. `scrapeContacts` is off unless you send `True` (the $0.49 per 1,000 add-on).

```python
import os
from apify_client import ApifyClient

client = ApifyClient(os.environ["APIFY_TOKEN"])
run = client.actor("deepmine/google-maps-scraper").call(run_input={
    "searchStringsArray": ["dentist"],
    "locationQuery": "Boise, ID",
    "maxCrawledPlacesPerSearch": 100,
    "website": "withWebsite",
    "scrapeContacts": True,
})
for place in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(place["title"], place.get("phone"), place.get("website"), place.get("emails"))
```

**Any language, one HTTP call**: start the run and get its places back as CSV in the same request. This endpoint waits up to 5 minutes for the run; for big searches, start the run with `/runs` and read its dataset when it finishes.

```bash
curl -X POST "https://api.apify.com/v2/acts/deepmine~google-maps-scraper/run-sync-get-dataset-items?format=csv&fields=title,categoryName,address,phone,website,totalScore,reviewsCount,url" \
  -H "Authorization: Bearer $APIFY_TOKEN" -H "Content-Type: application/json" \
  -d '{"searchStringsArray": ["dentist"], "locationQuery": "Boise, ID", "maxCrawledPlacesPerSearch": 100}' \
  -o places.csv
```

`format` takes `csv`, `xlsx`, `json`, `jsonl`, `xml` or `html`; `fields` picks the columns (leave it out for every field). The [API tab](https://apify.com/deepmine/google-maps-scraper/api) shows the same calls for JavaScript (Node.js) and the other clients.

**Schedule it**: save your input as a task, then add a schedule in the Apify Console (Schedules → Create, for example every Monday at 7:00) to collect the same search every week. Each scheduled run is billed like any run, per place. **Send it on**: Apify's [integrations](https://apify.com/integrations) connect finished runs to Google Sheets, Slack, Zapier, Make and Airbyte, and a [webhook](https://docs.apify.com/platform/integrations/webhooks) can call your own endpoint when a run finishes.

### Local business scraper: build a lead list

1. Search a category in a city (`plumber` in `Austin, TX`), and set a minimum rating or "only places with a website" in the filters. Places a filter leaves out aren't charged.
2. Turn on **website contacts** to read each website's home page and up to 2 contact pages for emails, phones and social profile links. Places with an email also land in the **📧 Places with emails** dataset.
3. Download the **Contacts** view as CSV or Excel, or schedule the same search weekly to catch new businesses.

A list of emails and links is not a list of named decision-makers: the contacts are what each business publishes on its own website, and a place without a website, or with a website that shows nothing, comes back without them.

### More Actors for the same job

- [Google Maps Place Details Scraper](https://apify.com/deepmine/google-maps-place-details-scraper): places you already have by place ID, with popular times, live busyness, menus, price level and related places.
- [Google Maps Email Extractor](https://apify.com/deepmine/google-maps-email-extractor), [Google Maps Business Leads](https://apify.com/deepmine/google-maps-business-leads) and [Google Maps No-Website Leads](https://apify.com/deepmine/google-maps-no-website-leads): the same engine set up for contact lists and for businesses without a website.
- [Google Maps Extractor](https://apify.com/deepmine/google-maps-extractor): fast business lists.
- [Google Maps Photos Scraper](https://apify.com/deepmine/google-maps-photos-scraper): the photos of places.
- [Facebook Pages Scraper](https://apify.com/deepmine/facebook-pages-scraper): the Facebook page of a business you found here, with its contacts, followers and rating.
- [LinkedIn Company Scraper](https://apify.com/deepmine/linkedin-company-scraper): the LinkedIn company profile behind a business website.

### Did it help?

If the data was useful, a short review on this page helps other people find the Actor. Missing a field, or a search that doesn't come back the way you expect? Open an issue on the **Issues** tab and we'll look into it.

# 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`):

Paid add-on: <strong>$0.49 per 1,000 places whose website gave at least one email, phone or social profile</strong>, on top of the place price; places without one aren't charged it. Reads each website (home page plus up to 2 contact pages) for emails, phones and Facebook, Instagram, LinkedIn, X, YouTube, TikTok and other profiles. Untick for place data only (Google's phone and website are always in the row). Off when an API input leaves it out.

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

Language of names, categories, hours and reviews, as Google Maps shows them. Pick one, or type any Google language code (e.g. es-419).

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

Keep only places with a category containing one of these words, e.g. <strong>dentist</strong>, <strong>orthodontist</strong>. With no search term, URL or place ID, each category is also searched. 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, ratings and the owner's reply. Signed-out Google Maps shows at most about 15 reviews of a place (the 5 newest and up to 10 most relevant; 5 each in highest or lowest rated order), so a higher number gives up to 15 per place and the run says so. 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. Highest or lowest rated: the 5 highest or lowest rated reviews (signed-out Google Maps shows 5 in those orders). No keyword filter in this version.

## `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. A number above 100 gives 100 (the run says so).

## `photosPerCategory` (type: `integer`):

Adds photosByCategory: up to this many photo links from each photo category the place has (Menu, Food & drink, Vibe, By owner, Latest, Videos, Street View & 360°, a hotel's Rooms...), and fills imageCategories. Included in the place price. 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": true,
  "language": "en",
  "searchMatching": "all",
  "placeMinimumStars": "",
  "website": "allPlaces",
  "skipClosedPlaces": false,
  "maxReviews": 0,
  "reviewsSort": "newest",
  "maxImages": 6,
  "photosPerCategory": 0,
  "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,
    "scrapeContacts": true
};

// 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,
    "scrapeContacts": True,
}

# 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,
  "scrapeContacts": true
}' |
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/BPuT3KmouJ2Z1p4dI/openapi.json
