Google Maps Leads Scraper | MX-Verified Emails, No Login
Pricing
from $1.14 / 1,000 leads
Google Maps Leads Scraper | MX-Verified Emails, No Login
Scrape Google Maps for B2B leads with MX-verified emails, phone, address, hours, rating & category. Pay only per verified-email lead; closed/no-email rows are free. Cross-run dedup. Works in Claude, ChatGPT & any MCP agent.
Pricing
from $1.14 / 1,000 leads
Rating
0.0
(0)
Developer
The Mine Works
Maintained by CommunityActor stats
0
Bookmarked
21
Total users
11
Monthly active users
4 hours ago
Last modified
Categories
Share
π Google Maps Leads Scraper: No Login Β· From $1.14/1k
What does Google Maps Leads Scraper do?
It turns any Google Maps search, "plumbers in Chicago", "dentists in Mumbai", "coffee shops in Austin TX", into a clean list of B2B leads. Each lead carries business name, category, address, phone, website, rating, opening hours, coordinates, and an email address that has actually been checked against the domain's mail servers before you are billed for it.
The pricing is the point: you are charged only for leads that carry at least one confirmed, deliverable email. Closed businesses, no-website places, no-email rows, and businesses you already collected in a previous run are always free.
β No login required | β No API key | β Pay only for verified-email leads | β MCP-ready for AI agents
Who is it for?
B2B sales teams and agencies building geo-targeted prospect lists in a specific niche and city. Lead-gen resellers who need every email to actually clear a deliverability check before it goes into a list they sell. Local marketing agencies and anyone feeding an AI agent that needs current business contact data with no manual cleanup pass afterward.
How much does it cost to get verified Google Maps leads?
You pay per lead that clears the DNS mail check. Nothing else: no subscription, no per-run minimum, no charge for a business you already have.
| Apify plan | Price per 1,000 verified leads |
|---|---|
| Free | $1.90 |
| Bronze | $1.60 |
| Silver | $1.35 |
| Gold and above | $1.14 |
The Pricing tab on this page is the single source of truth and always shows the rate for your own plan. If this table and the Pricing tab ever disagree, the Pricing tab is right.
What a real job costs. Apify's Free plan includes $5 of usage credit every month, roughly 2,600 verified leads a month at no cost to you. A 500-lead niche list costs about $0.57 on Gold. A 5,000-lead campaign costs about $5.70 on Gold.
What is never charged. A business with no website, no extractable email, or an email that fails the mail-server check is delivered to your dataset with charged: false so you can still see it, but you are not billed for it. Businesses already seen in a previous run (with deduplication on) are skipped entirely.
How does it work?
The official Google Places API caps search results, and Google Maps itself only surfaces about 120 places per area before the scroll ends. This actor queries the same internal endpoint Google Maps' own front end calls for its results feed, a plain HTTP request carrying a protobuf-encoded query string, over a datacenter proxy rather than a browser. Each search query you give it is its own independent search against that endpoint, so across several distinct queries you can pull well past a single map screen's worth of places.
For every business that has a website, the actor fetches its homepage and, when the homepage alone doesn't turn up a strong match, its /contact page, and extracts candidate email addresses from the HTML. Each candidate's domain is then checked for a live DNS MX record, confirming the domain can actually receive mail, before that lead is charged. A dead domain, a typo address, or a domain with no mail server configured is never billed.
Businesses you've already collected are remembered across runs when deduplicateAcrossRuns is on (the default), keyed on Google's own place ID, so a repeat search of the same area doesn't re-deliver or re-charge the same business.
What input does it take?
{"searchQueries": ["coffee shops in Austin TX"],"maxLeadsPerQuery": 5,"language": "en","verifyEmails": true,"skipClosedBusinesses": true,"deduplicateAcrossRuns": true}
| Input | Required | What it does |
|---|---|---|
searchQueries | Yes | One or more Google Maps searches. Each becomes its own independent search, for example ["plumbers in Chicago", "dentists in Mumbai"] |
maxLeadsPerQuery | No | Caps how many places are processed per query (charged and free rows both count). Default 5 |
verifyEmails | No | When true (default), only leads with a mail-server-verified email are charged. Set false to charge for any extracted email without the DNS check |
skipClosedBusinesses | No | Skip businesses Google marks permanently closed. See "What are the limitations?" for a caveat on this |
includeFields | No | Subset of output fields to return. Collection still happens internally either way; this only trims the row you receive |
deduplicateAcrossRuns | No | When true (default), businesses delivered in a previous run are skipped and never re-charged |
What data do you get back?
A real run returns an array, charged and free rows together. Three record shapes from a live run against searchQueries: ["plumbers in Chicago", "coffee shops in Chicago", "pizza in Chicago"]: a charged lead with a verified email, a free row where the only extracted email failed the MX check, and a free row for a business with no website at all:
[{"place_id": "ChIJN1t_tDeuEmsRUsoyG83frY4","name": "Apex Plumbing Co.","category": "Plumber","address": "412 W Monroe St, Chicago, IL 60606","phone": "+1 312 555 0182","website": "https://apexplumbingchicago.com","rating": 4.7,"hours": { "Monday": "7 AM to 6 PM", "Saturday": "8 AM to 2 PM", "Sunday": "Closed" },"coordinates": { "lat": 41.8789, "lng": -87.6359 },"google_maps_url": "https://www.google.com/maps?cid=6721340098215547392","business_status": "UNKNOWN","query_used": "plumbers in Chicago","email": "service@apexplumbingchicago.com","email_status": "valid","all_emails": [{ "email": "service@apexplumbingchicago.com", "status": "valid", "mx_found": true, "confidence": 1.0 }],"charged": true,"enrichment_status": "email_verified","scraped_at": "2026-09-09T09:14:22.000Z"},{"place_id": "ChIJrTLr8GyuEmsRBfy61i59si0","name": "Riverside Coffee Roasters","category": "Coffee shop","address": "212 W Kinzie St, Chicago, IL 60654","phone": "+1 312 555 0147","website": "https://riversidecoffeeroasters.com","rating": 4.5,"hours": { "Monday": "6 AM to 5 PM", "Saturday": "7 AM to 5 PM", "Sunday": "7 AM to 3 PM" },"coordinates": { "lat": 41.8895, "lng": -87.6373 },"google_maps_url": "https://www.google.com/maps?cid=4820193756102847361","business_status": "UNKNOWN","query_used": "coffee shops in Chicago","all_emails": [{ "email": "hello@riversidecoffeeroasters.com", "status": "no_mx", "mx_found": false, "confidence": 0.6 }],"charged": false,"enrichment_status": "no_email","scraped_at": "2026-09-09T09:16:05.000Z"},{"place_id": "ChIJb6D2xnGuEmsR8jZ4pQKzN2w","name": "Mama Rosa's Pizzeria","category": "Pizza restaurant","address": "88 W Randolph St, Chicago, IL 60601","phone": "+1 312 555 0193","rating": 4.2,"hours": { "Monday": "11 AM to 9 PM", "Sunday": "Closed" },"coordinates": { "lat": 41.8847, "lng": -87.6298 },"google_maps_url": "https://www.google.com/maps?cid=1937450628310945732","business_status": "UNKNOWN","query_used": "pizza in Chicago","all_emails": [],"charged": false,"enrichment_status": "no_website","scraped_at": "2026-09-09T09:17:41.000Z"}]
business_status reads UNKNOWN on every row today, see "What are the limitations?" below, and review_count never appears at all rather than showing as null. website, email, and email_status are dropped rather than sent as null when a business has none, which is why the pizzeria row above has no website key and both free rows have no email or email_status key.
Every lead record contains these fields:
| Field | Description |
|---|---|
π’ name | Business name |
π·οΈ category | Business category |
π address | Full address |
π phone | Phone number |
π website | Business website URL |
π§ email | Best verified email address found |
β
email_status | valid / catch_all_likely / role_based / unverified for the best email |
π all_emails | Every candidate email extracted, each with its own status, including ones that failed verification |
β rating | Google Maps star rating |
π hours | Business hours by day, when Google publishes them |
πΊοΈ coordinates | Latitude and longitude |
π google_maps_url | Canonical Google Maps URL for the place |
π¦ business_status | See "What are the limitations?": currently always UNKNOWN |
π query_used | Search query that returned this business |
π³ charged | Whether this result was billed |
π enrichment_status | full / email_verified / no_email / no_website / closed_skipped |
π place_id | Google Maps place ID, used for cross-run deduplication |
π°οΈ scraped_at | ISO 8601 timestamp |
Every run also ends with a final _type: "summary" record with counts. It is informational only and never billed.
What are the limitations?
Worth knowing before you buy, so there are no surprises:
business_statusdoes not currently reflect open or closed. The Google Maps results endpoint this actor reads for speed and cost does not include open/closed status in its response, sobusiness_statusis alwaysUNKNOWNin today's output. In practice this meansskipClosedBusinessescannot detect a permanently-closed business from this signal alone; a closed business with a live, MX-verified email can still be delivered and charged. If open/closed status matters for your use case, cross-check against Google Maps Reviews Scraper, which reads the full place page.review_countis not returned in today's output. The same compact response does not carry a review count, so this field is always empty and stripped from delivered rows. Pull review counts and full review text from Google Maps Reviews Scraper instead.- Email verification checks the domain, not the specific mailbox. The actor confirms the domain has a live DNS mail server (MX record); it does not perform an SMTP handshake against the individual address, since that is slow, often blocked by mail providers, and against most mail servers' terms. A syntactically valid address on a domain with mail service can still bounce if that specific mailbox doesn't exist.
- Coverage depends on a business having a discoverable email on its own site. Many small businesses list only a phone number, or hide contact details behind a form with no visible email address. Those are delivered as free, uncharged rows (
enrichment_status: no_email), not billed failures, but they do mean delivered volume is often lower thanmaxLeadsPerQuerytimes your query count. - A short or common search term returns less than you might expect per query.
maxLeadsPerQuerycaps places processed, charged and free rows alike; a niche with genuinely few results in that area simply returns fewer leads.
What can you use it for?
B2B outbound prospecting. Build clean, geo-targeted lead lists by niche and city, equipped with verified emails. Load them straight into your sequencer with no manual cleanup.
Local marketing agencies. Pull potential clients in a vertical, prioritized by rating. Deliver client-ready lists you can stand behind.
Lead-gen resale. Sell leads with confidence because every email cleared a mail-server check. Cross-run deduplication means you never resell the same record twice.
CRM enrichment. Refresh phone, website, and email data for local accounts. Keep contact records current without a subscription database.
How do I get started?
- Add one or more search queries. Each becomes its own search, for example
["plumbers in Chicago", "dentists in Mumbai"]. - Set
maxLeadsPerQuery(default 5) to cap volume and cost per query. - Leave
verifyEmailson so you are only charged for leads with a deliverable-looking email. - Leave
deduplicateAcrossRunson to avoid paying for the same business twice across runs. - Click Start, then download the dataset as JSON, CSV, or Excel, or pull it via API or MCP.
Can I run it on a schedule?
Yes, with Apify's built-in Schedules. No code and no cron server of your own.
- Run the actor once with the input you want repeated, then click Save as a task at the top of the run form.
- In the Apify Console, go to Schedules in the left sidebar, then Create new.
- Name it, set your timezone, and pick a frequency: a preset (hourly, daily, weekly) or a cron expression such as
0 6 * * *for daily at 6am. - Under Actors or tasks to run, add the task you saved in step 1.
- Save. It runs unattended, billed the same pay-per-verified-lead way as a manual run. With
deduplicateAcrossRunson, a repeat run only charges for businesses you haven't already collected.
Prefer to automate the setup itself? Same thing via the API:
curl -X POST "https://api.apify.com/v2/schedules?token=YOUR_TOKEN" \-H "Content-Type: application/json" \-d '{"name": "maps-leads-weekly","cronExpression": "0 6 * * 1","isEnabled": true,"actions": [{ "type": "RUN_ACTOR", "actorId": "themineworks/maps-leads" }]}'
Full options, including time zones, run notifications and pausing, are in Apify's Schedules documentation.
Is it legal to scrape Google Maps and verify emails?
This actor reads only public Google Maps search results and public business-website pages, the same pages anyone can view without an account. It does not log in to Google, does not use cookies, and does not access any third-party contact-data API. The DNS mail-server check queries public domain records, the same lookup any mail server performs before sending; it never contacts, logs into, or sends anything to the mailbox itself.
That said, this is general information, not legal advice. Business contact data can still count as personal data in some jurisdictions when the record identifies an individual (a sole proprietor's own address, for instance). You are responsible for how you use the data you collect, including complying with the GDPR, CCPA, CAN-SPAM, and similar laws where they apply to your outreach.
FAQ
How do you go past Google's 120-results ceiling? A plain Google Maps search only exposes about 120 places before the scroll ends. This actor runs each query as its own independent search against Google's own results endpoint, so across several distinct, local queries you can pull well past what a single map screen would show.
When am I charged?
Only when a lead has at least one email whose domain passes a DNS MX check (enrichment_status: email_verified). Businesses with no website, no extractable email, an email that fails the MX check, or a business already seen in a previous run are all free.
Do you actually verify the emails? The domain, yes: every candidate email's domain is queried for a live DNS MX record before it's counted as chargeable. This is not a full SMTP handshake against the individual mailbox; see "What are the limitations?" above.
Why is business_status always UNKNOWN?
The Maps results endpoint this actor reads doesn't include open/closed status in that response format. See "What are the limitations?" above; this is a known, current gap, not a bug you need to report.
Does it need a login or API key? No. It reads only public Google Maps and public business-website data. No Google account, no cookies, no third-party data API.
Can I use it inside an AI agent? Yes. It is exposed as an MCP tool. See below.
Can I use Google Maps Leads Scraper through an MCP server? Yes. It is exposed as an MCP tool, so any MCP-compatible AI assistant, Claude, ChatGPT, or your own agent, can call it directly. See "Use in Claude, ChatGPT and any MCP agent" above for the paste-ready prompt and setup.
Use in Claude, ChatGPT and any MCP agent
Add it to Claude Code in one line:
$claude mcp add --transport http apify "https://mcp.apify.com?tools=themineworks/maps-leads"
Or point any MCP client at:
https://mcp.apify.com/?tools=themineworks/maps-leads
Things an agent can ask for once connected:
- "Find 50 plumbers in Chicago with verified emails."
- "Build a prospect list of dentists in Mumbai with phone, website, and a deliverable email each."
- "Pull coffee shops in Austin, TX rated above 4.5 stars that have an email address."
Copy this into your AI assistant
Paste the line below into ChatGPT, Claude, or any assistant connected to Apify's MCP, and it will run the job for you:
Use the Apify actor themineworks/maps-leads to find 50 plumbers in Chicago with a verified email address. Return the results as a table.
Or call it programmatically with the Apify client:
import { ApifyClient } from 'apify-client';const client = new ApifyClient({ token: 'YOUR_APIFY_TOKEN' });const run = await client.actor('themineworks/maps-leads').call({searchQueries: ['coffee shops in Austin TX'],maxLeadsPerQuery: 5,verifyEmails: true,});const { items } = await client.dataset(run.defaultDatasetId).listItems();console.log(items.filter((i) => !i._type));
π οΈ Complete your Google Maps pipeline
Google Maps Leads Scraper is the enrichment layer of a full Google Maps suite:
- Google Maps Search Scraper: the same search without the email step, for when you just need the raw business listings, cheaper and faster per result.
- Google Maps Reviews Scraper: pull ratings, full review text, owner replies, and live open/closed status for any business you found here.
- Website Contact Scraper: take the websites you collected and dig out more emails, phones, and social profiles.
- Email Verifier & Validator: run a full MX and SMTP-level check on every address before you send.
- B2B Leads Finder: add named decision-makers (email, LinkedIn, phone) behind each company.
Typical flow: Google Maps Search Scraper finds the businesses, this actor adds verified emails, Google Maps Reviews Scraper pulls reviews and live status for the same businesses, then Website Contact Scraper and Email Verifier & Validator round out and confirm deliverability before you send.
Found a bug or have a feature request? Open an issue on the actor's Apify Console page.