Search Google Maps for local business leads by keyword and location. One row per place: name, category, address, phone numbers, website, ratings, opening hours, place ID. Optional website contacts: emails, social media, WhatsApp. Filter leads free: no website, low rated, unclaimed, new businesses.
Stop queued searches, grid expansion and further pagination when the spending limit or total place cap is reached. A budget below one deliverable place causes no Google or website requests.
Limit website enrichment to affordable contact events after reserving base place fees. Email-only mode reserves both prices before fetching candidates.
Serialize enrichment and billing across searches. A charge failure stops further work and fails the run instead of treating unpaid results as paid; already-paid base places remain available if their contact charge fails.
Record billing failures in SUMMARY. Preserve event IDs and prices; pin the cloud-tested Apify SDK to 3.4.1.
2026-10-16 — Keyword Planner and locale documentation
Validated search terminology against Google Ads Keyword Planner and Store shelves. Added localized usage guidance and bounded examples; retained existing English phrases. Clarified locale limitations where measured. No runtime, output fields, defaults, or pricing changed.
price change, set 2026-10-12, effective 2026-10-27
place $0.003 → $0.004 per row (rivals charge $0.003–0.008 per place plus enrichment; contact-found $0.002 → $0.003 (rivals $0.002–0.005)). the actor has paying users, so Apify applies the increase on 2026-10-27 and notified them; until then the old price bills and the listing text below describes the price from that date; nothing else changes — same rows, same free rows, same filters, no start fee, proxy and compute included. Every price mention in the input form, the event text and this README was updated with it.
1.2 — unknown locations refused again, 2026-10-11
Fixed: a location Google Maps does not know could be billed as another town's places. Since the 2026-09-21 build Google has answered the bare lookup of a nonsense string through US proxies not only with the empty map but, 6 lookups in 8, with one business near the asking IP whose name merely resembles the string ("Zzqqxwv Nowhereville" became the bar "Nowhere" on 14th Street, Manhattan; "Xyzzyplugh" four contractors; "Bali" fifteen vacation rentals in Jersey City), and the actor took that business for the town and billed 20 Manhattan plumbers with status: ok (cloud run QhzRcWWqr7HLes40R, 2026-10-11). A location now has to be a geocode — Google's own record type, read off the answer: a town, district, postcode, region, street or country, which Google never gives business categories — or a landmark typed by its name ("Times Square", "Heathrow", "東京タワー"); a business or a list of businesses, however near, ends the search as unknown_location with no charge, as the README has promised all along. Measured on 58 lookups in 9 countries and 5 languages: every town, ZIP, neighbourhood, state and country still resolves; what no longer resolves is a bare ambiguous name the old code silently centred on an arbitrary business ("Springfield" on an armory in Massachusetts, "Silicon Valley" on an office in Bethlehem, PA) and an alias spelled differently from the place's name ("LAX") — add the state or country, or type the name Google shows. No row field, price or event changed.
1.1 — listing text re-checked, 2026-10-11
No behaviour, output or price changed; the same inputs return the same rows.
Title, description and input order kept: every phrase that ranks today ("google maps leads" #9, "google maps low rated" #3, "unclaimed businesses" #1, "google maps whatsapp" #7) stays where it is.
seoDescription (indexed by Store search) now carries the synonyms agents type and the native nouns: Google Maps lead generation, local business leads, Google Business Profile listings, negocios, empresas, entreprises.
Place event text names the maxTotalChargeUsd stop; the contact event names onlyWithEmail as the other switch that turns enrichment on.
README agent section re-verified against the code (inputs, row fields, status values) and points review requests to kestrel/google-maps-reviews-scraper.
1.1 — 2026-09-21
Fixed: is_claimed was true for every place, so the unclaimed lead flag never appeared. It is now read from Google's own "Claim this business" link (in tests on Shibuya restaurants, 4–14% of listings are unclaimed).
New free filter isClaimed (any / yes / no): keep only unclaimed listings — the ones Google still offers to "Claim this business" — or only claimed ones. Filtered places are not charged.
Listing rewritten for AI agents and MCP clients: the inputs an agent needs first (contacts, email-only, website, rating, review and claimed filters, monitoring) now lead the input schema, every input says what to pass and what it costs, and the README opens with a request-to-input table.
1.0 — 2026-09-21
First release.
Google Maps places as one flat row each: ids and link, name and categories, address in parts, coordinates and plus code, phone in local and international format, website and domain, rating, review count and the per-star histogram, claimed and closed status, opening hours, description, attributes, booking link, cover photo and photo count, timezone.
Searches × locations, full phrases, circles, bounding boxes and polygons, pasted search URLs, place URLs, short links, place ids, feature ids and CIDs. Input saved for other Google Maps actors pastes unchanged (searchStringsArray, locationQuery, maxCrawledPlacesPerSearch, countryCode).
Free filters applied before billing: rating, review count, has website, has phone, categories, name, closed, inside the area, skip-lists by id or by dataset, only places with an email. The status row counts what each filter removed.
Contact enrichment from the place's own website (home page plus contact, about, team and imprint pages): emails with their source page, phone numbers, Facebook, Instagram, LinkedIn, X, YouTube, TikTok, WhatsApp. contact-found is charged only when something was found. Measured on 200 places: a contact for 51%, an email for 34%.
Full coverage: the area is split into a grid to go past the 120–220 places a single query lists; every place is delivered and billed once.
Only-new monitoring with a monitor key: later runs deliver and bill only places not delivered before.
A location Google Maps does not know ends as a successful, free run with an explanation instead of another town's places; a small town that answers empty is searched again around its looked-up centre.
Answers that arrive with review counts stripped (about half of them) are asked again, so review_count is filled on every row.
Charged equals delivered: rows are charged first and only the charged rows are written; the spending limit and an abort both stop billing and delivery at the same moment.