Google Maps Reviews Scraper
Pricing
from $0.26 / 1,000 reviews
Google Maps Reviews Scraper
Google Maps reviews scraper API for a place link, place ID, CID or business name. Each row has the star rating, full text, exact date, reviewer, owner reply and photos. It keeps paging until it has what you asked for or Google runs out. $0.27 per 1,000 reviews.
Pricing
from $0.26 / 1,000 reviews
Rating
5.0
(2)
Developer
Dami's Studio
Maintained by CommunityActor stats
0
Bookmarked
47
Total users
12
Monthly active users
a day ago
Last modified
Categories
Features
Share
Google Maps reviews scraper for a link, place ID, CID, business name or a search like "coffee shops in Lisbon": star rating, the full text, the exact date, who wrote it, the owner's reply, photos and videos. It keeps paging rather than stopping at the first screen.
How deep a run reads depends on the place.
| Input | Maps links, short links, place IDs, CIDs, business names or search phrases, up to 50 per run |
| Output | One row per review: stars, text, exact date, reviewer, owner reply, photos, ratings for food, service or rooms. Place details if you switch them on |
| Ceiling | 50,000 reviews per run |
| Account needed | None, and no Google API key |
| Price | $0.27 per 1,000 reviews on the free plan, down to $0.264 on Business. The free plan's $5 a month covers about 18,000 |
| Using an AI agent? | |
|---|---|
| Actor | dami_studio/google-maps-reviews-scraper |
| Set one field | placeUrls, labelled "Place links or IDs" in the Console |
| Cap the bill | maxTotalChargeUsd on the run, for example 0.10: it never charges past that |
| MCP, one link | https://mcp.apify.com/?tools=fetch-actor-details,dami_studio/google-maps-reviews-scraper |
| How often | Weekly, or daily for a place you watch |
🔍 What Google Maps Reviews Scraper does
It takes whatever form of a place you have: a copied address-bar URL, a maps.app.goo.gl short
link, a ChIJ… place ID, a numeric CID, or the business name. With Places per search above 1, a
phrase like "restaurants in Austin TX" gives up to 20 places in Google's order. Then it pages through
each review list until it has what you asked for or Google stops.
Up to 50 places per run. A total budget is split evenly, so a chain audit gets a comparable sample from every branch; a per-place cap alone gets that many from each.
Place details are optional: the star average, address, categories, phone and website on every row, and opening hours and amenities in one free row per place.
📋 What data you get from each Google Maps review
| What you get | Field |
|---|---|
| The place, as you named it and as Google knows it | target, placeName, placeUrl, placeId, cid, featureId |
| A stable id for the review, and its link | reviewId, reviewUrl |
| Stars and the text as written | rating, text, language, languageName |
| Google's translation, when the review is in another language | textTranslated, translationLanguage, translationLanguageName, originalText |
| Ratings for parts of the visit (food, service, rooms, location) | aspectRatings |
| Answers about the visit: meal type, price per person, trip type, noise, written tips | visitDetails |
| The exact time it went up, and Google's relative wording | publishedAt, relativeDate |
| Whether it was edited, and when | isEdited, editedAt |
| Who wrote it and how active they are on Maps | reviewerName, reviewerUrl, reviewerId, reviewerReviewsCount, reviewerPhotosCount, isLocalGuide |
| The owner's reply, roughly when, and Google's translation of it | ownerReply, ownerReplyRelativeDate, ownerReplyTranslated |
| Every photo link, and videos as a still plus a video link | reviewPhotosCount, reviewPhotoUrls, reviewVideos |
| Where the entry comes from, and the place's position in a search | reviewOrigin, searchRank |
| Place details, when switched on | placeRating, placeReviewsCount, placeAddress, placeStreet, placeCity, placePostalCode, placeState, placeCountryCode, placeNeighborhood, placeLatitude, placeLongitude, placeCategory, placeCategories, placePhone, placeWebsite, placePlusCode, placeKgmid, placeHotelStars, placeClosed, placeClaimed |
| Opening hours, amenities and highlights, in the place record | openingHours, amenities, highlights, timeZone |
| When the row was read | scrapedAt |
▶️ How to scrape Google Maps reviews
- Open Google Maps Reviews Scraper and click Try for free.
- Paste one or more links into Place links or IDs, or type names or a phrase into Business names to look up.
- Set Maximum reviews. Start around 20 to see the output shape.
- Pick a Review order and a Language if the defaults do not suit you, then click Start.
- Download the dataset as JSON, CSV or Excel, or read it from the Apify API.
💰 How much does it cost to scrape Google Maps reviews?
$0.27 per 1,000 reviews. That is the free plan's price; paid plans pay a little less: $0.268 on Starter, $0.266 on Scale and $0.264 on Business. On the free plan, the $5 Apify gives you each month covers about 18,000 reviews.
You pay per review row delivered. Reviews dropped by reviewsSince or onlyWithText, duplicates,
entries from other sites, place records, the sample row and diagnostic rows are all free. The
keyword, star and older-than filters are optional add-ons, billed from 9 November 2026: each review
they read and leave out costs $0.01 per 1,000, the same on every plan. Before that day they are free.
📥 What you give it
{"searchTerms": ["coffee shops in Lisbon"],"maxPlacesPerSearch": 5,"maxReviewsPerPlace": 40,"sort": "newest","reviewsSince": "6 months","maxStars": 2,"includePlaceDetails": true,"language": "en"}
| Field | Default | What it is |
|---|---|---|
placeUrls | none | Maps links, short links, place IDs or numeric CIDs. Up to 50. Paste the link exactly as the address bar gives it. |
searchTerms | none | Business names or phrases, if you do not have links. Up to 50. |
maxPlacesPerSearch | 1 | Places taken from each name or phrase, in Google's order, up to 20. 1 keeps the top match. |
maxReviews | 20 | Total across every place in the run, split evenly between them. Up to 50,000. |
maxReviewsPerPlace | none | Cap per place, on top of the even split. Set it with no total and it sets the total: 100 each for 10 places is 1,000. |
sort | newest | newest, relevant, highest or lowest. |
reviewsSince | none | Only reviews after this point. |
reviewsBefore | none | Add-on. Only reviews before this point. |
minStars, maxStars | none | Add-on. Only reviews with that many stars, 1 to 5. |
keywords | none | Add-on. Only reviews whose text or translation contains one of these words. Capitals and accents don't matter; a word matches at the start of a word, so tea finds "teapot" but not "steak". A place with no match in 1,000 reviews in a row is not read further. |
onlyWithText | off | Skip star-only ratings with no words. |
includeReviewerDetails | on | Off leaves out the reviewer's name, link, photo and id. |
includePlaceDetails | off | Place columns on every review row. |
includePlaceRecord | off | One free place row per place, with hours and amenities. |
language | en | Which language Google should translate into. |
country | us | Which country's Google to ask. |
proxyUrls | none | Optional. Your own servers, used exactly as given. |
Dates. reviewsSince and reviewsBefore take a date like 2026-01-15 or a window like 36 hours,
30 days, 2 weeks, 6 months or 1 year. Anything else stops the run before a page is read, with
a free BAD_INPUT row, instead of quietly pulling the full history.
reviewsSince stops paging early only when sort is newest. On any other order it still
filters, but the run reads further. The star filters stop early on lowest and highest.
📤 What you get back

A real row from a test run on 24 October 2026, with the long text and links trimmed:
{"ok": true,"charged": true,"recordType": "review","target": "Katz's Delicatessen New York","placeName": "Katz's Delicatessen","placeUrl": "https://www.google.com/maps?cid=3545819340560108778","placeId": "ChIJCar0f49ZwokR6ozLV-dHNTE","reviewId": "Ci9DQUlRQUNvZENodHljRjlvT2xOMWMybGhiekIyUWtoTlgwOWtUMUYwYmxad1FsRRAB","rating": 5,"text": "Katz's has been open since 1888 and it shows in the best possible way. ...","originalText": null,"language": "en","publishedAt": "2026-06-11T19:27:42.022Z","relativeDate": "4 months ago","reviewerName": "mutoni F.","reviewerReviewsCount": 4,"isLocalGuide": true,"ownerReply": null,"reviewPhotosCount": 4,"reviewPhotoUrls": ["https://lh3.googleusercontent.com/grass-cs/..."],"reviewOrigin": "Google","aspectRatings": { "Food": 5, "Service": 5, "Atmosphere": 5 },"visitDetails": { "Meal type": "Brunch", "Price per person": "$30–40", "Wait time": "No wait" },"textTranslated": null,"languageName": "English","isEdited": false,"reviewVideos": [],"searchRank": 1}
| Field | How to read it |
|---|---|
publishedAt | A real timestamp. On an edited review it is the time of the edit, and isEdited is true. |
reviewId | Stable. Use it as your dedupe key across runs. |
text, textTranslated, originalText | text is the review as written. When the writer used another language than yours, textTranslated holds Google's translation and originalText repeats the writer's words; both are null otherwise. |
aspectRatings, visitDetails | Only what the reviewer filled in, labelled in the language you asked for. null when they skipped it. |
isEdited | Read from Google's wording in English, German, French, Spanish, Portuguese, Italian and Dutch; null in other languages. |
isLocalGuide | The badge as true or false. Google's numeric level is not published here. |
placeName | null when you gave a bare ID or CID and place details are off. |
reviewVideos | Links only, as Google serves them; they can expire. |
🧾 Reading the output
Four kinds of row can land in your dataset.
| Row | How to spot it | Charged |
|---|---|---|
| A review | charged: true and a reviewId | yes |
| A place record | recordType: "place", only with Add one place record per place | no |
| The sample row | _sample: true | no |
| A diagnostic | _diagnostic: true and an errorCode | no |
Filter on _sample and _diagnostic being absent, not on recordType alone. The free sample
row also carries recordType: "review". Read charged: true as "this is a real row", not as a receipt.
| Code | What it means |
|---|---|
NO_PLACE_FOUND | That business name matched nothing. Use its link or place ID instead. |
NO_REVIEWS | The place resolved but has no reviews, or none survived your filters. |
BAD_INPUT | A date window or star range the run could not read. Nothing was fetched. |
SHORTLINK_UNRESOLVED | A maps.app.goo.gl link would not expand. Open it once in a browser and paste the full URL. |
PLACE_ID_UNRESOLVED | The ID did not resolve to a place. |
SEARCH_ or REVIEWS_ plus a status, SEARCH_PARSE, REVIEWS_PARSE | A name lookup or a page of reviews came back unreadable. Re-run it. |
TIME_BUDGET | The run ran out of time. Everything already delivered is complete. The run still ends as succeeded, with an amber status message, even when the time limit stopped it before any review came back. |
PROXY_INPUT_ADJUSTED | A network setting in your input was not usable, so the run used its own. |
NETWORK | Google was unreachable or answered badly. Re-run it. |
UNEXPECTED_ERROR | The run stopped early on an unexpected error. The results before this row are kept. |
One bad target never stops the others, and a diagnostic row never fails the run.
💡 What people use it for
- Watching what changed in a place's reviews since last month, on a schedule, using
reviewsSince. - Auditing every branch of a chain on the same terms, with a per-place cap so one busy site does not eat the budget.
- Pulling every 1 and 2 star review with
maxStarsat 2 to find the complaint that keeps repeating. - Checking which reviews the owner replied to across a set of locations.
From a city search to a chain's complaints, in three steps:
- Run Google Maps Scraper on a search like
Starbucks in Seattle, WAand copy theplaceUrlcolumn. - Paste those links into
placeUrlshere withsortonnewest,reviewsSinceat30 daysandmaxReviewsPerPlaceat 50. - Keep the rows with a
ratingof 1 or 2 and group them byplaceNameto see which branch is slipping.
🚧 What it does not do
- Place details are off unless you switch them on, and there are no popular times.
- No like counts, visit dates or a time on the owner's reply. The reply comes with its relative wording only.
- Not the full history of every place. A run stops at 50,000 reviews or at its time limit.
- No reviews from other sites. Entries Google marks as coming from another site are left out.
- Sorting is Google's, applied before paging. Asking for 20 sorted
highestgives you the 20 highest Google serves first, not a true sort of the whole history. - Star-only ratings have no text, so
textisnullon those unless you switch on Skip star-only ratings. - A name matching several places resolves to Google's top match, and a name with no city in it can land on the wrong branch. For a specific place, use its link or place ID.
- The row budget splits evenly between your places. A place with fewer reviews than its share returns fewer rows, and the leftover is not handed to the others.
- Rows are a snapshot. A review can be edited or deleted later, and
scrapedAtrecords when it was read. - It is not an official Google tool. Dami's Studio is independent and is not affiliated with or endorsed by Google, or by any other company named on this page.
🧭 Which Google Maps scraper do you need?
| If you want | Use |
|---|---|
| Places from a search, with reviews optional | Google Maps Scraper |
| Reviews for a place you can link, name or search for, with exact dates | This one |
| The photos and videos on a place | Google Maps Place Photos Scraper |
| Only what changed in your own locations' reviews, on a schedule | Google Reviews Monitor |
| Businesses in Russia and the CIS, from Yandex Maps | Yandex Maps Scraper |
| Reviews of hotels, restaurants and attractions on Tripadvisor | Tripadvisor Reviews Scraper |
❓ Questions people ask
Do I need a Google API key to scrape Google reviews?
No. Nothing to apply for, no account and no quota to manage.
Why did I get fewer reviews than I asked for?
Either the place does not have that many, or the budget was split across several places, or your filters left them out. You are charged for what arrived.
Can I monitor a place over time?
Yes. Schedule it with reviewsSince at something like 7 days and sort on newest, and each run
reads only what is new. reviewId makes deduping across runs straightforward.
Can I call it from code or connect it to an AI assistant?
The API tab has code for Python, JavaScript
and the CLI. MCP clients like Claude and ChatGPT use
https://mcp.apify.com/?tools=fetch-actor-details,dami_studio/google-maps-reviews-scraper; coding assistants can load
our skill
file. All
three bill your Apify account at the same price.
# pip install apify-clientfrom apify_client import ApifyClientclient = ApifyClient("YOUR_APIFY_TOKEN")run = client.actor("dami_studio/google-maps-reviews-scraper").call(run_input={"placeUrls": ["https://www.google.com/maps/place/Starbucks+Reserve+Roastery/data=!4m2!3m1!1s0x54906acdccf44db1:0x6da0c1f2d7a6736e"],"maxReviews": 50,},max_total_charge_usd=0.10, # the most this run may spend)for row in client.dataset(run["defaultDatasetId"]).iterate_items():if row.get("ok") is False: # free note rows, not resultscontinueprint(row.get("rating"), (row.get("text") or "")[:80])
Is scraping Google reviews legal?
These are public reviews on public place pages. They contain personal data all the same, which GDPR and similar laws cover, so have a reason for collecting it. Apify's write-up on the legality of web scraping is a good starting point, and we are not lawyers.
🆘 If something breaks
Open the Issues tab on the actor page. Send the place link and the run ID. The errorCode on
the diagnostic row usually names the problem on its own.