Google Maps Lead Cleaner: Dedupe, Remove Fake & Closed Listings
Pricing
from $2.50 / 1,000 cleaned lead rows
Google Maps Lead Cleaner: Dedupe, Remove Fake & Closed Listings
Clean Google Maps data: dedupe leads, remove fake lead-farm listings, closed businesses and off-category results, merge duplicates, format phones from any country, optionally return only new leads. $0.0025 per cleaned kept lead; dropped rows free. Plus platform usage.
Pricing
from $2.50 / 1,000 cleaned lead rows
Rating
0.0
(0)
Developer
Callback Local
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
3 days ago
Last modified
Categories
Security
Limited permissionsShare
What does Google Maps Lead Cleaner do?
Google Maps Lead Cleaner removes fake listings (lead farms), duplicates and closed businesses from your Google Maps leads. Give it Google Maps Scraper results and get back only real, open businesses in your category.
It also drops off-category results, standardizes phone numbers from any country to E.164 and adds sales flags. Pricing is $0.0025 USD per cleaned kept lead (pay per event). Dropped rows and already-seen (history) leads are not charged. You also pay normal Apify platform usage for the run.
Use it to clean Google Maps data, dedupe Google Maps leads and remove fake listings before they reach your CRM or cold-calling list. It does not scrape Google itself. It cleans data you already have, so it works as a filter step after any Google Maps scraping run, from the Apify Console, the API, a schedule or an AI agent.
Tested on real data from two trades in two areas of the Atlanta metro. See the limits section before relying on it at scale.
Try it in one click: the input form comes prefilled with 8 made-up demo listings. Press Start and see 8 rows become 3 leads: a duplicate merged, a closed shop and 3 fake look-alike listings dropped. Add
Plumberto Target categories and the off-category auto shop goes too, leaving 2.
⭐ Found this useful? A quick review on the Apify Store helps a lot. Leave a review
Why use Google Maps Lead Cleaner?
When you search Google Maps for a trade in a small area, Google does not stop at real matches. It pads the list with whatever is nearby: auto shops, suppliers, construction companies, even software companies. A scraper copies that padding faithfully.
We tested this on real data:
- Sandy Springs, GA plumbers: three searches returned 94 businesses. Only 26 were plumbers. 68 (72%) were off-category junk.
- Marietta, GA HVAC: two searches returned 100 businesses. 53 were off-category, and 9 were mass-made fake listings such as "Halcy HVAC Repair Marietta", "Gravix HVAC Repair Marietta" and "Metric HVAC Repair Marietta": the same name pattern, near-sequential phone numbers, no website, almost no reviews.
What you get:
- 🎯 Category filter: say
["Plumber"]and only plumbers stay. - 🚪 Closed filter: permanently or temporarily closed businesses are removed by default.
- 🕵️ Fake-listing (lead farm) filter: batches of look-alike, no-website, no-review listings are removed or flagged.
- 🆕 Only new leads since your last run: skip businesses you already received. Weekly repeat pulls return only what is new.
- 🧹 Cleanup: merges duplicate listings, formats phones from any country (
+14045551234and(404) 555-1234, or+442079460018and+44 20 7946 0018) and flagsno_website,unclaimed_profile,low_reviews,out_of_area_phone. - ⚙️ Apify platform: schedules, API, webhooks, integrations and monitoring come built in.
Real results: 94 rows → 25 open plumbers (Sandy Springs) and 100 rows → 36 real HVAC leads, with all 9 fake listings caught and no real company caught (Marietta). With history on, a repeat Sandy Springs pull delivered 10 new leads and skipped 15 already seen.
What data does Google Maps Lead Cleaner output?
One row per real business:
| Field | Type | Description |
|---|---|---|
title | string | Business name |
phoneE164 | string | Phone in E.164, for example +17704218400 |
phoneDisplay | string | Phone formatted for people, for example (770) 421-8400 |
website | string | Real website (Facebook, Instagram and Yelp pages do not count) |
address, city | string | Address from Google Maps |
categoryName | string | Google's main category |
reviewsCount, totalScore | number | Review count (highest across merged listings) and rating |
flags | array | Sales flags, see below |
placeIds | array | Google place IDs merged into this lead |
duplicateCount | number | How many extra listings were merged in |
isNew | boolean | Present when "Only new leads" is on |
Also: phoneExt, phoneCountry (two-letter country of the phone), otherPhones, url, sourceRowIndexes, and leadFarmReason (flag mode only).
Flags
| Flag | Meaning |
|---|---|
no_website | No real website |
unclaimed_profile | The owner has not claimed the Google profile |
low_reviews | Fewer reviews than your threshold (default 10) |
invalid_phone | No usable phone number |
out_of_area_phone | US only: area code belongs to another state than the listing (often a national call center; check it, it is not proof of anything). Toll-free and non-US numbers are never flagged |
off_category | Only in flag mode: not in your target categories |
lead_farm_suspect | Only in flag mode: part of a batch of look-alike fake listings |
permanently_closed / temporarily_closed | Only when Drop closed is off |
How to clean Google Maps data
- Run the Google Maps Scraper as usual.
- Start Google Maps Lead Cleaner and paste the scraper items into Listings, or give it the scraper run's Dataset ID.
- Set Target categories, for example
PlumberorHVAC contractor,Air conditioning contractor. Matching is case-insensitive and partial, against Google'scategoryNameandcategories. - Optional: turn on Only new leads since my last run and give the list a History key, for example
atlanta-plumbers. - Run it. The run status tells you what was kept and dropped, for example:
Cleaned 100 listings into 36 leads. Dropped: 1 closed, 53 off-category, 9 suspected fake listings. - Download the clean leads as JSON, CSV, Excel or HTML, or read them with the API.
Clean Google Maps data automatically after every scrape
Skip the copy and paste. Chain the cleaner to your scraper once and every scrape comes back clean.
- Open your Google Maps Scraper Actor or saved task in Apify Console and go to the Integrations tab.
- Add an Actor integration, pick Google Maps Lead Cleaner and choose the event Run succeeded.
- In the cleaner's input, set Dataset ID to
{{resource.defaultDatasetId}}(Apify swaps in the scraper run's dataset each time), then set your Target categories and other options. Leave Listings empty. - Save. From now on, each successful scraper run starts the cleaner on that run's results.
Tip: pair it with Only new leads since my last run and a History key on a scheduled scraper task, and each run delivers only businesses you have not seen before.
Integration input example:
{"datasetId": "{{resource.defaultDatasetId}}","targetCategories": ["Plumber"],"onlyNewSinceLastRun": true,"historyKey": "atlanta-plumbers"}
How much does it cost to clean Google Maps data?
$0.0025 USD per cleaned kept lead (pay per event). You are charged once for each lead delivered to the output dataset.
- Dropped rows (closed, off-category, suspected fake, no phone) are not charged.
- Already-seen leads skipped by history ("Only new leads since my last run") are not charged.
- You also pay normal Apify platform usage for the run (compute and storage). That is usually tiny because the Actor only processes data you already have.
- There is also a tiny Actor Start event ($0.00005) when the run begins.
- The Google Maps Scraper bills separately for its own run.
Input
See the Input tab for every option. The main ones:
| Input | Default | What it does |
|---|---|---|
Listings (items) | 8 demo listings (prefill) | Paste Google Maps Scraper items. Use this or Dataset ID. A Dataset ID wins if both are set |
Dataset ID (datasetId) | none | Dataset from a Google Maps Scraper run |
Target categories (targetCategories) | empty (keep all) | Categories to keep, for example ["Plumber"] |
Off-category leads (categoryMode) | drop | drop removes them, flag keeps them with off_category |
Drop closed businesses (dropClosed) | on | Removes permanently or temporarily closed listings |
Drop leads with no phone (dropNoPhone) | off | Removes leads without a valid phone |
Default phone country (defaultCountry) | US | Country for numbers written without +, for example GB. Each listing's own countryCode wins |
Suspected fake listings (leadFarmMode) | drop | drop removes them, flag keeps them with lead_farm_suspect, off skips the check |
Only new leads since my last run (onlyNewSinceLastRun) | off | Skips businesses already delivered under the same History key |
History key (historyKey) | default | One history per list, for example atlanta-plumbers |
Low reviews threshold (lowReviewsThreshold) | 10 | Fewer reviews than this gets low_reviews |
Merge near-duplicate listings (mergeNearDuplicates) | on | The same business listed twice becomes one lead |
Example:
{"datasetId": "YOUR_GOOGLE_MAPS_SCRAPER_DATASET_ID","targetCategories": ["Plumber"],"leadFarmMode": "drop","onlyNewSinceLastRun": true,"historyKey": "sandy-springs-plumbers"}
Output
You can download the dataset in various formats such as JSON, HTML, CSV, or Excel. Example rows:
[{"title": "Coolray Heating & Air Conditioning","phoneE164": "+17704218400","phoneDisplay": "(770) 421-8400","website": "https://www.coolray.com/","categoryName": "Air conditioning contractor","reviewsCount": 11254,"flags": [],"duplicateCount": 0,"isNew": true},{"title": "Eardley's Inc","phoneE164": "+17706350111","phoneDisplay": "(770) 635-0111","website": null,"categoryName": "HVAC contractor","reviewsCount": 1,"flags": ["no_website", "unclaimed_profile", "low_reviews"],"duplicateCount": 0,"isNew": true}]
How the fake-listing (lead farm) check works
A lead is weak when it has no real website and fewer reviews than your low reviews threshold. Two weak leads are linked when they have near-sequential phones (same area code and exchange, last 4 digits within 20 of each other; outside North America, same number except the last 4 digits; toll-free ignored) or the same name template (identical name after the first word, with the city in it or the same phone exchange, for example * HVAC Repair Marietta). A connected group of 3 or more weak leads is a suspected lead farm. Leads with a real website or many reviews are never linked, so real multi-location brands and franchises are not caught. Use flag mode to review suspects instead of dropping them.
New leads since your last run
History lives in a named key-value store in your own Apify account, maps-lead-cleaner-history, one record per History key (record name history-<key>). It holds only match keys: each Google place ID plus a backup key of normalized phone and name, for listings whose place ID changed. Only leads actually delivered are added, so if a run is cut short, the rest still count as new next time. To start over, use a new History key or delete that record. Named stores are kept until you delete them and use a little of your Apify storage.
Limits (honest version)
- It trusts Google's categories. If Google labels a plumber as "Contractor", a
Plumberfilter drops it, and if Google labels a car AC shop as "Air conditioning repair service", an HVAC filter keeps it. Add more target categories if your trade uses several labels. - The fake-listing check needs a batch. It catches groups of 3 or more look-alikes. A lone fake, or fakes with real-looking websites and reviews, can get through. A real tiny business that sits inside such a batch would be caught too.
- The out-of-area phone check is US only. It uses a static US area-code map, so a business that kept an out-of-state number after moving gets flagged too. Phones from other countries are cleaned and formatted, but not checked for area.
- Tested on two trades in two areas so far: Sandy Springs, GA plumbers (20 and 94 listings) and Marietta, GA HVAC (100 listings), plus synthetic test sets. Results elsewhere may differ.
- Duplicates are rare inside one scraper run, because the Google Maps Scraper already removes repeats. Merging matters most when you combine several runs or datasets.
- History is per Apify account and per History key.
- Not a scraper. You need Google Maps Scraper output first.
FAQ
How much does it cost?
$0.0025 USD per cleaned kept lead (pay per event). Dropped rows and already-seen (history) leads are not charged. You also pay normal Apify platform usage for the run, plus a tiny Actor Start event ($0.00005).
How do I remove duplicates from Google Maps results?
Paste your scraper results into Listings, or set Dataset ID to the scraper run's dataset. Keep Merge near-duplicate listings on (the default). The Actor merges the same business listed twice into one lead and keeps the best phone, website and review count. Chain it after your scraper so every scrape comes back deduped.
How do I find / remove fake Google Maps listings?
Set Suspected fake listings to drop (default) to remove them, or flag to keep them tagged as lead_farm_suspect so you can review. The check looks for batches of look-alike, no-website, low-review listings with near-sequential phones or the same name template. Real businesses with a website or many reviews are not linked into those groups.
How do I clean Google Maps data after a scrape?
Run your Google Maps scraper as usual, then start this Actor with that run's Dataset ID, or chain it under Integrations so every successful scrape starts the cleaner automatically (see "Clean Google Maps data automatically after every scrape" above). Set your Target categories and download the clean leads as JSON, CSV, Excel or HTML.
Which scrapers does it work with?
Any Google Maps scraper whose output has the usual place fields. It was built on compass/crawler-google-places output and also reads the output of compass/google-maps-extractor, vortex_data/google-maps, scraperlink/google-maps-scraper and scrapesage/google-maps-scraper. Pass the scraper run's Dataset ID, or chain it as shown above.
Data from other tools or a CSV export works too. Common alternative field names are read automatically, for example name for title, phoneNumber or phones for phone, place_id for placeId, category for categoryName, rating and ratingCount for the score and review count, formattedAddress for address, and businessStatus: CLOSED_PERMANENTLY for closed businesses.
I want to see what was removed instead of dropping it.
Set Off-category leads to flag, Suspected fake listings to flag, and turn off Drop closed businesses. Everything is kept and tagged.
Can I use it from an AI agent or the Apify API?
Yes. See the API tab. Anything that can start an Apify run with JSON input can use it.
Does it contact the businesses?
No. It only cleans and returns data.
Privacy and data
Each run saves a small RUN_SIGNALS record to your own run's key-value store (run id, input and output size, duration and a hash of the input, no lead data) for abuse checks. It is not sent anywhere else.
This Actor does not scrape anything. It only reads the listings you give it and returns a cleaned copy to your own Apify storage. Your input may already contain personal data, for example a sole trader's name or mobile number. You are responsible for having a lawful reason to keep and use it under GDPR, CCPA and similar laws.
Feedback
Found a wrong drop or a fake that got through? Open an issue in the Issues tab with the listing name and city.
Changelog
Nov 4, 2026 (build 0.3.9)
- Pricing is live at $0.0025 USD per cleaned kept lead (pay per event). README, listing and cost FAQ updated to match. Dropped and already-seen rows stay free.
- FAQ expanded in buyers' words: remove duplicates, find/remove fake listings, clean Google Maps data after a scrape.
- Field aliases for other scrapers' column names shipped in 0.3.8 (Nov 2):
name,phoneNumber,place_id,category,rating,formattedAddress,businessStatusand more.