Google Maps Scraper API — Local Business Leads & Emails avatar

Google Maps Scraper API — Local Business Leads & Emails

Pricing

from $20.00 / 1,000 lead extracteds

Go to Apify Store
Google Maps Scraper API — Local Business Leads & Emails

Google Maps Scraper API — Local Business Leads & Emails

Google Maps scraper API for leads: export names, phones, websites, emails, ratings, and coordinates by keyword and location. Guide: https://konabayev.com/tools/google-maps-leads-extractor/?utm_source=apify_readme&utm_medium=referral&utm_campaign=google-maps-leads

Pricing

from $20.00 / 1,000 lead extracteds

Rating

0.0

(0)

Developer

Tugelbay Konabayev

Tugelbay Konabayev

Maintained by Community

Actor stats

1

Bookmarked

31

Total users

1

Monthly active users

3 days ago

Last modified

Share

Google Maps scraper API for local business leads. Search a keyword + location, export business names, phone numbers, websites, ratings, coordinates, and optional email candidates whose domains have MX records. Bounded blocking recovery — optional 2Captcha/CapSolver handling and proxy support can recover some challenged runs, but access is never guaranteed. MX domain checks — DNS lookup records whether a non-Null MX exchanger is published; it does not prove that the domain or individual mailbox will accept a message. Firecrawl-powered website enrichment — when the business website is anti-bot-protected, we route through Firecrawl with JS rendering and proxy rotation. Per-record quality score — every record gets a 0.0-1.0 completeness score so you can filter low-quality leads downstream.

For implementation notes, examples, and local lead-generation workflows, see the Google Maps Leads Extractor guide on Konabayev.com.

Google Maps Leads Pro with structured business fields and optional email enrichment

Google Maps Leads input and output example Google Maps local business lead dataset preview

Why use this Google Maps lead extractor?

This Actor combines a bounded Google Maps search workflow with optional public-website enrichment. It is designed for teams that want one structured dataset and Apify-native scheduling instead of maintaining separate collection, normalization, and export jobs.

  • Optional blocking recovery. Proxy support and configured CAPTCHA providers can recover some challenge paths. They do not guarantee access, and the run reports when blocking remains.
  • Email-domain routing signal. MX checks record whether a non-Null MX exchanger is published; they do not prove that the domain or mailbox will accept a message or that outreach is permitted.
  • Optional website fallback. Firecrawl can retry a business website when the direct request does not produce usable enrichment. It does not bypass authentication or private content.
  • Quality score on every record. qualityScore is a documented completeness heuristic for filtering rows, not a guarantee of contactability or conversion.

Comparison

CapabilityThis ActorGeneral Store scraperOfficial Google Places API
Primary useExport public place rows with optional website enrichmentVaries by ActorSupported place data through an official API
Blocking behaviorProxy and optional solver recovery; still best-effortVaries by implementationGoverned by official quotas and SKU rules
Website email enrichmentOptional public-site extraction plus MX-domain signalVaries by ActorNot supplied as a website-email workflow
OutputApify Dataset with quality/provenance fieldsActor-specificOfficial response schema
AutomationApify API, schedules, webhooks, MCPUsually Apify-nativeCustom integration required
PricingPPE events plus the published Actor-start eventActor-specificCurrent Google Maps Platform pricing
Best fitApify-native lead research and enrichmentCompare current Store outputs and reviewsFirst-party supported place-data integration

What You Extract

Core Google Maps fields (always present)

  • name — business name (deduped within the run)
  • category — primary Google category
  • address + parsed city, state, postalCode, country
  • phone — when listed
  • website — when listed
  • rating, reviewsCount — when visible
  • sourceStatuslimited_view when Google explicitly returns its limited-view notice; review counts and the full week may be unavailable. standard_view means no such notice was detected, not that every field exists. unavailable means detail extraction failed and only the discovered business name remains. The actor returns and charges existing result events for the fields actually available; filter this column when you need detailed records.
  • priceLevel$ / $$ / $$$ / $$$$ when visible
  • openingHours — raw text from Google Maps
  • latitude, longitude — explicit coordinates of the selected place from its URL; a map viewport center is not used as a substitute
  • placeUrl — Google Maps URL
  • searchQuery — which input query found this place
  • extractedAt — ISO 8601 UTC timestamp

Premium fields (Pro only)

  • email — extracted from a public website and retained when a non-Null MX record is observed or the DNS check is inconclusive
  • emailVerified — legacy field name; true only when DNS returns a non-Null MX exchanger, never proof of domain or mailbox deliverability
  • socialMedia{facebook, instagram, twitter, linkedin, youtube, tiktok} URLs
  • websiteEnrichedtrue if Firecrawl rescue was used (anti-bot-protected sites)
  • websiteTitle, websiteDescription — meta tags from business website
  • openingHoursStructured{monday: {open: "09:00", close: "17:00"}, tuesday: ..., ...}
  • qualityScore — 0.0-1.0 weighted completeness score

Quality SLA

Pro enforces a quality contract on every run before publishing the dataset:

MetricTargetWhat it means
Min items returned1If a query returns nothing, the run fails loudly instead of silently shipping an empty dataset.
Min contact rate70%At least 7 in 10 records must have phone OR website OR email.
Min MX-checked email rate (when extractEmails: true)50%Half of records with an email must expose a non-Null MX exchanger; this is not mailbox validation.
Min average quality score0.40Average completeness across the dataset.

If the dataset misses these targets, the run is flagged so you can re-run on a different proxy/region instead of paying for junk.

How to run: input examples

  1. Start with one keyword/location query and a small result limit; keep optional website/email enrichment off.
  2. Inspect source place URLs, contact coverage, qualityScore, and extractedAt before enabling paid enrichment.
  3. Scale only validated markets and follow consent, suppression-list, privacy, and outreach requirements.

Fast first run (no enrichment)

{
"searchQueries": ["dentists in Miami FL"],
"maxItems": 10
}

Premium B2B prospecting (full enrichment)

{
"searchQueries": ["dental clinics in Miami FL"],
"maxItems": 100,
"extractEmails": true,
"extractSocialMedia": true,
"verifyEmailMx": true,
"firecrawlFallback": true,
"parseOpeningHours": true,
"includeQualityScore": true,
"solveCaptcha": true
}

Multiple cities, deduped output

{
"searchQueries": [
"plumber in Phoenix AZ",
"plumber in Tucson AZ",
"plumber in Mesa AZ"
],
"maxItems": 50,
"extractEmails": true,
"verifyEmailMx": true
}

Direct place URLs (CRM enrichment)

{
"placeUrls": [
"https://www.google.com/maps/place/Mama+Joe's+Pizza/@40.7,-74.0",
"https://www.google.com/maps/place/Joe's+Coffee/@40.71,-74.01"
],
"extractEmails": true,
"extractSocialMedia": true,
"verifyEmailMx": true
}

Cost-controlled high-volume run

{
"searchQueries": ["coffee shops in Brooklyn"],
"maxItems": 200,
"extractEmails": false,
"maxConcurrency": 5,
"includeQualityScore": true
}

Output Example

{
"name": "Mama Joe's Pizza",
"category": "Pizza restaurant",
"address": "123 Main St, Brooklyn, NY 11201, USA",
"city": "Brooklyn",
"state": "NY",
"postalCode": "11201",
"country": "USA",
"phone": "+1 718-555-0142",
"website": "https://mamajoes.com",
"email": "info@mamajoes.com",
"emailVerified": true,
"socialMedia": {
"facebook": "https://facebook.com/mamajoespizza",
"instagram": "https://instagram.com/mamajoespizza"
},
"rating": 4.6,
"reviewsCount": 1247,
"priceLevel": "$$",
"openingHours": "Monday: 11 AM–10 PM; Tuesday: 11 AM–10 PM; ...",
"openingHoursStructured": {
"monday": { "open": "11:00", "close": "22:00" },
"tuesday": { "open": "11:00", "close": "22:00" },
"wednesday": { "open": "11:00", "close": "22:00" },
"thursday": { "open": "11:00", "close": "22:00" },
"friday": { "open": "11:00", "close": "23:00" },
"saturday": { "open": "12:00", "close": "23:00" },
"sunday": { "open": "12:00", "close": "21:00" }
},
"latitude": 40.6892,
"longitude": -74.0445,
"placeUrl": "https://www.google.com/maps/place/...",
"websiteEnriched": false,
"websiteTitle": "Mama Joe's Pizza — Real New York Slices",
"websiteDescription": "Brooklyn's pizza institution since 1978. Order online for delivery.",
"qualityScore": 0.95,
"searchQuery": "pizza in Brooklyn",
"extractedAt": "2026-05-06T12:34:56Z"
}

Pricing — Pay Per Event (effective 2026-05-20)

Premium pricing reflects the higher cost of CAPTCHA solving and Firecrawl enrichment, charged only when those services actually deliver a result.

EventPriceWhen charged
actor-start$0.05Once per run
lead-extracted$0.02Per business pushed to dataset
email-verified$0.05Legacy event name; charged only when DNS returns a non-Null MX exchanger, not proof of deliverability
website-enriched$0.05Only when Firecrawl recovered fields the basic fetch missed

Realistic run costs

ScenarioCost breakdownTotal
100 leads, no enrichment$0.05 + 100 × $0.02$2.05
100 leads, 60 MX-checked email domains$0.05 + 100 × $0.02 + 60 × $0.05$5.05
100 leads, 60 MX-checked + 30 enriched$0.05 + 100 × $0.02 + 60 × $0.05 + 30 × $0.05$6.55

Compare to Google Places API: same 100 leads with phone, website, opening hours = ~$10-17 (depending on field-mask tier). Plus you must build the integration yourself.

Best Use Cases

  1. B2B sales prospecting — find local businesses by category and collect email candidates for separate mailbox-level validation before outreach.
  2. Agency lead-gen — identify businesses with weak online presence (no website, sparse hours, low rating) for SEO/web-design pitches.
  3. CRM enrichment — feed existing place URLs through Pro to add MX-checked email candidates, social profiles, and structured hours.
  4. Local market mapping — quantify competitor density, average rating, and price-level distribution by neighborhood.
  5. Lead qualification — combine phone, address, and MX-checked email candidates, then validate and review them before CRM import.
  6. Quality-filtered scraping — set qualityScore >= 0.7 to feed only complete records into your funnel.
  7. Recurring local-market monitoring — schedule weekly runs and watch new entrants/closures.

Programmatic Usage

Python

from apify_client import ApifyClient
client = ApifyClient("YOUR_TOKEN")
run = client.actor("tugelbay/google-maps-leads").call(run_input={
"searchQueries": ["dentists in Miami FL"],
"maxItems": 50,
"extractEmails": True,
"verifyEmailMx": True,
"firecrawlFallback": True,
})
mx_checked_leads = [
item for item in client.dataset(run["defaultDatasetId"]).iterate_items()
if item.get("emailVerified") and item.get("qualityScore", 0) >= 0.6
]
print(f"Got {len(mx_checked_leads)} high-quality leads with a non-Null MX record observed")

JavaScript / TypeScript

import { ApifyClient } from "apify-client";
const client = new ApifyClient({ token: "YOUR_TOKEN" });
const run = await client.actor("tugelbay/google-maps-leads").call({
searchQueries: ["plumber Chicago"],
maxItems: 100,
extractEmails: true,
extractSocialMedia: true,
verifyEmailMx: true,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
const mxChecked = items.filter(
(it) => it.emailVerified && (it.qualityScore ?? 0) >= 0.6,
);
console.log(`${mxChecked.length} leads with a non-Null MX record observed`);

LangChain tool

from langchain_core.tools import tool
@tool
def find_local_businesses(query: str, n: int = 25) -> list[dict]:
"""Find local businesses with contact data to validate before outreach."""
from apify_client import ApifyClient
client = ApifyClient("YOUR_TOKEN")
run = client.actor("tugelbay/google-maps-leads").call(run_input={
"searchQueries": [query],
"maxItems": n,
"extractEmails": True,
"verifyEmailMx": True,
"firecrawlFallback": True,
})
return [
it for it in client.dataset(run["defaultDatasetId"]).iterate_items()
if it.get("qualityScore", 0) >= 0.5
]

MCP (Apify MCP Server, Streamable HTTP)

npx mcpc connect mcp.apify.com
npx mcpc call tugelbay/google-maps-leads --json '{"searchQueries":["coffee Atlanta"],"maxItems":20}'

FAQ

Q: How does the Actor handle Google blocking? A: It supports Apify proxies and optional 2Captcha/CapSolver recovery when configured. Challenges, target changes, quotas, or provider failures can still end a search with fewer rows or an error, so validate a small run before scaling.

Q: Why an MX check instead of a full SMTP probe? A: SMTP probes are slow and often refused by receiving servers. This check only records a published non-Null MX exchanger; it does not prove that the domain or individual mailbox accepts mail. Use a dedicated consent-aware validation service when mailbox-level evidence is required.

Q: When does websiteEnriched get charged? A: Only when the basic httpx fetch returned no email and Firecrawl rescue actually retrieved new data. If both fail or basic fetch worked, no website-enriched event fires.

Q: What if my business doesn't list a website on Google Maps? A: You still get name, phone, address, hours, rating, coordinates. email, socialMedia, and websiteEnriched will be null. The lead is still useful — phone-based outreach.

Q: How many leads can I extract per run? A: The input schema allows 1-500 places per query. Total runtime and output depend on query count, target responses, proxy/solver behavior, enrichment settings, memory, and Apify platform limits; start with 10 and measure your own workload before scaling.

Q: Does it work outside the US? A: Yes. Address parsing is best for US ("Street, City, ST ZIP" pattern); international addresses appear in address but city/state/postalCode may be null. All other fields work globally. Set language to your locale's ISO 639-1 code (es, de, ru, ar, etc.).

Q: Can I schedule recurring runs? A: Yes — Apify Schedules. Common patterns: weekly per-city refresh, daily for hot markets, hourly for new-listing detection on a specific category.

Q: What about Google's Terms of Service? A: The Actor is limited to public pages and does not use Google account credentials or private owner fields. Public visibility is not permission for every downstream use: review Google's current terms, privacy/marketing law, consent requirements, and your jurisdiction before collection or outreach.

Q: Why not just use the Google Places API? A: Use the official Places API when you need a supported first-party integration, stable documented fields, and official quota handling. Use this Actor when you specifically need an Apify Dataset, scheduling/MCP integration, and optional public-website enrichment in one workflow. Compare current pricing and terms before choosing.

Troubleshooting

Empty dataset returned

  • Check that searchQueries or placeUrls is set (run will fall back to a demo query and warn).
  • Try a different region — some niches have very few Google Maps listings.
  • Set maxConcurrency: 1 to slow down and avoid being rate-limited.

Low emailVerified rate

  • Many small-business websites use contact forms instead of mailto links — emails simply aren't on the page.
  • Disable verifyEmailMx to keep raw emails (you'll get more results but need to validate downstream).
  • Enable firecrawlFallback if not already — recovers emails from JS-rendered/anti-bot-protected sites.

CAPTCHA logs but no 2captcha solves logged

  • The TWOCAPTCHA_API_KEY env var must be set on the actor (Console → Settings → Environment variables, marked Secret).
  • Check your 2Captcha balance: https://2captcha.com/enterpage
  • CapSolver (CAPSOLVER_API_KEY) acts as fallback if 2Captcha returns no token.

Run took too long

  • Drop maxItems, raise maxConcurrency (cap is 10).
  • Disable extractEmails/extractSocialMedia for the first scoping run, then re-run with enrichment on confirmed targets.

Validation evidence and Google terms (2026-07-14)

Validation on 2026-07-14 establishes a public-source and enrichment boundary:

  • Google's Maps Platform Terms describe licensing, customer obligations, privacy, and use restrictions for official Maps services.
  • Google's Terms of Service remain authoritative for Google surfaces; this independent Actor is not a Google Places API client or Google-endorsed product.
  • Results retain place URLs, search query, validation/enrichment flags, quality score, and extractedAt for source checks.
  • Strict Actor QA validates schemas, links, metadata, Docker configuration, enrichment defaults, and PPE declarations before release.

Users must follow current terms, privacy/marketing law, consent rules, and suppression lists. This evidence does not verify contact ownership, guarantee deliverability, rankings, sales, or AI citations.

Support

Send the run ID, sanitized keyword/location, public place URL, enabled enrichment options, expected field, observed row, and visible error. Do not send credentials, solver keys, cookies, or private lead lists.

Limitations

  • Email enrichment only works when the business website lists an email. No magic — if a business uses a contact form, the email isn't there.
  • A non-Null MX record is only a routing signal. The domain or mailbox can still reject mail. For deeper validation, pipe email through NeverBounce / ZeroBounce after this run.
  • Opening-hours parser handles common formats. "Mon-Fri 9-5", "Monday: 9 AM-5 PM", "Open 24 hours", "Closed". Exotic formats (e.g., "Shabbat Closed") fall back to null for that day; the raw text remains in openingHours.
  • CAPTCHA handling is best-effort. Solver providers, challenge types, target changes, and proxy reputation can still leave a run blocked or incomplete.
  • No reviews extracted. This actor focuses on the place's metadata + contact info. For reviews, use a dedicated reviews scraper.

See all actors: apify.com/tugelbay

Verification update — 2026-09-05

The candidate contact discovery follows up to three pages on the business website (20 seconds total). MX selection has a separate 20-second total budget, prefers a positive domain signal, and retains an inconclusive candidate without marking it verified. Two live London agency leads produced two email-verified events. Firecrawl charges require a new saved email, social link, title, or description; an empty response or an email rejected by MX alone does not qualify.

Changelog

  • 3.0 (2026-05-06) — Premium rebrand. CAPTCHA bypass via 2Captcha + CapSolver, MX-checked email domains, Firecrawl fallback for website enrichment, structured opening-hours JSON, per-record quality score, premium PPE pricing scheduled for 2026-05-20.
  • 2.0 (2026-04-24) — Fixed proxy support for browser, retry logic, race condition fix.
  • 1.0 (2026-04-15) — Initial release: Google Maps search + place extraction with optional email/social enrichment.