Google Maps Email & Social Leads Scraper
Pricing
from $2.02 / 1,000 business leads
Google Maps Email & Social Leads Scraper
Search Google Maps by keyword and location, then scan each business website for public emails, phone links and Facebook, Instagram, LinkedIn, X, YouTube and TikTok profiles. One flat lead row per business.
Pricing
from $2.02 / 1,000 business leads
Rating
0.0
(0)
Developer
Automation Lab
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
a day ago
Last modified
Categories
Share
Turn a Google Maps search into a prospect list. Enter a business type ("dentist", "roofing contractor", "coffee shop") and one or more cities. The Actor collects the matching businesses from Google Maps and then visits each business website. From the website it reads public emails, phone links and social profiles: Facebook, Instagram, LinkedIn, X (Twitter), YouTube, TikTok and Pinterest.
You get one flat row per business: name, address, Maps phone, website, rating, emails and social links side by side. The row is ready for a CRM import, a cold-email tool or a spreadsheet.
- 🔎 Search by keyword × location: several keywords and several cities in one run.
- 📧 Emails from mailto links, page text and Cloudflare-protected addresses. Emails on the business website's own registrable domain (Public Suffix List aware, so
acme.co.ukandacme.github.ioare not confused with other sites on the same suffix) are listed first; the rest keep page order. - 📱 Social links: Facebook, Instagram, LinkedIn, X, YouTube, TikTok, Pinterest.
- 📄 Reads the homepage plus up to 4 contact, imprint, about or team pages of each site.
- 🎯 Filters at no extra charge: only places with a website, only leads with an email, minimum star rating.
- 💸 One flat price per lead: no add-on events for contacts, filters or social links.
What does Google Maps Email & Social Leads Scraper do?
- It runs each search (for example
dentist Austin, TX) on Google Maps and pages through the result list, 20 places per page. - It skips duplicates (the same place found by two searches) and places that fail your filters.
- It opens the business website, finds the best contact pages on that site, and extracts emails,
tel:phone numbers and social profile links. - It saves one lead row and charges one lead event. Then it moves to the next place.
If a website is down or refuses automated visitors, you still get the Google Maps data. The websiteStatus field then says failed or blocked, so you can see why the contact fields are empty.
Who is it for?
- Agencies and freelancers building outreach lists of local businesses (web design, SEO, marketing, bookkeeping).
- SaaS sales teams prospecting a vertical such as dentists, gyms, salons, law firms or HVAC companies in many cities.
- Lead-generation sellers refreshing niche lists on a schedule.
- Recruiters and partnership managers who need the official contact address and social pages of local companies.
- Market researchers who want to know how many businesses in an area have a website, an email or an Instagram account.
Why use this Actor?
- Contacts included in the lead price. Some Google Maps scrapers charge one event for the place and another for contact enrichment. Here one lead event covers the Maps data, the website scan and all social links.
- Several cities per run. Every search term is combined with every location, up to 50 combinations per run.
- Transparent failures. Every row has
websiteStatus,websiteErrorandpagesScanned, so empty contact fields are explained. - Clean URLs.
utm_*and other tracking parameters are removed from websites, and phone numbers are deduplicated. - Safe by default. The Actor visits only public websites. It checks the address each connection actually uses, including after redirects, so private-network addresses are refused. Every page is capped at 1.5 MB and 12 seconds.
What data can you extract from Google Maps businesses?
| Field | Example | Source |
|---|---|---|
name | 38th Street Dental | Google Maps |
category, categories | Dentist, Cosmetic dentist… | Google Maps |
address, neighborhood, cityRegion | 1500 W 38th St Ste 56, Austin, TX 78731 | Google Maps |
phone, phoneInternational | (737) 260-5523, +17372605523 | Google Maps |
website, domain | https://www.myaustindds.com/ | Google Maps |
rating, reviewsCount | 5, 734 | Google Maps |
latitude, longitude | 30.3082, -97.7488 | Google Maps |
placeId, cid, fid, googleMapsUrl | ChIJe5fsvYXKRIYR… | Google Maps |
primaryEmail, emails | info@atxfamilydental.com | Business website |
websitePhones | +15124586222 | Website tel: links |
facebookUrl, instagramUrl, linkedinUrl, twitterUrl, youtubeUrl, tiktokUrl, pinterestUrl | https://www.instagram.com/38thstreetdental | Website links |
contactPageUrl, pagesScanned | https://www.myaustindds.com/contact/ | Website scan |
websiteStatus, websiteError | scanned / failed / blocked / no_website | Website scan |
searchString, searchLocation, rank | dentist, Austin, TX, 3 | Your input |
How much does it cost to scrape Google Maps business emails and social links?
The Actor uses pay-per-event pricing. You pay a small fee per run plus one fee per saved lead. Website visits, filters and social links have no separate charge.
| Event | Price (Bronze plan) |
|---|---|
| Run start | $0.003 per run |
| Business lead saved | $0.00336 per lead |
Example costs on the Bronze plan:
| Leads saved | Cost |
|---|---|
| 10 leads | $0.037 |
| 100 leads | $0.34 |
| 1,000 leads | $3.36 |
Higher Apify plans pay less per lead (Silver $0.0026208, Gold and above $0.002016). The Free plan pays $0.003864 per lead. You never pay for places skipped by your filters, duplicates, or leads dropped by the email-only filter. Set Maximum leads per run or a maximum charge per run to cap your spend.
How to scrape emails from Google Maps businesses
- Open the Actor in Apify Console and click Try for free.
- Under Search terms, enter one or more business types, for example
dentistorplumber. - Under Locations, enter the cities or areas, for example
Austin, TXandDallas, TX. - Set Maximum leads per search and Maximum leads per run.
- Optional: turn on Only leads with an email or set a Minimum Google rating.
- Click Start. Download the leads as CSV, Excel or JSON, or send them to your CRM.
Input parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
searchStringsArray | string[] | required | Business keywords. Each is combined with each location. |
locationQueries | string[] | empty | Cities or areas appended to each search term. Leave empty if your search terms already include the place. |
maxPlacesPerSearch | integer | 20 | Leads saved per search term × location, after filters (1–500). |
maxItems | integer | 100 | Leads saved per run across all searches (1–5,000). |
onlyWithWebsite | boolean | true | Skip places without a website. |
onlyWithEmail | boolean | false | Save only leads where an email was found; other places are not billed. Searches where very few websites have an email stop early (see FAQ). |
minRating | number | none | Skip places rated below this value, and places with no rating. |
maxPagesPerWebsite | integer | 3 | Homepage plus up to N−1 contact/imprint/about/team pages (1–5). |
language | string | en | Google interface language (en, de, es, fr, pt-BR…). |
countryCode | string | us | Google region context (us, gb, de…). This does not restrict results to that country. |
Example input:
{"searchStringsArray": ["dentist", "orthodontist"],"locationQueries": ["Austin, TX", "San Antonio, TX"],"maxPlacesPerSearch": 50,"maxItems": 200,"onlyWithEmail": true}
Output example
A real lead row (shortened):
{"name": "38th Street Dental","category": "Dentist","address": "1500 W 38th St Ste 56, Austin, TX 78731","phone": "(737) 260-5523","phoneInternational": "+17372605523","website": "https://www.myaustindds.com/","domain": "myaustindds.com","rating": 5,"reviewsCount": 734,"primaryEmail": null,"emails": [],"websitePhones": ["+15124586222"],"facebookUrl": "https://www.facebook.com/38th-Street-Dental-201580976550317/","instagramUrl": "https://www.instagram.com/38thstreetdental","linkedinUrl": "https://www.linkedin.com/company/38th-street-dental","twitterUrl": null,"youtubeUrl": null,"tiktokUrl": null,"pinterestUrl": null,"socialLinksCount": 3,"contactPageUrl": "https://www.myaustindds.com/contact/","pagesScanned": ["https://www.myaustindds.com/", "https://www.myaustindds.com/contact/", "https://www.myaustindds.com/locations/austin-office/"],"websiteStatus": "scanned","websiteError": null,"placeId": "ChIJe5fsvYXKRIYRwmoXXLCat2Q","cid": "7257439406780803778","googleMapsUrl": "https://www.google.com/maps?cid=7257439406780803778","searchString": "dentist","searchLocation": "Austin, TX","rank": 3,"scrapedAt": "2026-10-31T07:09:25.492Z"}
The dataset has two views: Leads (contact columns first) and Social links. The run's OUTPUT record in the key-value store holds counters: searches, places seen, duplicates, filtered places, websites scanned/failed and why the run stopped. searchesFailed counts searches whose first Google Maps page failed, searchesIncomplete counts searches that stopped on a later page (rows already saved are kept), and searchErrors lists each failure with its page number.
Tips and limits
- How many results per search? Google Maps usually lists about 120–200 places for one search. To get more, split the area into neighborhoods or nearby towns, for example
plumber Brooklynandplumber Queensinstead ofplumber New York. - Google Maps changes are reported, not hidden. The Actor only accepts the Google Maps response layouts it recognizes. An unrecognized layout counts as a failed search page instead of an empty result, and the run fails when every search fails. A real "no results" answer still finishes successfully with 0 rows.
- Places without a category. A few places, for example some hotel brands, have no Google category. They are still saved, with
categoryset to null. - Location is search text. Google decides relevance and may include nearby places outside the city you typed.
- Not every business publishes an email. In our tests, 50–70% of businesses with a website showed an email, and 70–80% linked at least one social profile. This depends a lot on the industry and country.
- Blocked websites. Some sites use bot protection (for example Cloudflare challenges) or are offline. Those rows have
websiteStatus: "blocked"or"failed"and keep the Google Maps data. - Emails are not verified. The Actor reports the addresses published on the site. Check deliverability with an email verifier before a campaign.
- Websites built fully in client-side JavaScript can hide emails from a plain page download. Use
contactPageUrlto check those sites manually.
Integrations
- Google Sheets / Excel: export the Leads view as CSV, or use the Apify Google Sheets integration to append new leads after each scheduled run.
- HubSpot, Pipedrive, Salesforce: connect through Make, Zapier or n8n. Map
name,primaryEmail,phoneInternational,websiteandaddressto company fields. - Cold email tools (Instantly, Lemlist, Smartlead): filter rows with
primaryEmail, verify them with our Bulk Email MX Verifier, then import. - Scheduled refresh: create an Apify schedule that runs the same searches every week and send new rows to a webhook.
Use the Actor with the Apify API
cURL:
curl -X POST "https://api.apify.com/v2/acts/automation-lab~google-maps-business-website-email-and-social-contact-leads/run-sync-get-dataset-items?token=YOUR_APIFY_TOKEN" \-H "Content-Type: application/json" \-d '{"searchStringsArray":["dentist"],"locationQueries":["Austin, TX"],"maxItems":20}'
JavaScript:
import { ApifyClient } from 'apify-client';const client = new ApifyClient({ token: 'YOUR_APIFY_TOKEN' });const run = await client.actor('automation-lab/google-maps-business-website-email-and-social-contact-leads').call({searchStringsArray: ['dentist'],locationQueries: ['Austin, TX'],maxItems: 20,onlyWithEmail: true,});const { items } = await client.dataset(run.defaultDatasetId).listItems();console.log(items.map((lead) => [lead.name, lead.primaryEmail, lead.instagramUrl]));
Python:
from apify_client import ApifyClientclient = ApifyClient("YOUR_APIFY_TOKEN")run = client.actor("automation-lab/google-maps-business-website-email-and-social-contact-leads").call(run_input={"searchStringsArray": ["dentist"],"locationQueries": ["Austin, TX"],"maxItems": 20,})for lead in client.dataset(run["defaultDatasetId"]).iterate_items():print(lead["name"], lead["primaryEmail"], lead["facebookUrl"])
Use with AI agents through MCP
Connect the Actor to Claude Code, Claude Desktop, Cursor or another MCP client through the Apify MCP server:
claude mcp add --transport http apify \"https://mcp.apify.com?tools=automation-lab/google-maps-business-website-email-and-social-contact-leads"
Claude Desktop, Cursor and VS Code: add this configuration to the client's MCP settings and authenticate with your own Apify token:
{"mcpServers": {"apify": {"url": "https://mcp.apify.com?tools=automation-lab/google-maps-business-website-email-and-social-contact-leads"}}}
Selecting this Actor also adds Apify's helper tools for runs and datasets (get-actor-run, get-dataset-items, get-key-value-store-record, abort-actor-run). A good agent workflow:
- Start one run and keep its run ID.
call-actorwaits at most about 45 seconds, so a larger lead list may still be running. - If the run is not finished, check the same run with
get-actor-runusing short backoff (2, 4, 8 seconds) and a total deadline. Do not start a second run just to poll. - When it succeeds, read the dataset with
get-dataset-itemsin pages:offset0, then 20, 40 and so on, withlimit20 and only the fields you need (fields:name,primaryEmail,website,instagramUrl). - Set a total budget for the chat before you start, for example at most 100 rows or 64 KB of returned data and a 5-minute deadline. Stop paging when you reach it.
- If you stop early, or the run ended with
stopReasonother thancompletedin itsOUTPUTrecord, say that the results are partial. Give the user the dataset ID so the full list can be exported from Apify storage instead of being pasted into the chat.
Example prompts:
- "Find 30 coffee shops in Lisbon with an Instagram account and list their emails."
- "Get roofing contractors in Phoenix, AZ rated 4.5 or higher that publish an email address."
- "Build a list of dentists in Austin and San Antonio with website, phone and Facebook page."
Is it legal to scrape emails from Google Maps and business websites?
The Actor collects publicly shown business listing data and contact details that businesses publish on their own websites. It does not log in, solve CAPTCHAs or access private data. Some business emails name a person (for example jane.doe@clinic.com). That is personal data under GDPR and similar laws. You are responsible for having a lawful basis to process it, and for following anti-spam rules such as CAN-SPAM, CASL and the ePrivacy Directive, including opt-out handling. Respect the websites' terms. When in doubt, ask a lawyer. This Actor is not affiliated with or endorsed by Google.
Data handling. The Actor uses no AI or model provider. Leads are stored only in your Apify run storage, under your account's retention settings. When a run fails, sanitized diagnostic input, the error and the Actor/build/run IDs are sent to our private GlitchTip service so we can fix the problem. Secret fields and URL query strings are removed, and reports are deleted after 30 days.
FAQ
Why do some leads have no email?
The business did not publish an email on the scanned pages, used a contact form instead, or the site was offline or blocked (see websiteStatus and websiteError). Increase Pages to scan per website to 4–5 to read more pages, or turn on Only leads with an email so you pay only for leads with an email.
Why did I get fewer leads than I asked for?
Google Maps ran out of results for that search, or your filters removed places. Check the OUTPUT record for placesSeen, filteredOut and duplicates. Use smaller areas or more keyword variations for more results.
Why did an email-only search stop early?
With Only leads with an email, the Actor visits websites that may not be saved. When a search has visited at least 40 websites and found fewer than one saved lead per 15 visits, it moves to the next search. The whole run stops the same way after 100 visits (stopReason: "lowEmailYield"). The OUTPUT record shows websiteVisits and searchesStoppedLowEmailYield. Try a business type that usually publishes emails, or turn the filter off.
Is the same business charged twice when two searches find it? No. Places are deduplicated across the whole run by their Google Maps ID. Only the first search that finds a place saves it.
Can I get leads without a website?
Yes. Turn off Only places with a website. Those rows have websiteStatus: "no_website" and are charged as normal leads.
Does it scrape Google reviews or photos? No. For reviews use our Google Maps Place Reviews Scraper.
Related Actors
- Google Maps Business Directory Scraper: cheaper Google Maps place lists without the website scan.
- Website Contact Finder: extract contacts from your own list of website URLs.
- Website Email Extractor: crawl websites you supply for email addresses.
- Bulk Email MX Verifier: check the mail servers of extracted email domains before outreach.
- Google Maps Place Reviews Scraper: collect reviews for the places you found.