Google Maps Places Scraper
Pricing
from $1.28 / 1,000 place rows
Google Maps Places Scraper
Search Google Maps and get one row per place: name, phone, website, address, coordinates, categories, rating, review count, hours, and attributes. Look up known place IDs too. Repeats and places outside your country filter are free.
Pricing
from $1.28 / 1,000 place rows
Rating
0.0
(0)
Developer
Mamba Labs
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
an hour ago
Last modified
Categories
Security
Limited permissionsShare
Give searches such as coffee shop in Austin, TX, or Google place IDs you already have, and get one row per place: name, phone, website, address, coordinates, categories, rating, review count, hours, attributes, and description. You pay per place returned. Repeats, places outside your country filter, and summaries are free.
Features
- Search or look up. Run searches, cross search terms with locations, or look up known ChIJ place IDs and Google Maps URLs.
- Plain place data. Place ID, CID, feature ID, phone in local and international format, full address and its parts, neighborhood, coordinates, time zone, all categories, rating, review count, weekly hours, open status, attributes, description, and, on place lookups, one photo.
- A country filter. A search for Berlin can return Berlin, New Jersey, on later pages. Set
only_countryto DE, and those rows are dropped and not charged. - One charge per place. Google repeats places across pages. A place found twice in a run is returned and charged once.
- No empty successful runs. Each search ends with one free summary row that says how many places were found, returned, and skipped, or why there were none.
- Clay ready. Number and on or off inputs are text. A comma stays inside a search.
How the data is read
The actor sends the same two plain requests the Google Maps web page sends, one for a search and one for a place, through the Apify proxy default pool. No login, no Google API key, no browser, and no other developer's actor. If Google answers with a rate limit or a challenge, the actor waits and retries, then writes a free blocked row. It does not try to get past a challenge.
Input
| Field | Type | Default | What it does |
|---|---|---|---|
search_terms | array | What to search on Google Maps, such as dentist in Austin, TX. One search per entry. Each search returns up to about 120 to 200 places, so split a large area into neighborhoods. | |
locations | array | Optional. Each search term is run once per location, as "term in location". Leave empty when your searches already name the place. | |
places | array | Optional. Look up places you already know: a ChIJ place ID, or a Google Maps place URL. Each costs one place row. | |
max_places_per_search | string | 20 | Whole number from 1 to 500. Default 20. Google stops most searches between 120 and 200 places. |
only_country | string | Optional 2 letter country code, such as DE. Places in other countries are dropped and not charged. A search for Berlin can otherwise return Berlin, New Jersey, on later pages. | |
dedupe | string | yes | yes or no. Default yes: a place found twice in a run is returned and charged once. |
language | string | en | Language code for names and categories, such as en or de. Default en. |
results_country | string | us | 2 letter code Google uses to tailor results. Default us. It does not limit results to that country; use only_country for that. |
max_charge_usd | string | Optional. The run stops before a charge that would pass this amount. Summary rows are always returned. |
Output
| Field | Type | What it holds |
|---|---|---|
row_type | string | One of: place, search_summary, run_summary. run_summary is the one free row written when the input is refused. |
input | string | The search or place reference that produced this row. |
rank | integer | Position in this search, counting each place once. |
name | string | Place name. |
place_id | string | Google place ID. Stable key for dedupe across runs. |
cid | string | Google customer ID for the place. |
feature_id | string | Google feature ID. |
google_maps_url | string | Link to the place. |
website | string | Listed website with tracking parameters removed. |
website_domain | string | Domain of the website. |
phone | string | Listed phone in local format. |
phone_international | string | Listed phone in international format. |
address | string | Full address. |
street | string | Street address. |
neighborhood | string | Neighborhood Google gives. |
city | string | City. |
postal_code | string | Postal code. |
state | string | State or region. |
country_code | string | 2 letter country code. |
latitude | number | Latitude. |
longitude | number | Longitude. |
time_zone | string | IANA time zone. |
primary_category | string | First category Google lists. |
categories | array | All categories Google lists. |
rating | number | Average star rating. |
review_count | integer | Number of reviews. |
reviews_url | string | Google page with the reviews. |
description | string | Editorial description where Google has one. |
attributes | array | Features the place has, by group, such as Accessibility: Wheelchair accessible entrance. |
hours_text | string | Weekly hours as text. |
open_status_text | string | Status when read, such as Open, Closes 3 PM or Permanently closed. |
photo_url | string | One photo Google shows for the place. Filled on place lookups only. |
places_found | integer | search_summary: places Google listed. |
places_returned | integer | search_summary: place rows returned. |
places_skipped | integer | search_summary: repeats and places outside only_country, not charged. |
pages_read | integer | search_summary: pages read. |
row_status | string | ok, or why this row carries no data: no_results, no_change, partial, blocked, or error. |
error_reason | string | Why the row is not ok. A refused input reads input_invalid: followed by what to fix. |
billable_events_json | string | What this row was billed as, for example {"place-row":1}. {} means free. |
scraped_at | string | When the row was written, UTC. |
Pricing
Pay per event. Summary rows, repeats, places outside only_country, and a refused input are free.
| Event | Free plan | Bronze | Silver | Gold |
|---|---|---|---|---|
place-row, one place | $0.0015 | $0.001425 | $0.00135 | $0.001275 |
apify-actor-start, once per run (one per GB of memory; the default 256 MB is one) | $0.007 | $0.007 | $0.007 | $0.007 |
Per 1,000 rows of place-row: $1.50 on the free plan, $1.28 on Gold.
Free plan cap: 1.50 USD of evaluation a month, about 1000 rows. Any paid Apify plan removes the cap, and it resets on the 1st. The run stops before a charge that passes your maximum charge per run in Apify or your max_charge_usd input.
Mamba Labs pays the platform costs of your run, Apify proxy traffic included.
Usage examples
Clay. Number and on or off inputs are text fields, which is what Clay sends. A list input takes a JSON list, so put the column inside a one item list.
Search.
{ "search_terms": ["dentist", "orthodontist"], "locations": ["Austin, TX", "Dallas, TX"], "max_places_per_search": "50", "only_country": "US" }
Lookup.
{ "places": ["ChIJIWnn51HTD4gR1Ie6zt2J2dE"] }
MCP. The Mamba Labs MCP server @mambalabsdev/mcp-google-maps-places-scraper exposes this actor to Claude and other MCP clients.
Error handling
| Case | What you get |
|---|---|
| Missing or unreadable input | One free row, row_type run_summary, error_reason starting input_invalid: with what to fix. The run ends successfully and charges nothing but the run start |
| A search with no places | One free search_summary row with row_status no_results |
| Google rate limits or challenges a search | One free search_summary row with row_status blocked. Two blocked searches in a row stop the run |
| A place reference that cannot be read | One free row with row_status error or no_results |
| Searches or lookups in a row return nothing | The run stops after 3 searches or 2 lookups before any place is returned, or after 10 once places have been returned, so a bad list does not keep spending |
| The run is close to its timeout | The actor stops starting new work 90 seconds before the timeout and delivers what it has |
Limitations
- Google ends most searches between 120 and 200 places. For a larger area, split it into neighborhoods or nearby cities.
- No popular times, review text, menus, or photos beyond one. Popular times were absent on all 4 busy places tested with this route, logged out.
- No price level: the field was empty on the places tested.
- No owner name, owner account, or review author data. No emails: this actor does not read websites.
- A service area business can have no address. Its row has an empty
country_code, andonly_countrykeeps it. - A search that keeps no place ends with a free summary row: after 1 page before the run has returned any place, or 3 pages after. A place only found on a later page can be missed by a narrow
only_country. - Result order can change between runs, because the proxy pool mixes exit countries.
results_countrytailors results but does not limit them. Useonly_countryto limit them.- Google's terms restrict automated collection and bulk export of Maps content. Read them and decide what your use allows.
Mamba Labs actor suite
Built by Mamba Labs.