Google Maps Email Extractor - Contact Details & Leads Scraper avatar

Google Maps Email Extractor - Contact Details & Leads Scraper

Pricing

from $1.27 / 1,000 place scrapeds

Go to Apify Store
Google Maps Email Extractor - Contact Details & Leads Scraper

Google Maps Email Extractor - Contact Details & Leads Scraper

Extract emails, phone numbers and social profiles of local businesses found on Google Maps. Search by category and city and get name, address, rating, reviews, website and opening hours, plus the contacts published on each business website. For lead generation, sales outreach and local research.

Pricing

from $1.27 / 1,000 place scrapeds

Rating

0.0

(0)

Developer

SR

SR

Maintained by Community

Actor stats

0

Bookmarked

262

Total users

67

Monthly active users

8 days ago

Last modified

Share

Google Maps Email Extractor - Contact Details Scraper

This Google Maps email extractor finds local businesses on Google Maps and collects the email addresses, phone numbers and social profiles published on their own websites. Search for a business category in a city, and each row gives you the place name, address, phone number, rating, review count, website and opening hours, plus the contact details found on that website. Use the dataset to build a local lead list, prepare sales outreach, review directory information or research potential customers in a specific city.

Each result is a place returned by Google Maps for your search. Contact enrichment adds information found on the place's own website. A website can have an email address, a social profile, both or neither. Empty contact fields remain empty when the public page does not provide that information. The Actor does not infer an email address from a business name or domain. This Actor was previously listed as Google Maps Email & Contact Details Scraper; the Actor URL, input and output are unchanged.

How the Google Maps email extractor works

  1. You enter one or more search phrases, such as dentist Utrecht or coffee shops amsterdam, optionally with separate location fields.
  2. The Actor runs each phrase as a Google Maps search and reads the places in result order, up to your limit per query.
  3. Your filters (rating, reviews, website, category, name matching, closed places) remove places that do not match.
  4. For each remaining place with a website, the Actor opens the homepage and up to two relevant contact pages and extracts email addresses, website phone numbers and links to Facebook, Instagram, LinkedIn, X (Twitter), YouTube, TikTok and Pinterest.
  5. Every place is written to the dataset as one row, whether or not contact details were found.

Input: Google Maps contact details searches

Provide one or more search phrases in queries. Include a business category and a location, or combine a category with the separate location fields. This is the input used for a successful run:

{"queries": ["coffee shops amsterdam"], "max_results_per_query": 20}

max_results_per_query defaults to 120 and accepts values from 1 to 400. The limit applies to each query. Google can return fewer places than the limit, particularly for a narrow area or category. A larger limit requests more results; it cannot make an unavailable business appear in Google's response.

Set location_query, city, state, postal_code or country_code to add a location to your search. These values are appended in address order, while text already present in the query is skipped. The returned search_query shows the exact composed phrase. gl defaults to us and controls the search region; it does not replace the geographic words in your query. hl defaults to en and controls the language of categories, opening hours and other display labels.

Set scrape_contacts to false when you only need the Maps information. It defaults to true.

Two older settings keep their names and defaults, so saved tasks and API calls continue to work unchanged. use_cookies defaults to true and lets the Actor open Google Maps with a fresh session, which returns the full set of place attributes and review counts; leave it on unless you are running a small test. use_proxy defaults to false and is still accepted, but it no longer changes the results: every run uses the same request routing. The optional cursor field is a continuation token for paged API access. A run already continues through all result pages on its own, so you normally leave it empty; if you do set it, keep the other input fields unchanged.

Filters and result counts

Use minimum_stars for a minimum rating of 3, 3.5, 4 or 4.5. minimum_reviews sets the lowest review count you want to keep. A place without a supplied rating or review count cannot pass the corresponding minimum. When Google's response omits a required filter field for all relevant results, the run reports that condition rather than claiming that every place had a low rating.

The website option accepts any, with_website or without_website. category_filter_words keeps places whose categories include at least one supplied word. search_matching supports all, only_includes and only_exact: the latter modes compare the place name with terms from the composed search phrase, including location terms. skip_closed_places removes places marked permanently closed. A temporarily closed place can remain in the results.

Filters apply after searching, so a filtered dataset can be smaller than the requested limit. The summary includes placesScanned, placesRejectedByFilters and filtersApplied, alongside the delivered result and enrichment counts. Use those fields to distinguish a restrictive filter from a search with few available places.

Output and exports

The default dataset contains one row per place, in query order and then result order. The same place can appear in more than one query. Core fields include name, place_id, fid, kgmid, address, neighborhood, street, city, postal_code, state, country_code, lat, lng, category, categories, rating, reviews_count, phone, website, website_domain, search_position and search_query. neighborhood contains the neighborhood supplied by Google, or null when it is unavailable.

Opening information is returned in current_status and opening_hours, with a day label and hours text for each supplied day. additional_info contains Google's grouped attributes. Fields such as price_range, plus_code and hours_status remain available and can be null when the response does not supply a usable value.

When contact enrichment is enabled, rows also contain emails, phones_on_website, contact_page_url, website_crawled, facebook, instagram, linkedin, twitter, youtube, tiktok and pinterest. Emails are lowercase and deduplicated. The Actor checks the homepage and up to two relevant contact pages. A failed website request keeps the Maps place available, with empty contact fields.

If Google lists a social profile as the place's website, that URL stays in website. Social profiles are skipped during the website crawl, so website_crawled remains false and the contact fields remain empty. Internal platform links are excluded from contact results. This does not generate a contact enrichment charge. Public links to business profiles found on a business website can still appear in the social fields.

This excerpt comes from an actual run with the input {"queries": ["dentist"], "location_query": "Utrecht", "country_code": "NL", "hl": "nl", "gl": "nl", "minimum_stars": "4", "minimum_reviews": 20, "website": "with_website", "max_results_per_query": 15} and several other filters, with a selection of the returned fields shown:

{
"search_position": 5,
"name": "Dental Clinics Utrecht Maliebaan",
"place_id": "ChIJdbHxEE1vxkcRKMHDEZqzNWw",
"address": "Dental Clinics Utrecht Maliebaan, Maliebaan 44, 3581 CS Utrecht",
"city": "Utrecht",
"postal_code": "3581 CS",
"country_code": "NL",
"lat": 52.0921853,
"lng": 5.1341021,
"category": "Tandarts",
"rating": 4.6,
"reviews_count": 474,
"phone": "030 231 0003",
"website_domain": "dentalclinics.nl",
"search_query": "dentist Utrecht NL",
"emails": ["maliebaan@dentalclinics.nl"],
"phones_on_website": ["+31302310003", "+319008602"],
"website_crawled": true,
"facebook": "https://www.facebook.com/DentalClinicsNL/?locale=nl_NL",
"instagram": "https://www.instagram.com/dentalclinicsnl",
"linkedin": "https://linkedin.com/company/dental-clinics-nederland",
"youtube": "https://www.youtube.com/channel/UC5FI8ARmy_GYNt3lT0JSb2Q",
"twitter": null,
"tiktok": null
}

In that run, 26 places were scanned, 11 were rejected by the filters and 15 were delivered; 14 of the 15 had at least one email address or social profile on their website. A place without contact details looks like this excerpt from the prefill run (coffee shops amsterdam):

{
"name": "Boerejongens",
"place_id": "ChIJG8scpJUJxkcR4ccjAgpLST4",
"address": "Boerejongens, Utrechtsestraat 21, 1017 VH Amsterdam, Netherlands",
"rating": 4.5,
"reviews_count": 5778,
"phone": "+31 20 447 3557",
"website": "https://www.boerejongens.com/",
"emails": [],
"facebook": null,
"instagram": null,
"website_crawled": true
}

Download the dataset as JSON, CSV or Excel through Apify. JSON preserves the nested opening-hours and attribute structures. The key-value store contains the summary record (also stored as OUTPUT) and an errors record when individual searches could not be completed. The summary includes warnings and partial: when a business website could not be checked completely, warnings names that website and partial is true, while every place row is still delivered. A contact link that returns 404 or 410 is treated as a missing page and does not make the run partial. A search with no matching places can finish successfully with an empty dataset.

Use cases

  • Local lead generation: build a list of dentists, plumbers, restaurants or agencies in a city, with an email address and phone number for each business that publishes one.
  • Sales outreach: combine emails, phone and linkedin to reach a business through the channel it actually uses, and use rating and reviews_count to prioritise.
  • Market and competitor research: count businesses per category and area, compare ratings and review volumes, and see which competitors have a website or social presence.
  • Directory and CRM enrichment: match on place_id or website_domain to update addresses, opening hours and contact channels in an existing database.
  • Agency prospecting: use website set to without_website to find businesses that may need a website, and the rating and review fields to see which ones have an established reputation.

Google Maps email extractor compared with other options

OptionMaps place dataEmails and social profilesEffort
Copying from Google Maps by handyes, one place at a timeonly after visiting each website yourselfvery high
A general Google Maps scraperyesusually not, or as a separate steplow, but a second tool is needed for contacts
Browser extensionspartly, limited to what is visible on screenvariesmedium, tied to your browser session
This Actoryes, including hours and attributesyes, from the business's own website, in the same rowlow: one input, one dataset, API and schedules available

You pay per place and per enriched place, not per page or per compute minute, so the cost of a run follows the number of businesses you receive. Setting scrape_contacts to false turns this Actor into a plain Maps place extractor without contact-enrichment events.

Pricing

The FREE-tier event prices are $0.0035 per delivered place, $0.0028 per contact-enriched place and $0.0007 per delivered place when a rating, review, website, category or name filter is enabled. A contact-enriched place has at least one email address or social profile found on its website. Merely attempting a website request does not create an enrichment event. Selecting only skip_closed_places does not activate the filter event.

Paid Apify tiers use their corresponding event prices displayed in the pricing panel. Apify also applies the Actor start event, with a FREE-tier price of $0.0002 per GB. An empty result produces no place, enrichment or filter events. The current Apify pricing panel is the authoritative listing of applicable prices and platform charges.

Free-plan runs deliver at most ten places. Only those delivered places contribute to the place, contact and filter event counts. Paid users can request the full result limit per query. Review the input and the pricing panel before running a large list of search phrases.

FAQ

Why do some places have no email address?

Google usually supplies a website link rather than an email address. The Actor checks that website for public contact information. A website may omit email addresses, show only a contact form or be unavailable during the run. Social profiles can still be present even when emails is empty.

Why did I get fewer results than requested?

The result limit is a ceiling. The search area, Google's available place list and your filters determine how many rows remain. Inspect the composed search_query, the filter settings and the summary counters before expanding the search.

Can I collect Maps places without contact enrichment?

Yes. Set scrape_contacts to false. You retain the Maps fields and avoid contact-enrichment events. This is useful for comparing locations, ratings, categories or existing website links.

Does a website failure remove the business from my dataset?

No. The Maps row remains available. website_crawled is false when the website could not be fetched, and contact fields stay empty. The Actor retries an unreachable website before giving up. If a website still cannot be checked, the run summary lists it in warnings, for example Website could not complete contact enrichment: https://easytimes.amsterdam/, and sets partial to true. A website phase limited by the run budget produces a warning as well. You are not charged a contact-enrichment event for a website that yielded no contacts.

What if a business only lists an Instagram or Facebook page?

Then that profile URL is returned in website, exactly as Google Maps shows it. The Actor does not crawl social profiles as if they were business websites, so website_crawled is false, the contact fields stay empty and no contact enrichment is charged for that place. Profiles that a business links from its own website do appear in facebook, instagram and the other social fields.

This excerpt from the prefill run (coffee shops amsterdam) shows such a place:

{
"name": "Coffeeshop Bluebird",
"place_id": "ChIJaRaLkL4JxkcR918LcqGLDwM",
"rating": 4.5,
"reviews_count": 3206,
"website": "https://www.instagram.com/bluebirdcoffeeshopams/",
"website_domain": "instagram.com",
"emails": [],
"website_crawled": false,
"facebook": null,
"instagram": null
}

How do I search several cities?

Put a separate phrase for each city in queries, or create separate runs with the location fields. A location field applies to every query in that run. Using explicit category-and-city phrases makes each returned search_query easy to inspect.

Is this Google Maps email extractor free?

Free-plan users can run it and receive up to ten places per run. Every delivered place is charged at the event prices listed above, also on the free plan, and empty results cost nothing apart from the Actor start event.

Which countries and languages are supported?

Any country where Google Maps lists businesses. Set gl to the country code for the search region and hl for the language of categories and opening hours; the Dutch example above uses gl and hl set to nl.

Can I use it through the API or on a schedule?

Yes. Start runs through the Apify API, a schedule, or an integration such as Zapier or Make, and read the dataset as JSON, CSV or Excel. The input is the same as in the Console.