Google Maps Business Scraper — Phones & Hours avatar

Google Maps Business Scraper — Phones & Hours

Pricing

from $0.43 / 1,000 business delivereds

Go to Apify Store
Google Maps Business Scraper — Phones & Hours

Google Maps Business Scraper — Phones & Hours

Search Google Maps for local businesses by term and location. Export names, phones, websites, addresses, ratings, review counts, and weekly hours. No Google API key. $0.50 per 1,000 delivered businesses.

Pricing

from $0.43 / 1,000 business delivereds

Rating

0.0

(0)

Developer

Meka.im

Meka.im

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

3 days ago

Last modified

Share

Search Google Maps by keyword and location to build a structured list of local businesses. Export names, phones, websites, addresses, ratings, review counts, and opening hours for $0.50 per 1,000 delivered businesses. No Google API key is required.

Tool preview: Explore Google Maps Lead Finder for recorded examples and the current preview status. Browse the tools directory for other sources.

  • Contact, address, hours, accessibility, ranking and location in the base price
  • Core business fields aligned with the leading Google Maps Actor
  • No charge for duplicates, failures, or empty searches
  • No Google API key required

Quick start: scrape Google Maps business data

  1. Put your search terms in the Search terms field, one per line.
  2. Click Start.
  3. Export the Dataset, or read it with the API calls below.
{
"searchStringsArray": ["dentist in Austin TX", "florist in Boston"],
"maxCrawledPlacesPerSearch": 20,
"language": "en"
}

Google Maps scraper input

FieldTypeDefaultNotes
searchStringsArrayarray of stringsrequiredOne search term per line. Terms that name a place work best. Searched separately, results keep your order
locationQuerystringA single place to search in. Combined with each term
city / county / state / postalCodestringOptional, added to the location
countryCodestringFilters by confirmable country: only businesses whose address country or time zone confirms this country are returned and charged; unconfirmable ones are left out. Detection relies on Google's data and may be imperfect
languagestringenLanguage of names, categories and hours
maxCrawledPlacesPerSearchinteger201 to 60. See Limits
customGeolocationobjectGeoJSON geometry; its centre becomes the map centre
categoryFilterWordsarrayKeep only these categories
searchMatchingstringallonly_includes or only_exact to match on the name
placeMinimumStarsstringDrop businesses below this rating
websitestringallPlaceswithWebsite or withoutWebsite

Duplicate search terms are searched once. A business that appears under two terms is written once.

All four filters run on each page after it is fetched and do not change the upstream query. Anything they remove is not charged. If a page leaves fewer rows than you asked for, the Actor fetches the next page, up to three pages and 60 businesses per search term.

Inputs from the reference Actor

This Actor also accepts the other inputs of the leading Google Maps Actor so an existing input file runs unchanged, even though they are not shown in the editor:

  • Accepted, no effect: review, image, contact, lead, social-profile and competitor-analysis options, scrapePlaceDetailPage, skipClosedPlaces and the other add-on switches. Setting any of them to a non-default value is reported in the run log and in the run summary, so it is never silent.
  • Rejected: startUrls, placeIds and allPlacesNoSearchAction. These change the input mode entirely, and quietly ignoring them would return results you did not ask for. A run that sets one stops with an explanation instead.

Google Maps business data output

One row per business, in the order of your search terms.

FieldTypeNotes
fidstringGoogle's feature ID. The stable key for joining and de-duplication
placeIdstringGoogle Place ID, ChIJ…
cidstringDecimal customer ID used by maps?cid= links
kgmidstringKnowledge Graph machine ID
businessProfileIdstringGoogle Business Profile ID
urlstringGoogle Maps link
titlestringBusiness name
categoryNamestringPrimary category
categoriesarrayAll categories, primary first
descriptionstring or nullEditorial summary
taglinestring or nullShort tagline. Additional field
addressstringStreet address without the business name
street / city / state / postalCode / countryCode / neighborhoodstring or nullAddress split into parts
locationobject{ lat, lng }, each null when Google has no coordinates
phonestring or nullAs Google displays it
phoneUnformattedstring or nullDigits only
websitestring or null
totalScorenumber or nullAverage rating
reviewsCountnumber or nullSee Limits
openingHoursarray{ day, hours }, Monday first
openingHoursCompletebooleanWhether all seven days are present
openStatestring or nullOpen/closed text at the moment of the scrape. Not a permanent-closure flag
timezonestringIANA timezone
additionalInfoobjectAccessibility attributes
thumbnailstring or nullPreview image
searchString / language / rank / scrapedAtWhere this row came from

Example row, trimmed:

{
"fid": "0x8644b4eb0b01986f:0x6b241d4769ed491e",
"placeId": "ChIJbxgBC-u0RIYRHknsaUcdJGs",
"title": "ATX Family Dental",
"categoryName": "Dentist",
"address": "1700 S 1st St, Austin, TX 78704",
"city": "Austin", "state": "TX", "postalCode": "78704", "countryCode": "US",
"location": { "lat": 30.2482229, "lng": -97.7559705 },
"phone": "(512) 717-3147", "phoneUnformatted": "+15127173147",
"website": "https://www.atxfamilydental.com/",
"totalScore": 4.9, "reviewsCount": 902,
"openingHours": [{ "day": "Monday", "hours": "8 AM–5 PM" }],
"openingHoursComplete": true,
"additionalInfo": { "Accessibility": [{ "Wheelchair accessible entrance": true }] },
"searchString": "dentist in Austin TX", "rank": 1
}

Google Maps business scraper pricing

$0.50 per 1,000 delivered businesses.

  • A search term that returns nothing is not charged. Unlike some alternatives, this Actor does not fill an empty search with unrelated businesses.
  • Duplicate search terms and businesses that appear under more than one term are charged once.
  • Filtered-out businesses are not written and not charged.
  • Failed searches are not charged.
  • A resumed run does not refetch or recharge a business already in the Dataset.

The run summary records delivered alongside charged, so you can reconcile the bill against the Dataset.

Google Maps business data coverage and limits

Stated here rather than discovered later.

Up to 60 businesses per search term, in pages of 20. The default is 20, which requests only the first page; existing inputs that leave this field unset keep the single-page behavior and cost. Values from 21 to 40 use up to two pages; values from 41 to 60 use up to three. Higher values are capped at 60 with a warning in the run log and summary.

The Actor follows continuation cursors until the requested number is reached or the search ends. A page that Google returns with fewer than 20 raw results ends that term early, and an empty page ends it too. Results removed by the country filter or by your filters do not make an otherwise full upstream page short: if Google returned 20 raw results, pagination can continue even when fewer than 20 remain after filtering. Businesses are de-duplicated by fid across pages, and rank stays continuous in page order and Google's order within each page.

If a later page fails, that search term publishes no partial batch and is not marked complete. On resume, it starts again from the first page. Businesses already written to the Dataset are not delivered or charged twice, and other completed terms are not refetched.

Review count and weekly hours come and go. Google answers this endpoint with either a full payload or a lite one, and the choice is per response: either all 20 businesses carry the review count and seven-day hours, or none of them do. The run detects a lite payload and retries, waiting between attempts because that is what actually helps. Most businesses end up complete; some do not, and openingHoursComplete tells you which. reviewsCount is null when the payload omitted it.

openState is not a closure flag. It is the open or closed text at the moment of the scrape, so a business that is simply shut for the night reads as closed. This version does not extract a permanent-closure flag.

additionalInfo covers accessibility only. Other attribute groups are not part of the search response.

Not included in this version: review text, rating distribution, image counts and full image sets, claim status, emails and website contacts, and more than 60 businesses per search term.

Compatibility

Designed to match the core search semantics of the leading Google Maps Actor, not its full input contract. Field names, types and null rules for the core business fields follow that Actor, verified field by field against 100 rows of a live run on 2026-09-20: 99.94% semantic match across 24 core fields and 1,632 comparisons.

Result sets are not identical. Google returns a somewhat different set of businesses for the same search from one call to the next. When you ask for more than 20, this version reads up to three separate pages for that term.

API and automation

Read the Dataset directly:

curl "https://api.apify.com/v2/datasets/DATASET_ID/items?format=csv&clean=true" \
-H "Authorization: Bearer APIFY_TOKEN"

Start a run and wait for its Dataset in one call:

curl -X POST "https://api.apify.com/v2/acts/ACTOR_ID/run-sync-get-dataset-items" \
-H "Authorization: Bearer APIFY_TOKEN" \
-H "Content-Type: application/json" \
-d '{"searchStringsArray":["dentist in Austin TX"]}'

Each run also writes an OUTPUT record to the key-value store with how many search terms were requested and deduplicated, and how many businesses were delivered, charged, de-duplicated, filtered out, skipped on resume, and how many searches returned nothing or failed.

Continuation cursor (product API)

The /prd/v1/google-maps-business-scraper product API returns an opaque cursor. Pass it back with the same input and unit to get the next page. A cursor is bound to the normalized input, search term and per-term limit, and the product enforces a maximum of three pages and 60 businesses per term.

A malformed, damaged, mismatched or out-of-range cursor returns HTTP 400 with code invalid_cursor before any upstream request. The PRD boundary separately rejects a non-string or oversized cursor as bad_request. The cursor carries a format/checksum and input-binding check and validates the allowed page range; it is not a secret signature. A caller that recomputes a well-formed cursor is outside that integrity guarantee, while the hard delivery boundary remains three pages and 60 businesses per term.

Build a local lead generation workflow

Use this Actor to discover businesses, then continue with:

The shared business website and Google Maps identifiers make the three Actors easy to connect in Apify Tasks, schedules, API calls, n8n, or Make.

FAQ

Why did I get fewer than the number I asked for?

Google returned a short or empty page, the three-page limit was reached, or a filter removed some businesses. Filters continue to the next page when more can be fetched, up to three pages and 60 businesses per term. Filtered-out businesses are not charged.

A business has no phone or website. Was I charged?

Yes. That is a real answer: the business does not publish one. A row is only skipped when it has no stable identifier.

openingHoursComplete is false. Why?

Google answered with its lite payload for that request and the retries did not land a full one. The hours you do get are correct, just not the whole week.

My run stopped early.

If stoppedOnBudget is true in the run summary, the run hit the maximum charge you allowed. Raise the limit and start it again. Businesses already delivered are not refetched or recharged.

Can I search by Place ID or a Google Maps URL?

Not in this version. A run that sets placeIds or startUrls stops with an explanation rather than returning something else.

Can I get reviews?

Not from this Actor. See Limits.

Privacy

This Actor sends one small telemetry event when a run starts and one when it finishes, so we can measure reliability and decide what to build next. An event carries your search terms, the public filters you set, and run counters: how many results you asked for, how many were delivered, how long the run took, and which error categories came up.

An event never carries your Apify token, cookies, authorization headers, API keys, proxy credentials, request headers, or any scraped result. URLs are reduced to a hostname, a path shape, a public resource ID, and a short allowlist of public query parameters — usernames, passwords, fragments and every other query parameter are removed before the URL leaves the run. Your Apify user ID is stored only as a keyed one-way hash, never in the clear.

Search terms are kept for 90 days and then deleted. After that only lowercase aggregate counts remain, and those are what the trend reports are built from.

To switch telemetry off, tick Disable usage telemetry under Advanced options. With that option on, the Actor sends no telemetry events.

This Actor is independently developed and is not affiliated with, endorsed by, or sponsored by Google.

It reads a public endpoint. It does not sign in, does not use cookies or credentials, and does not reach anything behind a login. You are responsible for how you use the data, including any applicable terms and data-protection rules.