Google Maps Rank Tracker — Local SEO Positions & Reviews
Pricing
from $4.00 / 1,000 tracked results
Google Maps Rank Tracker — Local SEO Positions & Reviews
Track where your business ranks on Google Maps for every keyword and city, daily, with rank changes and review growth - not just a list of places. Give keywords, locations and the businesses to watch; get position, change since the last run and review count. $5 per 1,000 results. No login.
Give it keywords, locations and the businesses to track (a name, a website, a Google Maps link or a place ID) and get, for every keyword in every area, the position at which each business appears on Google Maps, the places directly above it, who holds the top spots (by name, with their moves since the last run), and its rating and review count. $5 per 1,000 tracked results, no login, no API key, no browser.
Run it every day on a schedule and each row also says what changed since the last run: how many positions the business moved (positive = moved up), how many reviews it gained, whether its rating changed, and how many reviews the top ten places gained over the same time — so you see whether your reviews grow faster than the places around you. Google Maps only shows you today's list; this keeps the history for you. It does not output the list of places it reads - only the position and review numbers of the businesses you watch, and the names and positions of the top few places (no addresses, phones, hours or reviews of other businesses).
What you get
One row per keyword × location × tracked business (type: "watch-summary"):
| Field | What it is |
|---|---|
search, keyword, location | the search that was run ("dentist in Austin, TX") and its two parts (empty keyword and location for a free-text search) |
watched | the business as you gave it |
found | true if it is among the places read for this search |
rank | its best position in Google's list for that search (1 = first); empty when not found |
previousRank, rankChange, trend | position in your last run, positions moved (positive = moved up), and up, down, same, entered (was not in the last list), dropped-out (was in it, is not now), not-found or no-history (first run, or the last run read too few places to say) |
matchedBy, matchedPlaces | how it was matched (placeId, website or name) and how many places matched; above 1 means a chain or a shared website, and rank is the best of them |
placeId, name, address | Google's place ID, the listing's name and address, so you can check it is the right business |
rating, ratingChange | Google rating and its change since the last run |
reviewCount, reviewCountChange | number of reviews and the reviews gained since the last run |
competitorsAbove | up to 5 businesses ranked directly above it, top first (empty list at position 1; people-named listings and closed places are left out) |
topResults | the top places for the search, 5 by default (Top places to show, up to 20): rank, name, previousRank, rankChange (positive = moved up), newInTop (true = was not in the top last run) and watched (true = one of yours). Shown also when your business is not found. People-named listings and closed places are skipped, so ranks can jump (1, 3, 4 …) |
leftTopResults | places that were in the top last run and are not now: name, previousRank and rank today (empty when it is below the places read). Empty on the first run |
topTenAverageRating, topTenAverageReviewCountChange | the average rating of the top ten places other than yours, and the average review growth of those that were in the last list too — your growth against the places around you |
placesRead | how many places were read for the search |
note | why a business was not found, or that several places matched |
observedAt | when it was read |
The change fields are empty on the first run. A real row (read 2026-10-09, the fourth of four runs a few minutes apart, tracking a website; topResults cut to two of the five here):
{ "type": "watch-summary", "search": "emergency dentist in Austin, TX", "keyword": "emergency dentist", "location": "Austin, TX","watched": "treatyoakdental.com", "found": true, "rank": 38, "previousRank": 35, "rankChange": -3, "trend": "down","matchedBy": "website", "matchedPlaces": 1, "placeId": "ChIJRRBY-XS1RIYRIsb3UXu9kfw", "name": "Treaty Oak Dental","address": "2905 San Gabriel St #202, Austin, TX 78705", "rating": 4.8, "ratingChange": 0, "reviewCount": 171, "reviewCountChange": 0,"competitorsAbove": ["River Park Cosmetic & Implant Dentistry", "Lucent Dentistry", "myDental at Norwood Park", "Belterra Dental", "Daybreak Dental"],"topResults": [{ "rank": 1, "name": "Emergency Dentist of Austin", "previousRank": 1, "rankChange": 0, "newInTop": false, "watched": false },{ "rank": 2, "name": "Austin Emergency Dental", "previousRank": 2, "rankChange": 0, "newInTop": false, "watched": false } ],"leftTopResults": [],"topTenAverageRating": 4.76, "topTenAverageReviewCountChange": 0, "placesRead": 40, "note": null }
In the run before it, Urgent Dental Response had come into the top five from position 7 ("previousRank": 7, "rankChange": 2, "newInTop": true), and positions 3 and 4 had swapped places (rankChange 1 and -1).
Per search there is also one free row (type: "summary"): placesRead, averageRating, newSinceLastRun, leftSinceLastRun, watchedFound, reachedEnd (true when Google ran out of places before your limit), reviewCountsMissing, and a note when a search returned nothing. If a run is stopped before its time limit, one free notice row lists the searches that were not read.
Run it again and again
- On a schedule — save your input as a task and add a Schedule: the same keywords and areas every day. Send each run to Google Sheets, Slack or email with an integration on the task.
- Watch for changes — Nothing to switch on: from the second run each row says how many positions the business moved, how many reviews it gained and how the top places changed since the last run.
- In bulk — Put every keyword in Keywords, every area in Locations and every business in Businesses to track: one run checks all the combinations.
Use it for
- Local businesses — where do I show up for "dentist" in my town and the next town over, and did last week's review push move me?
- SEO and marketing agencies — one daily run for all clients: each client's name or website as a tracked business, every service keyword, every service area
- Multi-location businesses — track each location by its Google Maps link or place ID and compare areas
- Competitor watch — track the businesses that rank above you and see their review growth next to yours
Input
{"keywords": ["dentist", "emergency dentist"],"locations": ["Austin, TX", "Round Rock, TX"],"watch": ["treatyoakdental.com", "Austin Lifetime Dental", "ChIJ9eZOciDMRIYRSVHxKyz66So"],"maxPlacesPerSearch": 60}
- Keywords × Locations — every keyword is searched in every location as
keyword in location: the example above is 4 searches. You can also give free-text searches ("dentist in Manchester, UK") next to or instead of them. Up to 100 searches per run. - Businesses to track — required, up to 25 per run, each matched against every result. A website (
example.com; a subdomain matches too, andexample.com/austinonly matches pages under that path) is the sturdiest for a business with one site. A place ID (ChIJ…or0x…:0x…) or a Google Maps place link follows exactly one location. A name is compared ignoring case, accents and punctuation;Treaty Oak Dentalalso matchesTreaty Oak Dental – Downtown(a branch after a dash, comma or bracket) andmatchedPlacesshows when that gives several. Shortmaps.app.goo.gllinks cannot be followed; open one and copy the full address. - How deep to look — 1 to 200, default 60. A business below this position is
found: false. - Top places to show — 0 to 20, default 5. How many of the top places to name in
topResults; 0 turns it off. - Language — a language code (
en,de,ja,pt-BR…).
History is kept per search text and per language in a named key-value store in your Apify account, so the second run already shows changes. Schedule it (Apify → Schedules) for a daily log. Keep the wording of a search the same from run to run; a new wording is a new search with no history. A business you add later gets its previous position from the last list of places if it was in it.
Pricing
$5 per 1,000 tracked results (one per keyword × location × business), plus $0.01 per run. The summary row, error rows and a search that returned no list are free; nothing is charged for a tracked business of a search that could not be read. Reading deeper costs nothing extra. Example: 2 keywords × 2 cities × 3 businesses is 12 results = $0.06 + $0.01 per daily run.
Notes
- The location is the one in the search. Google ranks local results by the place named in the query, and this Actor sends no location of its own. Checked on 2026-10-09 from a PC in Japan (not from Apify's servers, so a US server address was not compared):
keywords: ["dentist"]withlocations: ["Austin, TX"]sends exactly the textdentist in Austin, TX, the same request as typing that search, andplumber in Aurora, COreturned the same 40 places in the same order whether the Google session was opened with that search, with a search in Tokyo or with no cookie at all. - Ranks are for a US visitor. The Actor asks Google as a visitor from the US. Asking
plumber in Denver, COas a visitor from the UK, Japan, Germany or Australia on 2026-10-09 gave 9, 8, 8 and 9 of the same top ten places as the US request, but in the same position for only 4, 2, 4 and 2 of them (top 40: 34 of the same places each, 2 to 5 in the same position; a second US request was identical). What a searcher sees at home can differ from your rank here; there is no country setting. - Wording matters.
plumber Denver COreturned 38 of the 40 places ofplumber in Denver, CO, only 9 of them in the same position. Pick one wording per keyword and keep it. - Give a place. A search without one (
plumber) returned places from wherever Google guessed: on 2026-10-09 the top 20 were spread over California, Oregon, Washington, Utah, Oklahoma and Maryland.keywordstherefore always needlocations. - The order wobbles, by keyword. Google does not always answer the same request with the same list. On 2026-10-09, four reads each of
dentist in Austin, TXandplumber in Denver, COgave the same 60 places, 58 to 60 of them in the same position.water heater repair in Aurora, COwas stable over 10 identical requests in a row in one series, but in a second series 3 of the 10 answers came back in a different order, and two Actor runs a few minutes apart shared only 20 of its 60 places.emergency dentist in Austin, TXwas the least stable: 6 to 9 of the same top 10 but only 2 in the same position, and 41 to 57 of the same top 60 with 2 or 3 in the same position. A move of one or two positions, or a single day on a volatile keyword, is noise: judge the trend over a week. - How deep a search goes is Google's call, and it differs by search. On 2026-10-09 Google ended the list by itself at 152 to 192 places for coffee in Austin, dentists in Manchester, ramen in Osaka, pharmacies in Berlin and plumbers in Toronto (
reachedEnd: true); hotels in Lisbon went on past 200. This Actor reads at most 200 per search. - Speed. Four searches of 60 places (240 places, 16 tracked results) took 29 and 33 seconds in two runs on 2026-10-09, about 8 seconds a search. Six searches of up to 200 places (1,048 places) took 143 seconds. If a run is about to hit its time limit, the Actor stops 90 seconds before it, keeps what it has, and lists the searches it did not read in a free
noticerow; run those again or raise the run timeout. - Language changes more than labels. It sets the language of categories, weekday names and hours, and it also shifts which places rank where: for
plumber in Denver, COon 2026-10-09, German, Japanese and Spanish each gave 19 of the same top 20 places as English, but only 8, 6 and 6 in the same position (two English reads were identical). Keep the language the same from run to run. - Not found.
found: falsemeans the business is not among the places read, not that it is not on Google Maps. Raise How deep to look (reading deeper costs nothing extra). If a search stops halfway because Google stops answering, a business that was not found so far gets no row at all (an error row says what happened); one that was found still does. - Chains and shared websites. A website or name that matches several places gives one row with the best position and
matchedPlacesabove 1. If the best location is a different place than in the last run,rankChangestill compares the best positions butratingChangeandreviewCountChangestay empty (they would mix two places). Use a place ID or a Google Maps place link to follow one location. - Needs a list, not one place. A search for one named place (
Eiffel Tower Paris) returned no list of places on 2026-10-09; the summary row says so innoteand no tracking rows are output. Use a category plus an area. - Review counts. Google sometimes leaves the review count out of an answer. The Actor asks again up to three times;
reviewCountsMissingin the summary row says how many stayed empty (0 in all six searches above). - Public listing data only. Only the numbers and names of the businesses you watch, the names in
competitorsAboveand the names and positions intopResultsandleftTopResultsare output. No reviewer names, review texts, owner names or photos are read. A listing that is clearly one person — a name with a title or credential (Dr. Jane Doe, DDS,Dr. med. dent. Jane Doe,Rechtsanwalt Mag. Jane Doe,Docteur Jane Doe) or with an occupation (Jane Doe - Realtor) — is left out ofcompetitorsAboveandtopResults. An address line that is an owner's name with a legal form (Jane Doe e.Kfr,Inh. Jane Doe,c/o …, seen on pharmacies in Berlin) is removed fromaddress. These are rules of thumb, not guarantees. - If Google refuses. Google can answer HTTP 429 or show a consent or "unusual traffic" page. The Actor waits and asks again, never tries to get around such a page, and reports the search in a free error row. The run fails only if nothing at all could be read. The figures above were measured over plain requests from one ordinary internet connection, and shared server addresses can be limited sooner. Not affiliated with Google.
To track where pages rank on Bing, see Bing Search Rank Tracker. For the same kind of ranking on video, see YouTube Search Rank Tracker. For places from OpenStreetMap, see OpenStreetMap Places Scraper.
For AI agents
{"keywords": ["dentist"], "locations": ["Austin, TX"], "watch": ["treatyoakdental.com"]} returns one watch-summary row per keyword, location and watched business (rank, rankChange, trend, reviewCount, reviewCountChange, competitorsAbove, topResults with the top 5 names and their moves, leftTopResults) plus one free summary row per search. It does not return the places it reads beyond those names and positions. watch is required. Row type is watch-summary, summary, notice or error. Run it on a schedule: change fields are empty on the first run. Always give locations; keep the search wording the same between runs.