# Google Maps Email Extractor — AI Lead Qualifier & Enrichment (`dltik/google-maps-email-extractor`) Actor

Turn Google Maps places or any website list into qualified B2B leads: verified emails (SMTP), decision makers, WhatsApp, French company registry (SIREN/NAF/BODACC), deterministic lead intelligence (grade, lifecycle, outreach verdict) + optional AI outreach drafts. HTTP-only — no residential proxy.

- **URL**: https://apify.com/dltik/google-maps-email-extractor.md
- **Developed by:** [Walid](https://apify.com/dltik) (community)
- **Categories:** Lead generation, Marketing
- **Features:** Limited permissions
- **Stats:** 74 total users, 3 monthly users, 100.0% runs succeeded, 2 bookmarks
- **User rating**: No ratings yet

## Pricing

from $20.00 / 1,000 lead enriched & qualifieds

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?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
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.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## 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.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Google Maps Email Extractor — AI Lead Qualifier & Enrichment

Extract and **verify** business emails from **Google Maps** — or from any website list — and get back **qualified leads, not raw rows**. This Google Maps email extractor crawls each business website for emails, phones, socials and **decision makers**, verifies deliverability by **SMTP**, cross-links French businesses to the **official company registry (SIREN/BODACC)**, and scores every lead with a deterministic **outreach verdict** (send-now / verify-first / enrich-first / nurture / skip). Optional AI writes a ready-to-send outreach draft.

**HTTP-only — no residential proxy, no browser.** Point it at Google Maps search queries, a list of websites, or the dataset of any Google Maps scraper (e.g. `compass/crawler-google-places`) and enrich thousands of places reliably.

> ⭐ **Found this useful?** Click the **Bookmark** button at the top of [this actor](https://apify.com/dltik/google-maps-email-extractor) — it keeps the tool visible to others who need it. One click, no signup beyond your Apify account.

***

### Why this Google Maps email extractor?

Most Google Maps scrapers hand you a CSV of names and phone numbers. This one hands your sales team **decisions**: who to contact, with which email, verified, with a personalised angle — and, for French leads, whether the company is even solvent.

| Feature | This actor | compass (Maps Scraper) | commodity email extractors |
|---|---|---|---|
| Google Maps data | Yes (or chain any scraper) | Yes | Yes |
| Website email extraction | Yes — 6 techniques | Add-on | Yes |
| **SMTP deliverability verification** | **Yes** | No | Rare |
| **Decision-maker discovery** | **Yes** (name/title/LinkedIn) | No | No |
| **French registry (SIREN/NAF/BODACC)** | **Yes** | No | No |
| Deterministic lead intelligence | grade + lifecycle + **verdict** | No | No |
| AI outreach drafts + ICP scoring | Yes (premium) | No | No |
| Residential proxy required | **No** | Varies | Varies |

You don't have to choose between this and the market-leading scraper: run [compass/crawler-google-places](https://apify.com/compass/crawler-google-places) for raw places, then pass its `datasetId` here to add the whole intelligence layer on top.

***

### Three ways to use it

1. **Google Maps search** (`mode: search`) — give keyword + location queries (`"dentist Lyon"`). HTTP-only Maps search, no browser.
2. **Your website list** (`mode: websites`) — already have domains? Enrich them directly with emails, decision makers, verification and intelligence.
3. **Chain from a Google Maps scraper** (`mode: datasetId`) — the most reliable at scale. Run any Google Maps scraper, then pass its finished `datasetId`; we read the places and enrich every one.

#### Quick start — search + French registry

```json
{
  "mode": "search",
  "queries": ["dentist Lyon", "plumber Paris 11"],
  "maxResultsPerQuery": 20,
  "emailDepth": "deep",
  "verifyEmails": true,
  "checkRegistry": true,
  "checkBodacc": true
}
```

#### Enrich an existing Google Maps scrape (chain from compass)

```json
{
  "mode": "datasetId",
  "datasetId": "PASTE_COMPASS_RUN_DATASET_ID",
  "verifyEmails": true,
  "findDecisionMakers": true
}
```

#### Premium AI qualification + outreach drafts

```json
{
  "mode": "websites",
  "websites": ["acme-salon.fr", "https://studio-beaute.fr"],
  "analyzeLeads": true,
  "businessProfile": "We sell online-booking software to independent French beauty salons."
}
```

***

### What data you get per lead

| Field | Source | Description |
|---|---|---|
| `name`, `address`, `phone`, `category`, `rating`, `reviews_count`, `latitude`, `longitude` | Maps / dataset | Core business data |
| `website`, `google_maps_url`, `place_id` | Maps / dataset | Identifiers |
| `primary_email`, `emails`, `generic_emails`, `personal_emails` | Website crawl | Ranked, classified emails |
| `email_source`, `email_quality` | Computed | mailto / schema.org / regex / contact_page + high/medium/low |
| `verification` | SMTP/DNS | `{status, mx, smtp_checked, catch_all, disposable, role}` |
| `decision_makers` | Team/about crawl | `[{name, title, email, linkedin, source}]` |
| `phones`, `socials`, `has_whatsapp` | Website / wa.me | Reach channels |
| `tech_stack`, `digital_signals` | Website | Shopify/WordPress/Meta Pixel…, booking/ecommerce/ads flags |
| `website_quality_grade` | Computed | A–F site maturity |
| `business_lifecycle_stage` | Computed | new / growing / established / mature / declining / dormant |
| `lead_archetype`, `momentum` | Computed | franchise / digital_native / solo_operator… |
| `opportunity_signals`, `likely_objections`, `pitch_angle` | Computed | Why & how to approach |
| `outreach_readiness`, `outreach_verdict` | Computed | 0–100 + send_now/verify_first/enrich_first/nurture/skip |
| `registry` | gov API | `{siren, siret, legal_name, naf, effectif, company_age_years, is_active, has_procedure_collective…}` |
| `ai` | LLM (premium) | `{outreach_draft, personalization_hooks, icp_fit_score, fit_reason, recommended_action}` |
| `cluster_id`, `cluster_size`, `lead_score` | Computed | Franchise grouping + legacy A–F |

A final `territory_summary` record gives the market view: counts by verdict, grade, lifecycle, archetype, distinct entities, and your top 10 leads.

***

### The intelligence layer (deterministic, reproducible)

Everything except the optional `ai` block is computed with **documented heuristics — no LLM**. That means it's reproducible across runs, needs no API key, and costs ~nothing. For each lead we derive its website maturity grade, tech stack, lifecycle stage, archetype, the concrete **opportunity signals** you can pitch against (no online booking, no ad pixels, outdated site…), the **likely objections**, a one-line **pitch angle**, an **outreach readiness** score, and a routing **verdict** so your SDRs work the `send_now` leads first and skip the dead ones.

### French company-registry enrichment (the moat)

A Google Maps row is anonymous. A French business, though, is in the open SIRENE/RNE registry — and Maps rows carry the exact keys (name + postcode + GPS) to resolve it. With `checkRegistry`, each French lead is matched (free, no key) to its **SIREN/SIRET, legal name, NAF activity, employee bracket, incorporation date and age, and active/ceased status**. Add `checkBodacc` to flag **insolvency proceedings** (`has_procedure_collective`) from the official gazette. That turns a lead list into a **KYC-grade** list — you stop emailing companies in liquidation. For other countries, chain the per-country registers such as [germany-companies-scraper](https://apify.com/dltik/germany-companies-scraper), or use [pappers-sirene-scraper](https://apify.com/dltik/pappers-sirene-scraper) for deep French financials.

### Email verification (SMTP)

With `verifyEmails`, each primary email runs the full ladder: syntax → **MX record** → **SMTP mailbox probe** → **catch-all** detection → **disposable** list. Status is `valid`, `catch_all`, `risky`, `invalid`, or `disposable`. Honest by design: if the network blocks outbound port 25 the SMTP step degrades to `risky` rather than lying — the MX and disposable checks always run, which already beats the commodity scrapers that do neither.

### AI qualification & outreach drafts (premium)

`analyzeLeads` (paid Apify plans) adds an `ai` block: a **ready-to-send outreach opener** that references a concrete fact we found (city, category, a website gap, a registry fact), plus — when you provide a `businessProfile` — an **ICP fit score 0–100**, a one-line reason, and a `recommended_action`. It's billed separately, only for leads actually analyzed.

***

### Pricing

Pay-per-event, split so you only pay for what you turn on:

| Event | What | Price |
|---|---|---|
| `lead-enriched` | Every lead: crawl + verification + registry + full deterministic intelligence | **$0.02 / lead** |
| `lead-analyzed` | Premium AI (ICP + outreach draft), only for analyzed leads | **$0.01 / lead** |

No residential proxy cost. A 200-lead run with registry + SMTP is **~$4**; add AI on all 200 for **+$2**.

***

### Related actors by dltik

| Actor | What it does |
|---|---|
| [Google Maps Reviews Scraper](https://apify.com/dltik/google-maps-reviews-scraper) | Ratings + reviews + sentiment — pair it to find each lead's pain points |
| [Pappers / Sirene Scraper](https://apify.com/dltik/pappers-sirene-scraper) | 26M French companies: financials, directors, BODACC risk, AI ICP scoring |
| [MCP Server — Pappers](https://apify.com/dltik/mcp-server-pappers) | French company lookup as an MCP tool for AI agents |
| [HelloWork Scraper](https://apify.com/dltik/hellowork-scraper) | French job postings + company registry enrichment + AI match |
| [Facebook Ads Scraper](https://apify.com/dltik/facebook-ads-scraper) | Meta Ad Library — creatives, CTA links, AI angle analysis |

***

### Connect with Make, Zapier & n8n

This actor integrates with any automation platform via the Apify API. Add an Apify **Run Actor** module, then a **Get Dataset Items** module to push qualified leads to Google Sheets, HubSpot, Pipedrive, Slack or your CRM. Filter on `outreach_verdict == "send_now"` to route only the best leads.

```python
from apify_client import ApifyClient

client = ApifyClient("YOUR_APIFY_TOKEN")
run = client.actor("dltik/google-maps-email-extractor").call(run_input={
    "mode": "search",
    "queries": ["dentist Lyon"],
    "verifyEmails": True,
    "checkRegistry": True,
})
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    if item.get("outreach_verdict") == "send_now":
        print(item["name"], item.get("primary_email"))
```

***

### FAQ

**Do I need residential proxies?** No. Unlike browser-based Google Maps scrapers, this actor is HTTP-only — datacenter proxy (included on every plan) is enough.

**Search mode returned nothing.** Google sometimes blocks datacenter IPs for the HTTP Maps endpoint. For guaranteed results at scale, run a dedicated Google Maps scraper and pass its `datasetId` (mode = datasetId), or use mode = websites.

**How accurate is SMTP verification?** MX + disposable checks are reliable. The exact-mailbox SMTP probe depends on outbound port 25; when it's blocked the status is `risky` (deliverable domain, unconfirmed mailbox) rather than a false `valid`.

**Which countries does registry enrichment cover?** France (SIRENE/RNE + BODACC) natively. For other countries, chain the per-country company-register actors in the dltik portfolio.

**Is this legal?** It collects only publicly available business information. Comply with GDPR/CCPA and anti-spam law (opt-out, legitimate interest) in your outreach.

# Actor input Schema

## `mode` (type: `string`):

How to gather businesses: 'search' = HTTP Google Maps search from your queries (no browser); 'websites' = enrich a list of websites/domains you already have; 'datasetId' = enrich the output of a Google Maps scraper run (e.g. compass/crawler-google-places) — the most reliable at scale.

## `queries` (type: `array`):

Google Maps searches, keyword + location (e.g. 'dentist Lyon', 'plumber Paris 11'). Used only when mode = search.

## `websites` (type: `array`):

List of business websites or bare domains to enrich (e.g. 'acme.fr', 'https://example.com'). Used only when mode = websites.

## `datasetId` (type: `string`):

The dataset id of a finished Google Maps scraper run (e.g. compass/crawler-google-places). We read its rows (title, address, phone, website, rating, coordinates) and add the full email + intelligence + registry layer on top. Best way to enrich thousands of places reliably.

## `maxResultsPerQuery` (type: `integer`):

Max businesses per search query (mode = search) or max rows read from the source dataset (mode = datasetId).

## `emailDepth` (type: `string`):

shallow = homepage only (faster). deep = homepage + /contact, /about, /team, /impressum, /mentions-legales (finds ~30-50% more emails and the decision makers).

## `findDecisionMakers` (type: `boolean`):

Discover named people (owner / director / manager) with their title, LinkedIn, and personal email from team/about pages. Deterministic, no LLM.

## `includeGuessedEmails` (type: `boolean`):

When no email is published, generate likely role addresses (info@, contact@) as a fallback. Marked email_quality = low.

## `verifyEmails` (type: `boolean`):

Check each primary email: MX record + SMTP mailbox probe + catch-all + disposable. Adds a 'verification' block with status valid/risky/invalid/catch_all/disposable. (SMTP may degrade to 'risky' if the network blocks port 25 — MX + disposable checks always run.)

## `checkWhatsApp` (type: `boolean`):

Check whether each phone number is registered on WhatsApp (adds has_whatsapp). Useful for WhatsApp Business outreach.

## `watchMode` (type: `boolean`):

Track each lead across recurring runs and report what CHANGED since last time: new/lost email, decision maker joined/left, website redesign, new tech (Shopify/booking/ads), reviews momentum, and — for FR leads — a NEW BODACC insolvency event or a ceased status. Adds a 'watch' block per lead. State is kept in a named store (see watchlistName) that persists between runs. Schedule the actor to get a change feed.

## `watchlistName` (type: `string`):

Name of the persistent key-value store that remembers the previous run's snapshot (only used when watchMode is on). Use one distinct name per campaign so their histories don't mix.

## `onlyChanges` (type: `boolean`):

When watchMode is on, push only the leads that are new or that changed since the last run (skip unchanged ones in the output). Billing still counts every lead enriched.

## `renderJs` (type: `boolean`):

PREMIUM (paying Apify plans). For sites where the fast HTTP crawl finds no email (typically React/Next/Vue single-page apps), spin up a headless browser to render the page and re-extract emails + decision makers. Billed per site actually rendered (lead-rendered), only for no-email sites. Leave off for HTTP-only speed.

## `checkRegistry` (type: `boolean`):

For French businesses, match each lead to its official legal entity via the free gov API: SIREN/SIRET, legal name, NAF activity, employee bracket, incorporation date + age, active/ceased status. Matched by name + postcode + GPS proximity. Turns a lead list into a KYC-grade list. (Other countries: chain the dltik/\*-companies-scraper actors.)

## `checkBodacc` (type: `boolean`):

For registry-matched French companies, look up the BODACC official gazette (free) and flag has_procedure_collective (bankruptcy/receivership/liquidation) + event count. Best for de-risking outreach. Requires checkRegistry.

## `analyzeLeads` (type: `boolean`):

PREMIUM (paying Apify plans). Adds an 'ai' block per lead: a ready-to-send personalised outreach opener referencing concrete facts we found, plus — if you give a businessProfile — an ICP fit_score (0-100), fit_reason and recommended_action (contact/watch/skip). Billed per analyzed lead on top of the base event.

## `businessProfile` (type: `string`):

Describe who you sell to (product, target sector/size/geo). Used only when analyzeLeads is on, to score each lead's fit and tailor the outreach draft. Example: 'We sell online-booking software to independent French beauty salons.'

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

Language for Google Maps search results and AI outreach drafts (ISO 639-1, e.g. 'en', 'fr').

## `proxyConfig` (type: `object`):

Optional. Unlike the old browser version, this actor is HTTP-only and does NOT require residential proxies. Datacenter proxy (included on all plans) is enough; only enable if your IP gets rate-limited.

## Actor input object example

```json
{
  "mode": "search",
  "queries": [
    "dentist Lyon"
  ],
  "maxResultsPerQuery": 20,
  "emailDepth": "deep",
  "findDecisionMakers": true,
  "includeGuessedEmails": true,
  "verifyEmails": false,
  "checkWhatsApp": false,
  "watchMode": false,
  "watchlistName": "lead-watchlist",
  "onlyChanges": false,
  "renderJs": false,
  "checkRegistry": false,
  "checkBodacc": false,
  "analyzeLeads": false,
  "language": "en",
  "proxyConfig": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

## `results` (type: `string`):

List of enriched, scored leads with contact info, verification, registry, and outreach verdict.

# 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 = {
    "queries": [
        "dentist Lyon"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("dltik/google-maps-email-extractor").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 = { "queries": ["dentist Lyon"] }

# Run the Actor and wait for it to finish
run = client.actor("dltik/google-maps-email-extractor").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 '{
  "queries": [
    "dentist Lyon"
  ]
}' |
apify call dltik/google-maps-email-extractor --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,dltik/google-maps-email-extractor"
        }
    }
}
```

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/JIo6ULyA7Sre1HUhv/builds/bKX7lWF8ZzpBNxNal/openapi.json
