# Google Maps Scraper + Emails, Socials & WhatsApp – All-In-One (`locomint/locomint-places`) Actor

Scrape Google Maps places worldwide with business emails, social profiles, WhatsApp, phone, website, rating & tech stack included. One flat price for every plan, no add-ons. Built for lead generation, local SEO and CRM enrichment.

- **URL**: https://apify.com/locomint/locomint-places.md
- **Developed by:** [Umaid Ali](https://apify.com/locomint) (community)
- **Categories:**
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.50 / 1,000 result delivereds

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## Google Maps Scraper + Emails, Socials & WhatsApp – All-In-One

Search any business category in any city worldwide and get **clean, complete
business records** – name, address, coordinates, phone, website, rating, review
count, opening status – **with website enrichment included**: business emails,
social profiles, WhatsApp, contact page and tech stack.

**One price per place. Every field included. No add-ons. Same price on every plan.**

```json
{
  "searchStringsArray": ["dentist", "orthodontist"],
  "locationQuery": "Toronto, Canada",
  "maxCrawledPlacesPerSearch": 100
}
```

Give it a search term and a city – get a lead list you can use, not a lead list
you have to pay extra to complete.

***

### 🎯 What can you do with it?

- **Lead generation** – build prospect lists of businesses by category and city
  with phone, email, WhatsApp and social profiles ready for outreach.
- **Local SEO & agencies** – audit every competitor in a niche: ratings, review
  counts, whether they have a website, what it's built on.
- **CRM enrichment** – match your existing accounts to phone, website, email,
  socials and tech stack.
- **Market research** – density, ratings and price level of a category across
  any city on earth.
- **AI agents & automations** – structured JSON that drops straight into n8n,
  Make, Zapier, Clay or your own code via the Apify API.

***

### 📦 What data do you get for every place?

| Group | Fields |
|---|---|
| **Identity** | `name`, `place_id`, `cid`, `categories`, `primary_category`, `description` |
| **Location** | `address`, `street`, `city`, `region`, `postal_code`, `country_code`, `lat`, `lng`, `plus_code`, `timezone` |
| **Contact** | `phone`, `phone_e164`, `website` |
| **Reputation** | `rating`, `review_count`, `price_level` |
| **Status & hours** | `status` (open / temporarily closed / permanently closed), `open_now`, `hours` (weekly schedule), `service_area_business` |
| **Extras** | `photos_count`, `photo_urls`, `attributes` (wheelchair access, delivery, dine-in, …) |
| **✨ Enrichment (included)** | `emails[]`, `socials{facebook, instagram, linkedin, x, youtube, tiktok}`, `whatsapp`, `contact_form_url`, `tech_stack[]`, `website_status` |

Everything comes back normalized: E.164 phone numbers, ISO country codes, the
same field names in Tokyo, Lagos, São Paulo and Berlin.

***

### 🧾 Example output

A real record from a run for `restaurant` in `Lisbon, Portugal`:

```json
{
  "place_id": "ChIJ…",
  "name": "Belcanto",
  "primary_category": "Fine dining restaurant",
  "categories": ["Fine dining restaurant", "Portuguese restaurant", "Restaurant"],
  "address": "Largo de São Carlos 10, 1200-410 Lisboa, Portugal",
  "city": "Lisbon",
  "country_code": "PT",
  "lat": 38.7099,
  "lng": -9.1418,
  "phone": "+351 21 342 0607",
  "phone_e164": "+351213420607",
  "website": "https://belcanto.pt/",
  "rating": 4.6,
  "review_count": 6697,
  "status": "open",
  "open_now": true,
  "timezone": "Europe/Lisbon",
  "emails": ["belcanto@belcanto.pt", "press@belcanto.pt", "work@belcanto.pt"],
  "socials": {"instagram": "https://www.instagram.com/belcantolisboa", "facebook": "https://www.facebook.com/belcantolisboa"},
  "whatsapp": null,
  "contact_form_url": "https://belcanto.pt/contact/",
  "tech_stack": ["wordpress", "react", "google-analytics"],
  "website_status": "ok",
  "service_area_business": false
}
```

Records with no website are reported honestly (`website_status: "no_website"`)
rather than padded. Businesses whose "website" is a Facebook or Instagram page
are flagged `redirect_social` with the profile captured.

***

### ▶️ How to use it

1. Click **Try for free** – no card, no setup.
2. Type one or more **search terms** (`dentist`, `coffee shop`, `car rental`, …).
3. Type the **location** – always with the country: `Warsaw, Poland`, not `Warsaw`.
4. Set **max places per search** (up to 500 per term).
5. **Start.** Results stream into the dataset as they're found. Export as
   JSON, CSV, Excel, or pull them through the API.

Every Apify account comes with free monthly platform credit – enough to try
this actor on a few thousand places before paying anything.

***

### ⚙️ Input

| Field | Type | Default | Notes |
|---|---|---|---|
| `searchStringsArray` | string\[] | – | One or more search terms, searched separately. Alias: `keyword` |
| `locationQuery` | string | – | City, area or address **with country**. Alias: `location` |
| `maxCrawledPlacesPerSearch` | integer | 20 | Up to 500 per term. Alias: `resultPerKeyword` |
| `includeDetails` | boolean | true | Description, plus code, timezone, photos, attributes |
| `includeEnrichment` | boolean | true | Visit each business website for contacts and tech stack |
| `language` | string | `en` | Any BCP-47 code – names and categories come back localized (`ar`, `de`, `ja`, …) |
| `placeIds` | string\[] | – | Skip searching: paste place IDs (`ChIJ…`) and get the full enriched record for each. Up to 1,000 per run |
| `includeNearbyPlaces` | boolean | false | Keep results that fall outside the resolved city area (off by default – they are usually a same-name town elsewhere) |

#### Filters – all free

Other scrapers charge $1 per 1,000 places for *each* filter. Here they are free,
and a place that is filtered out is never fetched, so it never costs you anything.

| Field | Type | Default | Notes |
|---|---|---|---|
| `placeMinimumStars` | string | – | `"4"`, `"4.5"`, … Places without a rating are skipped |
| `websiteFilter` | string | `any` | `with` (only businesses with a website) or `without` (great for web-design outreach) |
| `skipClosedPlaces` | boolean | false | Drop temporarily and permanently closed places |
| `categoryFilterWords` | string\[] | – | Keep only places whose category contains one of these words |
| `searchMatching` | string | `all` | `only_includes` / `only_exact` – place name must include / equal the search term (brand searches) |

**Switching from another Google Maps scraper?** The input names above are the
ones you already use. Paste your existing input and run.

***

### 💰 Pricing – one number

| | Locomint | Typical Google Maps actors |
|---|---|---|
| Place record | **$1.50 / 1,000** | $1.50–$4.90 / 1,000 depending on *your* Apify plan |
| Details (description, hours status, photos, attributes) | **included** | +$1.05–$30.00 / 1,000 |
| Website contacts (emails, socials, WhatsApp) | **included** | +$0.50–$2.00 / 1,000 |
| Complete record, free-plan user | **$1.50** | **$7.50–$34.90** |

No per-filter fees. No per-detail fees. No "Business plan discount" you have to
pay $499/month to unlock. Nothing is charged for a search that returns nothing.

***

### 🛡️ What we deliberately don't do

- **No personal data.** We extract role mailboxes (`info@`, `sales@`,
  `reservations@`), company social pages and WhatsApp business lines – never
  people's names, personal emails, job titles or LinkedIn profiles. Safer for
  you under GDPR/UK GDPR, and it's the right thing to do.
- **No fake completeness.** Missing website, unreachable site, parked domain –
  each is reported as what it is.

***

### 🗺️ Whole-city coverage

A single map search stops at a couple of hundred results however big the city
is. Ask for more and the actor tiles the city into a grid and searches every
cell, deduplicating as it goes — 500 unique restaurants in Lagos in under 30
seconds. Results that drift outside the requested area (a different city with
the same name) are dropped, not delivered.

### 📈 Reliability you can check

A canary suite runs every day: 30 cities on every continent, every business
category we support, through the same code path customers use. The result feeds
a public status page. Layout changes upstream are caught by 200+ fixture-backed
tests before they reach a run.

***

### 🔌 Integrations

Run it from the Apify Console, on a **schedule**, or from anywhere:

- **API** – Python, JavaScript, cURL (see the *API* tab)
- **n8n, Make, Zapier** – via the Apify integration
- **Google Sheets, Slack, webhooks** – Apify integrations
- **MCP** – use it as a tool from AI agents
- **Hosted REST API** – need answers in under three seconds inside your own app?
  The same data is available as an API at [locomint.io](https://locomint.io).

***

### ❓ FAQ

**How fast is it?**
Roughly 20 places per minute with details and enrichment on. That's deliberate:
the request rate is kept conservative so the data path stays healthy for
everyone. Turn off `includeEnrichment` for faster, contact-free runs.

**Does it work outside the US and Europe?**
Yes – it's verified daily in 30 cities across Asia, Africa, the Middle East,
Latin America and Oceania, in Latin, Arabic, CJK and other scripts.

**Are weekly opening hours included?**
Yes – `hours` carries the full weekly schedule (`open`/`close` in 24-hour time, `24:00`
for midnight, next-day closings like `01:00` as-is), plus `open_now` and closure status.

**Can I get reviews?**
The hosted API at locomint.io serves the first page of reviews per place. A dedicated
reviews actor with full paging is in progress.

**Why do some records have no email?**
Because the business's website doesn't publish one, or the business has no
website. We report what's there; we never guess or buy addresses.

**Is this legal?**
The actor reads publicly available business listings and business websites –
the same pages any visitor sees, with no login. It never bypasses access
controls. You are responsible for how you use the data; see the
[Apify terms](https://apify.com/terms) and your local law. Business owners
can request removal at hello@locomint.io.

***

### 🧑‍💻 Support

Questions, missing fields, a city that behaves oddly – open an issue on the
*Issues* tab or write to **hello@locomint.io**. Response within one working day.

*Locomint is not affiliated with Google. Data is provided as-is from public sources.*

# Actor input Schema

## `searchStringsArray` (type: `array`):

What to look for - one or more categories or business names, e.g. "dentist", "coffee shop", "car rental". Each term is searched separately. Up to 25 per run.

## `locationQuery` (type: `string`):

City, area or address. Always add the country for unambiguous results: "Warsaw, Poland" rather than "Warsaw".

## `maxCrawledPlacesPerSearch` (type: `integer`):

Upper limit of places to collect for each search term. You are charged per place delivered. Large asks sweep the whole city automatically.

## `placeIds` (type: `array`):

Already have a list? Paste place IDs (ChIJ...) and get the full record with enrichment for each - no search needed. Up to 1,000 per run.

## `placeMinimumStars` (type: `string`):

Only deliver places rated at least this. Places without a rating are skipped. Free - filtered places are not charged.

## `websiteFilter` (type: `string`):

Only places with a website (good for enrichment) or only places without one (good for web-design outreach).

## `skipClosedPlaces` (type: `boolean`):

Leave out places marked temporarily or permanently closed.

## `categoryFilterWords` (type: `array`):

Keep only places whose category contains at least one of these words, e.g. \["dentist", "orthodontist"]. Case-insensitive.

## `searchMatching` (type: `string`):

Restrict results by how the place name relates to the search term. Useful when searching for a brand.

## `includeNearbyPlaces` (type: `boolean`):

By default, results outside the resolved city area are dropped (they are usually a different place with the same name). Turn on to keep them.

## `includeDetails` (type: `boolean`):

Adds description, weekly opening hours, plus code, timezone, photos and attributes for each place. Included in the price.

## `includeEnrichment` (type: `boolean`):

Visits each business's own website to extract business emails, social profiles, WhatsApp, contact page and tech stack. Included in the price. Never collects personal data.

## `language` (type: `string`):

BCP-47 language for names and categories (en, ar, de, ja, ...).

## Actor input object example

```json
{
  "searchStringsArray": [
    "restaurant"
  ],
  "locationQuery": "Lisbon, Portugal",
  "maxCrawledPlacesPerSearch": 5,
  "placeMinimumStars": "",
  "websiteFilter": "any",
  "skipClosedPlaces": false,
  "searchMatching": "all",
  "includeNearbyPlaces": false,
  "includeDetails": true,
  "includeEnrichment": true,
  "language": "en"
}
```

# Actor output Schema

## `places` (type: `string`):

One record per business: identity, location, contact, reputation, status and website enrichment.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "searchStringsArray": [
        "restaurant"
    ],
    "locationQuery": "Lisbon, Portugal",
    "maxCrawledPlacesPerSearch": 5
};

// Run the Actor and wait for it to finish
const run = await client.actor("locomint/locomint-places").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "searchStringsArray": ["restaurant"],
    "locationQuery": "Lisbon, Portugal",
    "maxCrawledPlacesPerSearch": 5,
}

# Run the Actor and wait for it to finish
run = client.actor("locomint/locomint-places").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "searchStringsArray": [
    "restaurant"
  ],
  "locationQuery": "Lisbon, Portugal",
  "maxCrawledPlacesPerSearch": 5
}' |
apify call locomint/locomint-places --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,locomint/locomint-places"
        }
    }
}

```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/eUOu1I05F99P2GLFc/builds/4PmP7qx38fSwDhgZh/openapi.json
