Google Maps Reviews Scraper avatar

Google Maps Reviews Scraper

Pricing

from $0.26 / 1,000 reviews

Go to Apify Store
Google Maps Reviews Scraper

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

Dami's Studio

Maintained by Community

Actor stats

0

Bookmarked

47

Total users

12

Monthly active users

a day ago

Last modified

Features

Limited permissions

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.

InputMaps links, short links, place IDs, CIDs, business names or search phrases, up to 50 per run
OutputOne row per review: stars, text, exact date, reviewer, owner reply, photos, ratings for food, service or rooms. Place details if you switch them on
Ceiling50,000 reviews per run
Account neededNone, 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?
Actordami_studio/google-maps-reviews-scraper
Set one fieldplaceUrls, labelled "Place links or IDs" in the Console
Cap the billmaxTotalChargeUsd on the run, for example 0.10: it never charges past that
MCP, one linkhttps://mcp.apify.com/?tools=fetch-actor-details,dami_studio/google-maps-reviews-scraper
How oftenWeekly, 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 getField
The place, as you named it and as Google knows ittarget, placeName, placeUrl, placeId, cid, featureId
A stable id for the review, and its linkreviewId, reviewUrl
Stars and the text as writtenrating, text, language, languageName
Google's translation, when the review is in another languagetextTranslated, 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 tipsvisitDetails
The exact time it went up, and Google's relative wordingpublishedAt, relativeDate
Whether it was edited, and whenisEdited, editedAt
Who wrote it and how active they are on MapsreviewerName, reviewerUrl, reviewerId, reviewerReviewsCount, reviewerPhotosCount, isLocalGuide
The owner's reply, roughly when, and Google's translation of itownerReply, ownerReplyRelativeDate, ownerReplyTranslated
Every photo link, and videos as a still plus a video linkreviewPhotosCount, reviewPhotoUrls, reviewVideos
Where the entry comes from, and the place's position in a searchreviewOrigin, searchRank
Place details, when switched onplaceRating, 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 recordopeningHours, amenities, highlights, timeZone
When the row was readscrapedAt

▶️ How to scrape Google Maps reviews

  1. Open Google Maps Reviews Scraper and click Try for free.
  2. Paste one or more links into Place links or IDs, or type names or a phrase into Business names to look up.
  3. Set Maximum reviews. Start around 20 to see the output shape.
  4. Pick a Review order and a Language if the defaults do not suit you, then click Start.
  5. 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"
}
FieldDefaultWhat it is
placeUrlsnoneMaps links, short links, place IDs or numeric CIDs. Up to 50. Paste the link exactly as the address bar gives it.
searchTermsnoneBusiness names or phrases, if you do not have links. Up to 50.
maxPlacesPerSearch1Places taken from each name or phrase, in Google's order, up to 20. 1 keeps the top match.
maxReviews20Total across every place in the run, split evenly between them. Up to 50,000.
maxReviewsPerPlacenoneCap 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.
sortnewestnewest, relevant, highest or lowest.
reviewsSincenoneOnly reviews after this point.
reviewsBeforenoneAdd-on. Only reviews before this point.
minStars, maxStarsnoneAdd-on. Only reviews with that many stars, 1 to 5.
keywordsnoneAdd-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.
onlyWithTextoffSkip star-only ratings with no words.
includeReviewerDetailsonOff leaves out the reviewer's name, link, photo and id.
includePlaceDetailsoffPlace columns on every review row.
includePlaceRecordoffOne free place row per place, with hours and amenities.
languageenWhich language Google should translate into.
countryusWhich country's Google to ask.
proxyUrlsnoneOptional. 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

Real run output

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
}
FieldHow to read it
publishedAtA real timestamp. On an edited review it is the time of the edit, and isEdited is true.
reviewIdStable. Use it as your dedupe key across runs.
text, textTranslated, originalTexttext 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, visitDetailsOnly what the reviewer filled in, labelled in the language you asked for. null when they skipped it.
isEditedRead from Google's wording in English, German, French, Spanish, Portuguese, Italian and Dutch; null in other languages.
isLocalGuideThe badge as true or false. Google's numeric level is not published here.
placeNamenull when you gave a bare ID or CID and place details are off.
reviewVideosLinks only, as Google serves them; they can expire.

🧾 Reading the output

Four kinds of row can land in your dataset.

RowHow to spot itCharged
A reviewcharged: true and a reviewIdyes
A place recordrecordType: "place", only with Add one place record per placeno
The sample row_sample: trueno
A diagnostic_diagnostic: true and an errorCodeno

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.

CodeWhat it means
NO_PLACE_FOUNDThat business name matched nothing. Use its link or place ID instead.
NO_REVIEWSThe place resolved but has no reviews, or none survived your filters.
BAD_INPUTA date window or star range the run could not read. Nothing was fetched.
SHORTLINK_UNRESOLVEDA maps.app.goo.gl link would not expand. Open it once in a browser and paste the full URL.
PLACE_ID_UNRESOLVEDThe ID did not resolve to a place.
SEARCH_ or REVIEWS_ plus a status, SEARCH_PARSE, REVIEWS_PARSEA name lookup or a page of reviews came back unreadable. Re-run it.
TIME_BUDGETThe 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_ADJUSTEDA network setting in your input was not usable, so the run used its own.
NETWORKGoogle was unreachable or answered badly. Re-run it.
UNEXPECTED_ERRORThe 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 maxStars at 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:

  1. Run Google Maps Scraper on a search like Starbucks in Seattle, WA and copy the placeUrl column.
  2. Paste those links into placeUrls here with sort on newest, reviewsSince at 30 days and maxReviewsPerPlace at 50.
  3. Keep the rows with a rating of 1 or 2 and group them by placeName to 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 highest gives you the 20 highest Google serves first, not a true sort of the whole history.
  • Star-only ratings have no text, so text is null on 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 scrapedAt records 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 wantUse
Places from a search, with reviews optionalGoogle Maps Scraper
Reviews for a place you can link, name or search for, with exact datesThis one
The photos and videos on a placeGoogle Maps Place Photos Scraper
Only what changed in your own locations' reviews, on a scheduleGoogle Reviews Monitor
Businesses in Russia and the CIS, from Yandex MapsYandex Maps Scraper
Reviews of hotels, restaurants and attractions on TripadvisorTripadvisor 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-client
from apify_client import ApifyClient
client = 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 results
continue
print(row.get("rating"), (row.get("text") or "")[:80])

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.