Google Maps Scraper - Businesses and Leads avatar

Google Maps Scraper - Businesses and Leads

Pricing

from $0.80 / 1,000 places

Go to Apify Store
Google Maps Scraper - Businesses and Leads

Google Maps Scraper - Businesses and Leads

Find public Google Maps businesses by keyword and area. Phone, website, hours, categories, ratings and star distribution included at one flat price. Adaptive map splitting expands coverage. Export JSON or CSV, then enrich websites into verified leads.

Pricing

from $0.80 / 1,000 places

Rating

0.0

(0)

Developer

Sumitr Mardy

Sumitr Mardy

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

3 hours ago

Last modified

Categories

Share

Google Maps Scraper — Businesses and Leads

Find public business listings by keyword and location. Phone numbers, websites, opening hours, categories, ratings and star distribution are included at one flat price. Export JSON, CSV or Excel. No Google API key, login, cookies or browser required.

Quick start

{"searchQueries":["coffee"],"locations":["Lisbon, Portugal"],"maxPlaces":10}

Queries run in every location. With no locations, write the location inside the query:

{"searchQueries":["dentist in Austin TX"],"maxPlaces":50,"requireWebsite":true,"requirePhone":true}

Input

FieldDefaultMeaning
searchQueries[]Business keywords, not URLs.
locations[]Place names geocoded through public Maps. Empty means use the query as written.
maxPlaces100Returned unique places per query/location, 1–5,000. Prefill is 10.
splitAreatrueSplit busy viewports into four smaller areas, down to a 500 m viewport.
languageenMaps UI language (hl).
countryusTwo-letter country code (gl).
minRating0Local minimum-rating filter. Missing rating counts as 0.
requireWebsitefalseReturn only listings with a website.
requirePhonefalseReturn only listings with a phone.

At most 100 query/location combinations. Duplicate combinations are merged. Deduplication by placeId applies across all pages/tiles for each combination. The same place may appear under different queries or locations. Filtering happens before saving and charging; filtered-out listings are free.

Coverage and automatic map splitting

A single Maps search often stops near 140–180 places. The Actor paginates each viewport; a short page before offset 120 marks it complete. A capped area is split into four quadrants. This continues until the result limit, 500 m minimum viewport, inventory exhaustion, spending limit or free-work guard.

Measured from Apify on 2026-10-30: the Maps-returned viewport for Manhattan produced 174 unique restaurants from one wide search; adaptive splitting reached 1,000 unique restaurants across 7 viewports, then stopped at the requested limit with 18 areas still pending. This is a measured coverage improvement, not an exhaustive census.

The location sets a Maps viewport/bias, not an administrative polygon. Nearby districts or cities may appear. A Maps geocoded viewport can be much wider than the named area; we do not claim exact city-boundary filtering. Smaller viewports and Maps ranking can still hide places. maxPlaces is a ceiling, not a guarantee.

Output

One row per unique successful place per query/location. All 26 keys are always present, never null. Missing strings are "", counts 0, categories [], openingHours {}, and starDistribution always has keys "1" through "5".

FieldMeaning
inputIndex, query, locationOriginal combination index and search context.
placeId, cid, mapsUrlPublic place ID, decimal CID converted from its feature ID, and Maps link.
name, category, categoriesPublic business name, primary category and category array.
address, cityDisplayed address and available locality label; not verified administrative membership.
phone, phoneE164, websiteListed display phone, E.164 phone and website. Empty if absent.
rating, reviewsCountDisplayed average rating and number of reviews.
starDistributionObject with counts for 1-, 2-, 3-, 4- and 5-star ratings; absent values 0.
latitude, longitudePublic listing coordinates; 0 if absent.
openingHours, timezoneDisplayed weekday/hour text and available timezone. Hours can reflect special/holiday dates.
positionOne-based returned position within this combination.
status, subStatus, error, scrapedAtStable result, machine-readable reason, explanation and ISO timestamp.
statussubStatusPlace charge
okplaceYes
no_resultsno_resultsNo
failedinvalid_input, location_not_found, http_CODE, blocked, parse_error, network_error, free_work_limit, cost_limit_reachedNo

A partially completed search can return successful places plus a final free error or limit row. A free failure does not remove charges for places already saved.

Measured field availability

Direct Apify spike, 2026-10-30. Availability varies by business and changes over time; fields are not fabricated.

SamplePlacesPhoneWebsiteRatingHours
Lisbon coffee viewport160108 (67.5%)106 (66.3%)153 (95.6%)147 (91.9%)
Manhattan restaurant viewport with splitting1,000985 (98.5%)878 (87.8%)988 (98.8%)970 (97.0%)
dentist in Austin TX6060 (100%)60 (100%)60 (100%)60 (100%)

Phone and website are included only when the business lists them. Use requirePhone/requireWebsite to filter, with no extra fee.

Pricing

Apify tierPer placePer 1,000 places
FREE$0.002$2.00
BRONZE$0.0015$1.50
SILVER$0.0012$1.20
GOLD+$0.0008$0.80

Everything listed above is included. No phone, website, details or filter surcharge. Default Actor start fee: $0.00005 per start event (per GB, minimum one). Failed, empty and locally filtered places have no place charge; start still applies. Dataset-item billing is disabled. The Actor pays platform usage under PPE. User spending limits may stop runs early.

Lead pipeline: Maps → contacts → email verification

  1. Collect business listings here and take non-empty website values.
  2. Pass those URLs as domains to Website Contact Finder, which returns its emails array alongside contacts and source information.
  3. Pass collected email strings as emails to Email Verifier.

Contact Finder input example (its field name was checked):

{"domains":["https://example-business.com"],"maxPagesPerDomain":5}

Email Verifier input:

{"emails":["contact@example-business.com"]}

Each Actor has its own pricing and spending limit. This Actor does not automatically run or charge the other two. Keep verification status and catch-all/unknown results when assessing contacts.

API examples

curl -X POST "https://api.apify.com/v2/acts/sumitr_mardy~google-maps-scraper/run-sync-get-dataset-items?format=json" \
-H "Authorization: Bearer $APIFY_TOKEN" -H "Content-Type: application/json" \
-d '{"searchQueries":["coffee"],"locations":["Lisbon, Portugal"],"maxPlaces":10}'
import os
from apify_client import ApifyClient
client = ApifyClient(os.environ["APIFY_TOKEN"])
run = client.actor("sumitr_mardy/google-maps-scraper").call(
run_input={"searchQueries":["dentist"], "locations":["Austin, TX"],
"maxPlaces":50, "requireWebsite":True, "requirePhone":True}
)
places = list(client.dataset(run["defaultDatasetId"]).iterate_items())
websites = sorted({row["website"] for row in places
if row["status"] == "ok" and row["website"]})
# Optional next step; this runs a separately priced Actor:
# contacts_run = client.actor("sumitr_mardy/website-contact-finder").call(
# run_input={"domains": websites}
# )

Use asynchronous runs for larger exports; download the dataset after completion.

Use it from AI agents (MCP)

Hosted OAuth:

{"mcpServers":{"maps":{"url":"https://mcp.apify.com/?tools=sumitr_mardy/google-maps-scraper"}}}

Hosted Bearer alternative:

{"mcpServers":{"maps":{"url":"https://mcp.apify.com/?tools=sumitr_mardy/google-maps-scraper","headers":{"Authorization":"Bearer YOUR_APIFY_TOKEN"}}}}

Stdio:

{"mcpServers":{"maps":{"command":"npx","args":["-y","@apify/actors-mcp-server","--tools","sumitr_mardy/google-maps-scraper"],"env":{"APIFY_TOKEN":"YOUR_APIFY_TOKEN"}}}}

Set an explicit maxPlaces, specify the area, and inspect status/subStatus. Ask for phone/website filters only when needed. Do not treat a missing field or 0 coordinate as verified data.

Scope and limits

Not affiliated with Google. Public listing JSON only; no place detail page, review texts, photos, login or private data. Results reflect Google Maps for the requested language/country. Field positions can change; missing fields stay empty. Opening hours and star distributions may be unavailable or stale.

At most two query/location workers; pages sequential, with a 300 ms pause after each request before that worker's next request. Hard network deadlines and a free-work loss guard bound slow or unproductive work. The default prefill makes two requests: geocode plus one results page.

A CAPTCHA, /sorry/ or consent challenge stops that request and future requests in the run. No captcha solving, cookie/session reuse, residential proxy or IP rotation around a challenge. Non-challenge HTTP failures may be retried once directly, then once through Apify's default datacenter proxy. A guard or spending limit can end coverage before all tiles are visited.