Google Maps New Business & Competitor Openings Monitor
Pricing
from $10.00 / 1,000 listings
Google Maps New Business & Competitor Openings Monitor
Runs a Google Maps place search for an area and business category and emits only the listings that are new since the previous run, so you get an alert-style feed of new openings instead of a full re-download every time.
Pricing
from $10.00 / 1,000 listings
Rating
0.0
(0)
Developer
Mikkel Bech-Hansen
Maintained by CommunityActor stats
0
Bookmarked
1
Total users
0
Monthly active users
14 days ago
Last modified
Categories
Share
Runs a Google Maps search for an area and business category (e.g. "coffee shop in Austin, TX") and reports only the listings that are new since the last time you ran it. Instead of re-downloading every business in the area on every run, you get an alert-style feed of what just opened — useful for site-selection scouting, franchise expansion research, or watching a competitor's category for new entrants.
The first run for a query has nothing to compare against, so it reports every listing
found as a baseline (each record is flagged isFirstRunBaseline: true). From the second
run onward, only genuinely new listings are reported.
How it works
Google Maps' search results are loaded by the same public, no-login search surface that
maps.google.com itself uses — no API key, no Places API billing. This actor drives a
real browser (Playwright) to the search results feed, scrolls it to collect listings, and
for every listing that's new since the previous run, opens that listing's own Maps page to
also pull its phone number, website and review count. That second step only runs for
listings that turned out to be new, so a quiet run (nothing new opened) stays cheap.
Each business is tracked by the place ID Google Maps embeds in its own listing links
(the same ChIJ... identifier used across Google's products), stored in a named
key-value store between runs so scheduled runs keep comparing against the same history.
Input
| Field | Type | Default | Notes |
|---|---|---|---|
searchQueries | array of strings | ["coffee shop in Austin, TX"] | One entry per area+category. Write it exactly as you'd type it into the Google Maps search box. |
maxResultsPerQuery | integer | 60 | How many listings to scan per query (1–120). Google Maps rarely returns more than ~120 for one search. Does not limit how many new listings can be reported. |
enrichNewListings | boolean | true | Fetch phone/website/review count for each newly detected listing. Adds one page load per new listing, not per scanned listing. |
stateStoreName | string | google-maps-new-openings-monitor-state | Key-value store used to remember what was already seen. Leave at default so scheduled runs keep comparing against the same history; change only to run two independent monitors from the same account. |
proxyConfiguration | object | no proxy | Off by default so a first run is free to try. Google will start showing consent/CAPTCHA pages if you run many queries from the same IP in a short time — enable Apify Proxy (residential recommended) once you monitor more than a handful of queries. |
maxConcurrency | integer | 2 | Search queries processed in parallel. Kept low by default — each one drives a real browser page, and going higher raises the chance of a CAPTCHA. |
requestTimeoutSecs | integer | 90 | Timeout for a single Maps page load (search or place detail) before it's retried. |
maxRequestRetries | integer | 2 | Retries per page after a failed load. |
Output
One dataset record per newly detected listing:
{"placeId": "ChIJG-gJw2vKRIYROWi2uwOp8QE","name": "Epoch Coffee","category": "Coffee shop","address": "221 W N Loop Blvd, Austin, TX 78751, United States","phone": "+1 512-454-3762","website": "http://www.epochcoffee.com/","rating": 4.5,"reviewCount": 2511,"latitude": 30.3186037,"longitude": -97.7245402,"mapsUrl": "https://www.google.com/maps/place/Epoch+Coffee/...","searchQuery": "coffee shop in Austin, TX","isFirstRunBaseline": true,"detectedAt": "2026-08-17T23:31:41.159Z"}
phone, website and reviewCount are only populated when enrichNewListings is on;
otherwise they're null. address and rating come from the search results feed either
way. isFirstRunBaseline is true for every listing reported the first time a given
query is run (see above) and false for genuinely new openings detected afterward —
filter on this field if you only want real alerts.
Cost guidance
With the suggested pay-per-event pricing (see MONETIZATION.md): area-checked ($0.002)
fires once per search query per run regardless of results, new-listing-detected ($0.01)
fires once per newly found listing. A typical scheduled run of 5 tracked areas that turns
up 3 new listings costs about 5 × $0.002 + 3 × $0.01 ≈ $0.04. The first run on a fresh
query is more expensive since every listing counts as a "new" baseline record — scanning
60 listings for one query on day one costs about $0.002 + 60 × $0.01 = $0.60.
Known limitations
- This is not the official Places API. It reads the same public search results page
maps.google.comitself renders. It's free to run (no Places API billing) but is not as stable a contract as a paid API — see Legal below. - Google Maps compact search cards don't show review counts. Review count is only available by opening each listing's own page, which is why it's only fetched for newly detected listings, not for every scanned listing.
- Category and street address are parsed from the results feed's visible text, which
is a compact, sometimes inconsistent summary (e.g. street address only, no city/zip).
Turning on
enrichNewListingsgets you the full, structured address instead. - No login means no personalization, which is a plus for consistent results but means
ranking/order can shift slightly between runs even with no real change on the ground —
this can occasionally surface a listing as "new" that was just previously outside your
maxResultsPerQuerycutoff, not a genuine new opening. - Sponsored/ad listings are filtered out — they're existing businesses paying for placement, not new openings, so they'd otherwise create false "new listing" alerts.
- Consent walls and CAPTCHAs. Without a proxy, Google may start showing a consent interstitial or CAPTCHA after repeated automated requests from the same IP in a short window. If a query's search fails outright, the run logs it and continues with the other queries; if every query fails, the run fails rather than reporting a false empty success. Add a proxy (see Input) if this happens regularly.
- State lives in a key-value store, not the dataset. If you delete or rename the
stateStoreNamestore, the next run starts over and reports every listing as a new baseline again.
Legal
This Actor is an independent, third-party tool. It is not affiliated with, endorsed by, or sponsored by Google or Google Maps.
It retrieves data by automating Google Maps' public, no-login search interface rather than through Google's official, paid Places API. Google's Terms of Service restrict automated access to Google Maps outside of that API, regardless of whether the underlying data (business names, addresses, ratings) is publicly visible. Using this Actor may not comply with those terms. You are responsible for reviewing Google's Terms of Service and applicable law before using this Actor, and for how you use the data it returns — including any restrictions on using Maps data to build a competing mapping/business-directory product, which Google's terms specifically prohibit.


