# Google Maps Places Scraper: Phones, Hours, Owners (`luzivanlt/google-maps-places-scraper`) Actor

Every place a Google Maps search lists, read to the end, with phone, website, hours and owner. $0.40 per 1,000 places. Attributes and coordinates. No add-on fees.

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

## Pricing

from $0.28 / 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 Places Scraper: Phones, Hours, Owners

Get every place a Google Maps search lists, read to the end of the list
(about 120 to 220 places a search), each with every detail Google shows in
its results: phone, website, rating, review count, opening hours, service
hours, accessibility and other attributes, booking and ordering links, the
owner, the photo, and exact coordinates. One row per place, in the language
you choose. No add-on fees and no Google account.

Tested daily. Latest check: 100 of 100 dentists asked for in Austin, Texas;
669 places from four searches in Austin and Hanoi, each read to the end of
Google's list, in 42 seconds; 60 cafés in Hanoi with Vietnamese names,
categories and hours.

### What does this Actor do?

You give it search terms and a location, or links to Google Maps searches.
For each search it saves one row per place Google Maps lists, until it
reaches your limit or the list ends.

Each place comes with:

- its name (and its name in the local language, when Google shows one), its
  categories and a description when Google has one
- its full address, and the address split into street, neighborhood, city,
  postal code, state and country
- latitude and longitude, plus the entrance's position when Google marks one
- phone number in three forms (as shown, national, and digits only)
- website, and on a few places other links Google shows (social pages)
- rating, number of reviews and a link to the reviews
- the cover photo and the number of photos
- the opening hours for each day of the coming week, today's open/closed
  line, and service hours such as happy hours or delivery when the place
  lists them
- attributes such as wheelchair access, and labels such as LGBTQ+ friendly
  or women-owned, when the place has them
- "Reserve a table" and "Order online" links with their providers, when the
  place offers them
- the owner's name, Google id and photo, and whether the listing is claimed
- Google's ids for the place: place id, CID, data id and Knowledge Graph id,
  and a Google Maps link
- the search it was found in, and its rank there

### Why use it?

- **Build lead lists.** Phone, website and owner for every business in a
  category and city.
- **Every field, one price.** Everything Google shows for a place in its
  results comes in the same row, for the same price per place.
- **Any language, any country.** Choose the language Google answers in;
  categories, hours and attributes come in it.
- **Use the data anywhere.** Download as JSON, CSV or Excel, or send it to
  your own tools through Apify's API and integrations.

### How to use it

1. Type one or more **Search terms** and a **Location**, or paste **Search
   links**, or both.
2. Optionally, set the **Language** and **Max places per search**.
3. Click **Start**. When the run ends, open the **Output** tab to view the
   places or download them.

Run it with no input to see a sample: up to 100 dentists in Austin, Texas,
charged as usual.

#### Links that work

A Google Maps search, such as
`https://www.google.com/maps/search/dentist+in+austin`. A search link that
carries a map position, such as
`https://www.google.com/maps/search/restaurants/@48.8566,2.3522,14z`,
searches around that position. A single place's page, a list or a route is
refused before anything is read, naming the link.

### Input

| Field                                            | What it does                                                       | Default |
| ------------------------------------------------ | ------------------------------------------------------------------ | ------- |
| **Search terms** (`searchTerms`)                 | What to search for, one search each                                | —       |
| **Location** (`location`)                        | A city, district or region, added to every term as "term in place" | —       |
| **Search links** (`startUrls`)                   | Google Maps search links                                           | —       |
| **Language** (`language`)                        | The language Google answers in, as a code (`en`, `de`, `vi`)       | `en`    |
| **Max places per search** (`maxPlacesPerSearch`) | Stop each term or link after this many places, 1 to 500            | `100`   |

Give at least one search term or one link. Example input:

```json
{
  "searchTerms": ["dentist", "orthodontist"],
  "location": "Austin, Texas",
  "language": "en",
  "maxPlacesPerSearch": 200
}
```

### Output

One row per place. An example, with made-up values:

```json
{
  "place_id": "ChIJ0000000000000000000000",
  "name": "Example Family Dental",
  "name_local": null,
  "name_local_language": null,
  "category": "Dentist",
  "categories": ["Dentist", "Cosmetic dentist"],
  "place_type": "dentist",
  "description": "Family dental practice offering cleanings, fillings and crowns.",
  "description_short": null,
  "address": "100 Example St, Austin, TX 78701",
  "address_lines": ["100 Example St", "Austin, TX 78701"],
  "neighborhood": "Downtown",
  "street": "100 Example St",
  "city": "Austin",
  "postal_code": "78701",
  "state": "Texas",
  "country_code": "US",
  "locality": "Austin, TX",
  "regions": ["Austin", "Texas", "United States"],
  "latitude": 30.2672,
  "longitude": -97.7431,
  "entrance_latitude": 30.2671,
  "entrance_longitude": -97.7432,
  "timezone": "America/Chicago",
  "phone": "(512) 555-0100",
  "phone_national": "(512) 555-0100",
  "phone_unformatted": "+15125550100",
  "website": "https://example-dental.com/",
  "website_domain": "example-dental.com",
  "links": [{ "url": "https://example-dental.com/", "domain": "example-dental.com" }],
  "rating": 4.8,
  "reviews_count": 312,
  "reviews_url": "https://search.google.com/local/reviews?placeid=ChIJ0000000000000000000000",
  "image_url": "https://lh3.googleusercontent.com/…",
  "photos_count": 45,
  "opening_hours": [
    { "day": "Monday", "date": "2026-10-19", "hours": ["8 AM–5 PM"] },
    { "day": "Sunday", "date": "2026-10-25", "hours": ["Closed"] }
  ],
  "open_status": "Open · Closes 5 PM",
  "permanently_closed": false,
  "temporarily_closed": false,
  "service_hours": [],
  "attributes": [
    {
      "group": "Accessibility",
      "name": "Wheelchair accessible entrance",
      "value": true,
      "text": "Has wheelchair accessible entrance"
    }
  ],
  "highlights": ["Identifies as women-owned"],
  "actions": [
    {
      "label": "Book online",
      "url": "https://www.google.com/maps/reserve/…",
      "providers": [
        {
          "name": "Example Booking",
          "domain": "booking.example",
          "url": "https://booking.example/…"
        }
      ]
    }
  ],
  "owner_name": "Example Family Dental",
  "owner_id": "100000000000000000000",
  "owner_photo_url": "https://lh3.googleusercontent.com/…",
  "is_claimed": true,
  "cid": "1000000000000000000",
  "data_id": "0x0000000000000000:0x0de0b6b3a7640000",
  "kgmid": "/g/11example",
  "google_maps_url": "https://www.google.com/maps?cid=1000000000000000000",
  "search_query": "dentist in Austin, Texas",
  "search_rank": 1,
  "search_url": "https://www.google.com/maps/search/dentist%20in%20Austin%2C%20Texas?hl=en"
}
```

| Field                                          | What it holds                                                                                     |
| ---------------------------------------------- | ------------------------------------------------------------------------------------------------- |
| `place_id`                                     | Google's place id (`ChIJ…`)                                                                       |
| `name`                                         | The place's name                                                                                  |
| `name_local`, `name_local_language`            | Its name in the local language, and that language, when Google shows one                          |
| `category`, `categories`                       | Its main category, and all of them                                                                |
| `place_type`                                   | Google's type for the place in lower case (`restaurant`, `dentist`)                               |
| `description`, `description_short`             | Google's description of the place, long and short, when it has one                                |
| `address`, `address_lines`                     | The full address, and the same split into the lines Google shows                                  |
| `neighborhood`, `street`, `city`               | Parts of the address                                                                              |
| `postal_code`, `state`, `country_code`         | Parts of the address. `state` holds the state, or the district and city where there are no states |
| `locality`, `regions`                          | The area line Google shows ("Austin, TX"), and the wider areas the place lies in                  |
| `latitude`, `longitude`                        | Where the place is                                                                                |
| `entrance_latitude`, `entrance_longitude`      | Where its entrance is, when Google marks one                                                      |
| `timezone`                                     | The place's time zone                                                                             |
| `phone`, `phone_national`, `phone_unformatted` | Its phone number as shown, in national form, and as digits with the country code                  |
| `website`, `website_domain`, `links`           | Its website; `links` holds other links Google shows, rarely filled                                |
| `rating`, `reviews_count`, `reviews_url`       | Its star rating, the number of reviews, and where to read them                                    |
| `image_url`, `photos_count`                    | Its cover photo, and how many photos it has                                                       |
| `opening_hours`                                | Each day of the coming week, with its date and hours                                              |
| `open_status`                                  | The open/closed line Google showed when the place was read ("Open · Closes 10 PM")                |
| `permanently_closed`, `temporarily_closed`     | `true` when Google marks the place closed. Read in English runs only; empty in other languages    |
| `service_hours`                                | Other hours the place lists (happy hours, delivery, kitchen), by day                              |
| `attributes`                                   | Facts Google lists, by group, each `true` or `false` ("Wheelchair accessible entrance")           |
| `highlights`                                   | Labels the business chose ("LGBTQ+ friendly", "Identifies as women-owned")                        |
| `actions`                                      | "Reserve a table", "Order online" and similar links, with the sites that take the order           |
| `owner_name`, `owner_id`, `owner_photo_url`    | The listing's owner as Google shows them, their Google id and photo                               |
| `is_claimed`                                   | `false` when Google offers to let the business claim the listing                                  |
| `cid`, `data_id`, `kgmid`                      | Google's other ids for the place                                                                  |
| `google_maps_url`                              | The place on Google Maps                                                                          |
| `search_query`, `search_rank`, `search_url`    | The search the place was found in, its position there, and the search on Google Maps              |

Not included: reviews' text, the full photo gallery, the price level,
popular times, and the questions and answers.

The rows hold what businesses publish on Google Maps, and the owner fields
can name a person. Where the data includes personal data, your use of it
must follow the privacy laws that apply to you.

### How much does it cost?

No surcharges and no paid options; an item that fails is not charged.

You pay for what you get:

- **$0.40 per 1,000 places** ($0.0004 a place). Each place is charged once per run, even when two of your searches list it.
- No start fee, and nothing per search.

So a search that lists 200 places costs $0.08. If you set a maximum cost for a run, the Actor stops when it reaches it and keeps every place saved so far.

### How long does a run take?

About 100 places in 14 to 80 seconds; 669 places from four whole searches
in 42 seconds. Searches are read at the same time.

### Good to know

- **About 120 to 220 places a search.** That is as deep as Google Maps lists
  one search, whatever the area holds. For more, split it: several districts
  or neighborhoods instead of one city, or several related terms.
- **Google decides what matches.** The Actor returns what Google lists for
  the search, in Google's order.
- **One place, one row.** A place found again in the same run, under the same
  or another search, is not saved again.
- **Without a location**, Google picks the area itself, and results can come
  from anywhere in a country. Put the place in the term or the **Location**
  field.
- **A search that names one place** (an exact business name) can return
  nothing: Google opens that place instead of a list.

### More Actors from us

- [Google Play Reviews Scraper: Device, Star Filter & Replies](https://apify.com/luzivanlt/google-play-reviews-scraper): Google Play reviews with the device each was written on, a star filter and the developer's reply.
- [Facebook Ads Library Scraper: Meta Ads by Keyword or Page](https://apify.com/luzivanlt/facebook-ads-library-scraper): Meta Ad Library ads by keyword, Page or Ad Library link, with text, images, videos and dates.
- [Facebook Comments Scraper: With Replies](https://apify.com/luzivanlt/facebook-comments-scraper): Comments and replies from public Facebook posts, reels and videos, with reactions by type.
- [Facebook Pages Scraper: Contacts, Followers & Ratings](https://apify.com/luzivanlt/facebook-pages-scraper): Facebook Page details from links: exact follower count, phone, email, address, websites.
- [Facebook Posts Scraper: Groups, Pages & Profiles](https://apify.com/luzivanlt/facebook-posts-scraper): Posts from public Facebook groups, Pages and profiles with reaction, comment and share counts.
- [Instagram Posts Scraper: Likes, Comments & Dates](https://apify.com/luzivanlt/instagram-posts-scraper): A public Instagram profile's posts, newest first, each with its like count, comment count and exact date.
- [Lazada Reviews Scraper: Newest First, Sub-Ratings & Photos](https://apify.com/luzivanlt/lazada-reviews-scraper): The newest reviews of any Lazada product first, with separate stars for product, seller and delivery.

### Use it from an AI agent or the API

One call starts a run and returns its items (Apify waits up to 300 seconds; for a
longer run, start it with `POST /v2/acts/…/runs` and read its dataset):

```text
POST https://api.apify.com/v2/acts/luzivanlt~google-maps-places-scraper/run-sync-get-dataset-items?token=<YOUR_APIFY_TOKEN>
```

With the sample input as its JSON body:

```json
{
  "searchTerms": ["dentist"],
  "location": "Austin, Texas",
  "language": "en",
  "maxPlacesPerSearch": 100
}
```

Its inputs, in the order of the input form:

| Input                                        | What it takes                                                                                                                   | Default |
| -------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------- | ------- |
| `searchTerms` (Search terms)                 | What to search for on Google Maps, one search per term, e.g. "dentist" or "coffee shop".                                        | —       |
| `location` (Location)                        | Where to search, as you would type it on Google Maps: a city, a district or a region, e.g. "Austin, Texas" or "Hanoi, Vietnam". | —       |
| `startUrls` (Search links)                   | Links to Google Maps searches (google.com/maps/search/…), e.g. https://www.google.com/maps/search/dentist+in+austin.            | —       |
| `language` (Language)                        | The language Google Maps answers in, as a language code, e.g. "en", "de", "vi" or "pt-BR".                                      | `"en"`  |
| `maxPlacesPerSearch` (Max places per search) | Stop each search term or link after this many places, from 1 to 500; default 100.                                               | `100`   |

Apify's MCP server, `https://mcp.apify.com`, lists it as `luzivanlt/google-maps-places-scraper`. To give an
AI agent this Actor as a tool, add the server to the agent's MCP config:

```json
{
  "mcpServers": {
    "apify": {
      "url": "https://mcp.apify.com?tools=luzivanlt/google-maps-places-scraper"
    }
  }
}
```

The client signs in with OAuth, or add `"headers": { "Authorization": "Bearer <APIFY_TOKEN>" }`.

Charged per place delivered; the sample input above costs at most $0.04.

# Changelog

This Actor's version history is a separate document: https://apify.com/luzivanlt/google-maps-places-scraper/changelog.md

# Actor input Schema

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

What to search for on Google Maps, one search per term, e.g. "dentist" or "coffee shop". Each term is up to 200 characters, and the same term typed in another case is searched once. A link here is refused: paste it under Search links. Give at least one search term or one link.

## `location` (type: `string`):

Where to search, as you would type it on Google Maps: a city, a district or a region, e.g. "Austin, Texas" or "Hanoi, Vietnam". Added to every search term as "<term> in <location>", not to Search links. Up to 200 characters. Leave it empty to put the place in the term yourself; without one, Google picks the area and results can come from anywhere in a country.

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

Links to Google Maps searches (google.com/maps/search/…), e.g. https://www.google.com/maps/search/dentist+in+austin. Any Google domain works (google.de, maps.google.com), and so does Google's /maps/search/?api=1\&query=… form. A link that carries a map position (/@latitude,longitude,zoom) searches around it. A place's page, a list or a route is refused before anything is read.

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

The language Google Maps answers in, as a language code, e.g. "en", "de", "vi" or "pt-BR". Names, categories, hours and attributes come in it, for search terms and links alike. Default "en". Whether a place is marked closed is read in English runs only.

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

Stop each search term or link after this many places, from 1 to 500; default 100. Google lists about 120 to 220 places for one search. Each place is charged once per run ($0.40 per 1,000 places), so this caps what each search costs. Example: 200 places cost at most $0.08.

## Actor input object example

```json
{
  "searchTerms": [
    "dentist"
  ],
  "location": "Austin, Texas",
  "language": "en",
  "maxPlacesPerSearch": 100
}
```

# Actor output Schema

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

Every place the run saved, one row per place.

## `allFields` (type: `string`):

The same rows with every field.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

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

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "searchTerms": [
        "dentist"
    ],
    "location": "Austin, Texas",
    "maxPlacesPerSearch": 100
};

// Run the Actor and wait for it to finish
const run = await client.actor("luzivanlt/google-maps-places-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 = {
    "searchTerms": ["dentist"],
    "location": "Austin, Texas",
    "maxPlacesPerSearch": 100,
}

# Run the Actor and wait for it to finish
run = client.actor("luzivanlt/google-maps-places-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 '{
  "searchTerms": [
    "dentist"
  ],
  "location": "Austin, Texas",
  "maxPlacesPerSearch": 100
}' |
apify call luzivanlt/google-maps-places-scraper --silent --output-dataset

```

## MCP server setup

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