# Google Places API Alternative | Maps Data | $0.30 / 1K (`hridayrungta/google-maps-places-scraper`) Actor

Google Places API alternative for Google Maps data and local business leads: name, address, phone, website, rating, review count, categories, hours and coordinates. Optional emails from websites. $0.30 per 1,000 places. No login, no API key.

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

## Pricing

from $0.30 / 1,000 place scrapeds

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

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

A **Google Places API alternative** with no API key and no billing setup. Get **Google Maps data** for any business type in any city, without a browser, a login or an API key. For every place you get the name, address, phone number, website, rating, review count, categories, opening hours and coordinates. Switch on **website enrichment** and you also get emails, extra phone numbers and social profile links taken from each business's own website.

It calls the same search endpoint the Google Maps web app uses, over plain HTTP. That makes it fast (up to ~230 places in a single request) and cheap: **$0.30 per 1,000 places**, plus a $0.001 start fee per run.

### What you can use Google Maps data for

- **Google Places API alternative:** the same kind of listing data (name, address, phone, website, rating, coordinates) without a Google Cloud project, an API key or per-request billing.
- **Local business leads:** every dentist, plumber, gym or restaurant in a city with phone and website, filtered by rating, review count or category. Build a Google Maps lead list for cold calling, outreach or a CRM import.
- **Google Maps email extractor:** one run returns the Maps listing and the emails found on the business's own website (enrichment, see limits below).
- **Restaurants, cafes and shops in any city:** export a clean list such as "restaurants in Austin" or "coffee shops in Manchester" to CSV, Excel or JSON.
- **Local SEO and competitor analysis:** map competitors, count businesses per category and neighbourhood, compare ratings and review counts.
- **Market research and site selection:** how many gyms or pharmacies does a district already have? Count them with real coordinates.
- **Google Maps phone numbers and websites:** get the phone (local and international format) and the website of every listing, with tracking parameters removed from URLs.
- **Whole-city coverage:** set a radius and the Actor tiles the area with overlapping map windows and de-duplicates by place, so one search is not limited to the ~230 places Google shows per window.
- **Monitoring ratings over time:** schedule the same run weekly or monthly and compare ratings and review counts between datasets.
- **Google Maps data for AI agents and automations:** feed places into n8n, Make, Zapier, Google Sheets or an LLM workflow through the Apify API.

### What this Actor does NOT do

Be sure this fits before you run it:

- **No review text, photos, popular times, menus, Q\&A or price level.** Those are not in the search response this Actor reads. If you need reviews, use a dedicated reviews scraper (see Related Actors).
- **Results follow Google.** You get what Google Maps returns for the search (ranking, fuzzy matches and all). A search for "dentist" can include pharmacies with a dental counter; use the **Category must contain** filter to narrow it. A misspelled or made-up location is matched to whatever Google thinks you meant.
- **Coverage is best effort.** Google returns at most about 230 places per map window. Area mode (radius) covers much more but cannot guarantee that every business in the area is returned.
- **Website enrichment reads only what is on the pages it fetches** (homepage plus a few contact/about pages, no browser). Sites that render contacts with JavaScript or only offer a contact form return nothing.

### How to scrape Google Maps places

1. Open the Actor and type one or more **Search terms** (dentist, coffee shop, yoga studio).
2. Add **Locations** (Austin, TX, USA / Manchester, UK). Every term is searched in every location.
3. Set **Max places per search** and, if you need more than one map window, a **radius in km**.
4. Optional: filters (rating, reviews, website, phone, category) and **Enrich with website contacts**.
5. Click **Start** and export the dataset as JSON, CSV or Excel, or call it from the API.

### Input

| Field | What it does |
|---|---|
| `searchStrings` | Business types or keywords, one per line. |
| `locations` | Cities, regions or addresses, one per line. Leave empty if the search term already names a place ("dentists in Paris"). |
| `startUrls` | Optional Google Maps search URLs (`google.com/maps/search/pizza+in+rome/@41.9,12.5,13z`). Place pages and short links are not supported. |
| `maxPlacesPerSearch` | Cap per term and location pair. Default 100. |
| `maxItems` | Cap for the whole run. Default 1,000. |
| `radiusKm` | 0 = one map window (up to ~230 places). Above 0 = tile the area around the location and keep only places inside the radius. |
| `tileZoom`, `maxTilesPerSearch` | Window size (15 is about 2 km) and a safety cap on windows per search. Area mode stops early after 12 windows in a row with nothing new. |
| `latitude`, `longitude` | Optional custom search centre. |
| `minRating`, `minReviews`, `requireWebsite`, `requirePhone`, `categoryFilter` | Filters. Free: you only pay for the places you keep. |
| `enrichContactInfo`, `maxPagesPerWebsite` | Visit each place's website for emails, phones and social links. |
| `language`, `countryCode` | Google Maps language (`en`, `de`, `fr`...) and region (`us`, `gb`, `de`...). |
| `useProxy` | `onBlock` (default), `always`, `never`. |

#### Example input

```json
{
  "searchStrings": ["coffee shop"],
  "locations": ["Austin, TX, USA"],
  "maxPlacesPerSearch": 100,
  "minRating": 4,
  "requireWebsite": true,
  "enrichContactInfo": false
}
```

### Output

| Field | Example |
|---|---|
| `title` | Epoch Coffee |
| `categoryName` / `categories` | Coffee shop |
| `address`, `street`, `city`, `state`, `postalCode`, `countryCode`, `neighborhood` | 221 W N Loop Blvd, Austin, TX 78751 |
| `latitude`, `longitude` | 30.3186, -97.7245 |
| `totalScore`, `reviewsCount` | 4.5, 2538 |
| `phone`, `phoneInternational` | (512) 454-3762, +15124543762 |
| `website` | http://www.epochcoffee.com/ (tracking parameters removed) |
| `description` | Google's short description, when the place has one |
| `openingHours` | Seven entries, Monday to Sunday, in the language you chose |
| `placeId`, `fid`, `cid`, `url` | Google place ID, feature ID, customer ID, Maps link |
| `timezone`, `rank`, `searchString`, `location`, `scrapedAt` | America/Chicago, 1, coffee shop, Austin, TX, USA |
| With enrichment: `emails`, `phonesFromWebsite`, `linkedin`, `facebook`, `instagram`, `twitter`, `youtube`, `tiktok`, `pinterest`, `whatsapp`, `contactStatus` | |

#### Example output (real run)

```json
{
  "title": "Epoch Coffee",
  "placeId": "ChIJG-gJw2vKRIYROWi2uwOp8QE",
  "fid": "0x8644ca6bc309e81b:0x1f1a903bbb66839",
  "cid": "140078896924485689",
  "categoryName": "Coffee shop",
  "categories": ["Coffee shop"],
  "address": "221 W N Loop Blvd, Austin, TX 78751",
  "street": "221 W N Loop Blvd",
  "neighborhood": "North Loop",
  "city": "Austin",
  "postalCode": "78751",
  "state": "Texas",
  "countryCode": "US",
  "latitude": 30.3186037,
  "longitude": -97.7245402,
  "totalScore": 4.5,
  "reviewsCount": 2538,
  "phone": "(512) 454-3762",
  "phoneInternational": "+15124543762",
  "website": "http://www.epochcoffee.com/",
  "description": "Hip coffee shop with light bites",
  "openingHours": [
    { "day": "Monday", "hours": "12 AM–11:30 PM" },
    { "day": "Tuesday", "hours": "Open 24 hours" }
  ],
  "timezone": "America/Chicago",
  "url": "https://www.google.com/maps/place/?q=place_id:ChIJG-gJw2vKRIYROWi2uwOp8QE",
  "searchQuery": "coffee shop in Austin, TX, USA",
  "rank": 1,
  "searchString": "coffee shop",
  "location": "Austin, TX, USA",
  "scrapedAt": "2026-10-20T04:06:51.474Z"
}
```

(`openingHours` shortened here; the real row has all seven days.)

### Pricing

Pay per event, no subscription:

| Event | Price |
|---|---|
| Actor started (once per run) | $0.001 |
| Place scraped | $0.0003 ($0.30 per 1,000) |
| Website contacts found (only with enrichment on) | $0.0008 ($0.80 per 1,000) |

Worked examples:

| Run | Cost |
|---|---|
| 100 places | $0.001 + 100 x $0.0003 = **$0.031** |
| 1,000 places | $0.001 + 1,000 x $0.0003 = **$0.301** |
| 1,000 places, 800 with website contacts found | $0.301 + 800 x $0.0008 = **$0.941** |
| 10,000 places | **$3.001** |
| A search that finds nothing | **$0.001** |

You are never charged for: empty or failed searches, places removed by your filters, places already returned earlier in the same run, or websites where enrichment found nothing new. A phone number that Google already lists for the place does not count as a contact find. Set the run's maximum cost in the Apify run options and the Actor stops at your limit, including enrichment.

### Tips

- **Need more than ~230 places for a search?** Set `radiusKm` (for example 15 for a city) and keep `maxTilesPerSearch` high enough. Zoom 16 gives more places in dense city centres at the cost of more requests.
- **The same business twice?** Places are de-duplicated across all searches in a run by Google's feature ID, so a second search term only returns places the first one did not.
- **Several close terms?** "dentist" and "dental clinic" overlap heavily; the second only adds the new places.

### Integrations and scheduling

Everything on Apify can be automated, so Google Maps data can flow into the tools you already use:

- **Google Sheets, Excel, CSV, JSON:** export from the dataset page, or use the Apify integration for Google Sheets to push results into a sheet.
- **Make, n8n and Zapier:** start the Actor from a workflow and read the dataset when the run finishes. Typical flow: new lead list, then CRM import, then outreach sequence.
- **Webhooks and API:** call the Actor over the Apify REST API or the JavaScript and Python clients, and get a webhook when a run succeeds.
- **Apify Schedules:** run the same search daily, weekly or monthly to track new listings and rating changes. The Actor de-duplicates inside one run only, so to find what changed you compare the new dataset with the previous one (a `placeId` match in Sheets or your database works well).
- **Tasks:** save your favourite search (business type, city, filters) as an Apify Task and re-run it with one click or on a schedule.

### FAQ

#### Do I need a Google API key?

No. There is no login and no key.

#### Is this a Google Places API alternative? Why use it instead of the official API?

The official Places API needs a Google Cloud project with billing enabled and an API key, bills per request and per field tier, and limits how many results one search can return, so building a full list of businesses for a city takes many paginated calls. This Actor needs no key, returns the listing fields in one flat row, and can tile a whole city. The trade-off: it is not an official Google product, so Google can change the endpoint it reads, and it does not return reviews or photos. If you need Google's official terms, SLAs or reviews, use the official API.

#### Why is the result different from what I see on maps.google.com?

Google ranks results by relevance and by where you are. Searching from a server in another country can change ranking slightly. Use `countryCode` and `language` to match your market.

#### Is the data accurate?

The fields come straight from Google Maps search results. We spot-checked name, address, rating, review count, phone and website against the live Maps page; they matched. Ratings and review counts change continuously.

#### How do I get all businesses in a city, not just the first page?

Set a **radius** (for example 10 to 15 km around the city centre). The Actor then tiles the area, searches every window and removes duplicates. Coverage is best effort, not guaranteed.

#### Can I get emails from Google Maps?

Google Maps itself does not list emails. With **Enrich with website contacts** on, the Actor visits each business's own website and collects the emails it finds there. Sites with no public email, or that load contacts with JavaScript, return nothing, and you are not charged for those.

#### Does it use proxies?

It requests Google directly first and only falls back to Apify's datacenter proxy (a fresh IP per attempt) when Google refuses a request. If Google stops answering altogether, the run stops with a clear status message instead of retrying forever, and you are not charged for places it never returned.

#### How fast is it?

A search of up to ~230 places takes about 3 to 5 seconds. A 1,000 place area run takes under a minute. Website enrichment is slower (a few seconds per website, run in parallel).

#### What are alternatives to this Google Maps scraper?

The largest Google Maps scraper on the Store is [Google Maps Scraper by Compass](https://apify.com/compass/crawler-google-places), which also covers reviews, images and more detail fields. Pick it when you need those extras. Pick this Actor when you mainly need business listings, phones, websites, ratings and optional emails at a low per-place price. For reviews alone, see [Google Maps Reviews Scraper](https://apify.com/compass/Google-Maps-Reviews-Scraper).

#### Is it legal to scrape Google Maps?

This Actor only reads information that Google shows to anyone without logging in: public business listings. It does not log in, use private data or bypass access controls. Business listing data can still include personal data (a sole trader's phone number, for example), and Google's Terms of Service restrict automated access. You are responsible for how you use the data: follow Google's terms, data protection law (GDPR, CCPA) and anti-spam rules (for example when emailing the addresses you collect). This is not legal advice.

### Related Actors

| Actor | What it does |
|---|---|
| [Google Maps Scraper (Compass)](https://apify.com/compass/crawler-google-places) | The most-used Google Maps scraper on the Store, with reviews, images and extra detail fields |
| [Google Maps Email Extractor](https://apify.com/lukaskrivka/google-maps-with-contact-details) | Google Maps places with contact details from each website |
| [Google Maps Reviews Scraper](https://apify.com/compass/Google-Maps-Reviews-Scraper) | Review text and ratings for places (this Actor does not return reviews) |
| [Contact Info Scraper](https://apify.com/hridayrungta/contact-info-scraper) | Emails, phones and socials from any list of websites |
| [Website Content Crawler](https://apify.com/hridayrungta/website-to-markdown-crawler) | Websites to clean Markdown for LLMs and RAG |
| [Google Trends Scraper](https://apify.com/hridayrungta/google-trends-scraper) | Keyword interest, related queries and trending searches |
| [YouTube Transcript Scraper](https://apify.com/hridayrungta/youtube-transcript-scraper) | Captions and full text from videos, channels and playlists |

# Actor input Schema

## `searchStrings` (type: `array`):

What to look for, one per line: a business type or keyword such as dentist, coffee shop, plumber, yoga studio. Each term is searched in every location below.

## `locations` (type: `array`):

Cities, regions or addresses, one per line (Austin, TX, USA / Manchester, UK / 10115 Berlin). Google geocodes the text itself. Leave empty if your search terms already contain a place ("dentists in Paris").

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

Optional. Paste Google Maps search pages (google.com/maps/search/pizza+in+rome/@41.9,12.5,13z). The search text and map position are read from the URL. Place pages and short links are not supported.

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

Stop each search term + location pair after this many places. One Google Maps window returns at most about 230 places; to go beyond that set a radius below.

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

Cost cap for the whole run: the run writes at most this many places across all searches.

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

0 = one Google Maps window (up to about 230 places per search). Above 0 the Actor tiles the area around the location with many overlapping windows and de-duplicates by place, so a whole city can be covered. Only places inside the radius are kept.

## `tileZoom` (type: `integer`):

How small each window is when a radius is set: 15 = about 2 km windows (balanced), 16 = about 1 km windows (more places in dense city centres, more requests), 14 = about 4 km (rural areas).

## `maxTilesPerSearch` (type: `integer`):

Safety cap on how many map windows are requested for one search when a radius is set. Searching stops early after 12 windows in a row with nothing new.

## `latitude` (type: `number`):

Optional. Search around exact coordinates instead of (or as well as) a text location. Use together with longitude.

## `longitude` (type: `number`):

Optional. Longitude of the custom centre.

## `minRating` (type: `number`):

Keep only places with at least this star rating (0 = no filter). Free: filters never cost extra.

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

Keep only places with at least this many Google reviews (0 = no filter).

## `requireWebsite` (type: `boolean`):

Skip places that list no website.

## `requirePhone` (type: `boolean`):

Skip places that list no phone number.

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

Optional, one per line. Keep only places whose Google category contains one of these words (for example: dentist, orthodontist). Case-insensitive.

## `enrichContactInfo` (type: `boolean`):

Visit each place's own website (homepage plus a few contact/about pages) and add emails, extra phone numbers and social profile links. Billed per place where something was found; failed or empty lookups are free.

## `maxPagesPerWebsite` (type: `integer`):

Homepage plus up to this many pages in total (contact, about, team...). 1 = homepage only.

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

Language of the Google Maps interface: category names and address format follow it (en, de, fr, es, pt, it, ja...).

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

2-letter region code sent to Google (us, gb, de, in, au...). It nudges ranking and result language toward that country.

## `useProxy` (type: `string`):

"On block" requests Google Maps directly and falls back to Apify datacenter proxy (fresh IP per attempt) only when Google refuses a request. "Always" uses the proxy for every request (slower). "Never" never uses a proxy.

## Actor input object example

```json
{
  "searchStrings": [
    "coffee shop"
  ],
  "locations": [
    "Austin, TX, USA"
  ],
  "maxPlacesPerSearch": 10,
  "maxItems": 1000,
  "radiusKm": 0,
  "tileZoom": 15,
  "maxTilesPerSearch": 30,
  "minRating": 0,
  "minReviews": 0,
  "requireWebsite": false,
  "requirePhone": false,
  "enrichContactInfo": false,
  "maxPagesPerWebsite": 3,
  "language": "en",
  "countryCode": "us",
  "useProxy": "onBlock"
}
```

# Actor output Schema

## `places` (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 = {
    "searchStrings": [
        "coffee shop"
    ],
    "locations": [
        "Austin, TX, USA"
    ],
    "maxPlacesPerSearch": 10
};

// Run the Actor and wait for it to finish
const run = await client.actor("hridayrungta/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 = {
    "searchStrings": ["coffee shop"],
    "locations": ["Austin, TX, USA"],
    "maxPlacesPerSearch": 10,
}

# Run the Actor and wait for it to finish
run = client.actor("hridayrungta/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 '{
  "searchStrings": [
    "coffee shop"
  ],
  "locations": [
    "Austin, TX, USA"
  ],
  "maxPlacesPerSearch": 10
}' |
apify call hridayrungta/google-maps-places-scraper --silent --output-dataset

```

## MCP server setup

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