# Google Maps Scraper — Google Places API & Business Leads (`prestilink/google-maps-scraper`) Actor

Google Places API without limits: every business on Google Maps for any search and area, with phone, website, rating, reviews count, address, coordinates, hours and attributes. Optional emails and social profiles from each website. Scans whole cities. No browser.

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

## Pricing

Pay per event

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 — Google Places API & Business Leads

Get **every business on Google Maps** for any search and any area: name, category, **phone**, **website**, **rating**, **number of reviews**, full address, coordinates, opening hours, attributes, price level, booking links and Google IDs. Turn on one option to also get **emails and social profiles** from each business website.

No browser: the Actor reads Google Maps data directly, so **50 places take about 8 seconds and 600 places about a minute**. Ask for more places than one search returns and it **scans the whole city tile by tile**, so you get thousands of businesses, not 120.

**A Google Places API alternative without per-request fees or quotas**: you only pay for the places you get. Places removed by your filters are free.

### Who uses it

- **Lead generation and sales teams**: lists of local businesses with phone, website and email for cold outreach.
- **Web designers and marketing agencies**: businesses **without a website**, or with low ratings, to pitch.
- **Local SEO**: rankings, ratings, review counts and categories of every competitor in an area.
- **Market research and real estate**: how many dentists, gyms or cafes there are in each neighborhood, and how good they are.
- **AI agents and apps**: up-to-date business data through a simple API.

### What you get

| Data | Field |
|---|---|
| Name, main category and all categories | `name`, `category`, `categories` |
| Rating and number of reviews | `rating`, `reviewsCount` |
| Phone, local and international format | `phone`, `phoneInternational` |
| Website and domain | `website`, `domain` |
| Emails and social profiles from the website (option) | `emails`, `socialProfiles` |
| Address and its parts | `address`, `street`, `city`, `postalCode`, `state`, `countryCode` |
| Coordinates and time zone | `latitude`, `longitude`, `timezone` |
| Opening hours and current status | `openingHours`, `openingStatus`, `permanentlyClosed`, `temporarilyClosed` |
| Attributes: accessibility, service options, amenities, payments... | `attributes` |
| Price level, description, booking and order links | `priceLevel`, `description`, `bookingLinks` |
| Google IDs and links | `placeId`, `cid`, `featureId`, `kgmid`, `googleMapsUrl`, `reviewsUrl` |

### How to use

1. Write **what to search**, one per line: `dentist`, `italian restaurant`, `plumber`.
2. Write the **location**: `Austin, TX`, `Paris, France`, `Manchester`, or a postcode. Or paste **Google Maps search URLs**, or give **latitude and longitude** with a radius.
3. Set **Max places per search**. Above about 170, the Actor scans the area to find every place.
4. Optionally keep only places **with or without a website**, **with a phone**, above a **minimum rating** or **number of reviews**, or whose **category contains** a word.
5. Turn on **Emails and social profiles** to visit each website.
6. Run, then download the results as CSV, Excel or JSON, or get them through the API.

**Leads for web agencies**: set **Website** to *Only places without a website*.

### Input example

```json
{
  "searchTerms": ["dentist", "orthodontist"],
  "location": "Austin, TX",
  "maxPlacesPerSearch": 500,
  "scrapeContacts": true,
  "phone": "with",
  "minRating": "4",
  "language": "en"
}
```

### Output example

```json
{
  "type": "place",
  "searchQuery": "dentist",
  "position": 1,
  "name": "ATX Family Dental",
  "category": "Dentist",
  "categories": ["Dentist", "Cosmetic dentist", "Emergency dental service"],
  "rating": 4.9,
  "reviewsCount": 916,
  "phone": "(512) 717-3147",
  "phoneInternational": "+15127173147",
  "website": "https://www.atxfamilydental.com/",
  "domain": "atxfamilydental.com",
  "emails": ["info@atxfamilydental.com"],
  "socialProfiles": {"facebook": "https://www.facebook.com/atxfamilydental", "instagram": "https://www.instagram.com/atxfamilydental"},
  "address": "1700 S 1st St, Austin, TX 78704",
  "street": "1700 S 1st St",
  "city": "Austin",
  "postalCode": "78704",
  "state": "Texas",
  "countryCode": "US",
  "latitude": 30.2482229,
  "longitude": -97.7559705,
  "openingHours": [{"day": "Monday", "hours": "8 AM–5 PM"}, {"day": "Saturday", "hours": "Closed"}],
  "attributes": {"Accessibility": ["Wheelchair accessible entrance", "Wheelchair accessible parking lot"]},
  "placeId": "ChIJb5gBC-u0RIYRHkntaUcdJGs",
  "cid": "7720327853776914718",
  "googleMapsUrl": "https://www.google.com/maps/place/?q=place_id:ChIJb5gBC-u0RIYRHkntaUcdJGs",
  "permanentlyClosed": false,
  "status": "ok"
}
```

Values in this example are illustrative.

### Pricing

Pay per event: a small fee per run, a fee per place, and a fee per website checked for emails and social profiles. Bigger Apify plans pay less. See the **Pricing** tab for exact prices on your plan.

Set a maximum cost per run in the run options and the Actor stops before going over it. Places removed by your filters, duplicates and websites that can't be opened are never charged.

### Good to know

- One Google Maps search shows at most about 170 places. For more, the Actor searches the same term tile by tile around the location, up to your limit or the radius you set.
- The same place is never returned twice in a run, even across search terms.
- Emails come from the business's own website (home page and contact or about page). Not every business publishes one.
- Data is what Google Maps shows at the time of the run, in the language you choose.

### Use it with

- **AI agents and MCP**: add this Actor as a tool through the Apify MCP server (Claude, Cursor, ChatGPT and other MCP clients), LangChain, LlamaIndex or CrewAI.
- **No-code automation**: n8n, Make and Zapier, for example new leads into a Google Sheet or a CRM every week.
- **CRMs and outreach tools**: export CSV for HubSpot, Pipedrive, Salesforce, Instantly or Lemlist.
- **Developers**: the Apify API, Python and JavaScript clients, webhooks and scheduled runs.

***

This Actor is not affiliated with, endorsed by, or sponsored by Google. Google Maps is a trademark of Google LLC.

# Actor input Schema

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

One per line, as you would type it on Google Maps: <b>dentist</b>, <b>italian restaurant</b>, <b>plumber</b>. You can also write the place in it: <b>coffee shop in Lisbon</b>.

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

City, region, postcode or address, like <b>Austin, TX</b>, <b>Paris 11e</b> or <b>90210</b>. Added to every search term.

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

Google stops a single search at about 170 places. Ask for more and the Actor scans the whole area tile by tile to find every place.

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

Visit each place's website and collect emails and social profiles (Facebook, Instagram, LinkedIn, X, YouTube, TikTok, WhatsApp). Charged per website checked.

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

Places without a website are leads for web designers and agencies.

## `phone` (type: `string`):

Keep only places that list a phone number.

## `minRating` (type: `string`):

Keep only places rated at least this high.

## `minReviews` (type: `integer`):

Keep only places with at least this many reviews.

## `categoryFilter` (type: `array`):

Keep only places whose Google category contains one of these words, like <b>dentist</b> or <b>orthodont</b>. Removes off-topic results.

## `skipClosed` (type: `boolean`):

Leave out places marked permanently or temporarily closed.

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

Language of categories, hours and descriptions: en, fr, de, es, it, pt, ar...

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

Two-letter country code, like US or FR, to read Google Maps as a local user would.

## `latitude` (type: `string`):

Instead of a location: search around this point, like 30.2672. Set longitude too.

## `longitude` (type: `string`):

Like -97.7431.

## `radiusKm` (type: `integer`):

How far from the location or point to scan when you ask for more places than one search returns. Empty means the Actor sizes it from the first results.

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

Paste Google Maps search URLs, like https://www.google.com/maps/search/dentist+in+austin/@30.26,-97.74,13z. The search and the map area are reused.

## Actor input object example

```json
{
  "searchTerms": [
    "dentist"
  ],
  "location": "Austin, TX",
  "maxPlacesPerSearch": 50,
  "scrapeContacts": false,
  "website": "any",
  "phone": "any",
  "minRating": "0",
  "minReviews": 0,
  "skipClosed": true,
  "language": "en"
}
```

# Actor output Schema

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

One item per place: name, category, rating, reviews count, phone, website, emails and social profiles, address, coordinates, hours, attributes, IDs and a Google Maps link.

# 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, TX",
    "maxPlacesPerSearch": 50
};

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

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

```

## MCP server setup

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