# Maps to Contacts — Clean Domains + Find Emails (`night111/maps-to-contacts`) Actor

One-run lead pipeline: clean messy website lists from Google Maps or CRM, then extract emails, phones, and socials. Skip manual handoffs between tools.

- **URL**: https://apify.com/night111/maps-to-contacts.md
- **Developed by:** [ng. night](https://apify.com/night111) (community)
- **Categories:** Lead generation
- **Stats:** 3 total users, 0 monthly users, 100.0% runs succeeded, 1 bookmarks
- **User rating**: 5.00 out of 5 stars

## Pricing

from $4.48 / 1,000 contact results

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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

## Maps to Contacts — Clean Domains + Find Emails

**One-run lead pipeline:** paste messy websites from Google Maps, directories, or CRM → get **emails, phones, and socials**.

No need to run a cleaner and a contact scraper as two separate jobs.

### What is Maps to Contacts?

Maps to Contacts combines two steps in a single Apify Actor:

1. **Clean** — normalize hosts, strip paths, drop social-only URLs, dedupe
2. **Enrich** — crawl each kept company website for public **emails**, **phones**, and **social links**

Ideal when your input is a raw **website** column from a Maps export.

```
Google Maps / directory / CRM
        ↓ messy websites
 Maps to Contacts   ← you are here (clean + extract)
        ↓
 emails + phones + socials (one row per domain)
```

Prefer separate tools? Use **[Domain List Cleaner](https://apify.com/night111/domain-list-cleaner)** then **[Website Contact Finder](https://apify.com/night111/website-contact-finder)**.

### What data can I extract?

| Field | Description |
| --- | --- |
| 🌐 **Domain / URL** | Clean company site |
| 📧 **Emails** | Public addresses from HTML |
| 📞 **Phones** | From `tel:` and page text |
| 💼 **Socials** | LinkedIn, X, Facebook, Instagram, YouTube, … |
| 📎 **Original** | First raw input string for that domain |

### Why use this Actor?

- 🔗 **One run** — clean + contacts without manual CSV handoff
- 🧹 **Junk filtered** — Facebook-only “websites” and free-mail hosts dropped before crawl
- 📦 **One row per domain** — CRM-friendly
- ⚡ **Cheerio-fast** — no full browser by default
- 💰 **Fair PPE** — pay only when email or phone is found (empty rows free)

### How to use

1. [Create a free Apify account](https://console.apify.com/sign-up)
2. Open **Maps to Contacts**
3. Paste websites from your Maps / CSV export
4. Click **Start**
5. Download the **Dataset** (CSV / Excel / JSON)

#### From Google Maps

1. Run a [Google Maps / Places scraper](https://apify.com/compass/crawler-google-places)
2. Copy the **website** field (or export that column)
3. Paste into this Actor → Start

### Input

| Field | Description |
| --- | --- |
| **Websites / domains** | List of messy URLs or domains |
| **Raw text** | Optional paste block |
| **Keep subdomains** | Default off |
| **Drop social hosts** | Default on |
| **Max domains to enrich** | Cap after cleaning (default 100) |
| **Max pages per domain** | Default 5 |
| **Follow contact links** | Default on |
| **Proxy** | Optional Apify Proxy |

#### Example input

```json
{
  "websites": [
    "https://www.Example.com/about?ref=maps",
    "facebook.com/localbiz",
    "https://shop.acme.co.uk/"
  ],
  "dropSocialHosts": true,
  "maxDomains": 50,
  "maxPagesPerDomain": 5,
  "followContactLinks": true
}
```

### Output

One dataset item per cleaned domain (same shape as Website Contact Finder, plus `original`):

```json
{
  "domain": "example.com",
  "url": "https://example.com/",
  "original": "https://www.Example.com/about?ref=maps",
  "emails": ["hello@example.com"],
  "phones": ["+1 415 555 0100"],
  "socials": {
    "linkedin": "https://www.linkedin.com/company/example"
  },
  "emailCount": 1,
  "phoneCount": 1,
  "pageTitle": "Example",
  "scrapedAt": "2026-07-28T12:00:00.000Z"
}
```

A run summary is stored as key-value `OUTPUT` (input count, cleaned count, reject reasons).

### Who is this for?

- Sales teams enriching Maps exports
- Agencies delivering “places → contacts” for clients
- Anyone who wants clean + contact without two Actors

### How much does it cost?

**Pay-per-event.** Charge only when a cleaned domain yields **at least one email or phone**. Social-only / empty rows are free (still in the dataset).

| Event | Price |
| --- | --- |
| **Contact result** (email **or** phone found) | **$0.008** → **$8 / 1,000** |
| Actor start | **$0** or tiny infrequent fee |
| Platform usage | Included (typical PPE setup) |

Slightly above standalone Contact Finder because cleaning is included. Always check the **Pricing** tab.

### FAQ

#### Does this scrape Google Maps itself?

No. Feed it **websites** from any Maps or directory Actor / CSV. It cleans those URLs and scrapes the company sites.

#### What if every row is Facebook?

Social hosts are dropped by default — you may get zero domains. Turn off **Drop social hosts** only if you really want those (usually not useful for email).

#### Standalone Cleaner or Contact Finder?

- Only need clean URLs → [Domain List Cleaner](https://apify.com/night111/domain-list-cleaner)
- Already clean domains → [Website Contact Finder](https://apify.com/night111/website-contact-finder)
- Messy Maps column → **this Actor**

### Limitations

- Public HTML only (no login walls / image-only emails)
- Does not geocode or scrape the Maps UI
- Public-suffix collapse is best-effort

### Feedback & support

Open an issue on the Actor **Issues** tab. Related: Domain List Cleaner, Website Contact Finder.

***

**Keywords:** google maps email scraper, maps to contacts, website email extractor, lead generation pipeline, domain cleaner contact finder, places to emails, sales enrichment

# Changelog

This Actor's version history is a separate document: https://apify.com/night111/maps-to-contacts/changelog.md

# Actor input Schema

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

Messy list of websites from Google Maps, directories, or CRM. Strings or objects with url / domain / website fields are fine.

## `websitesText` (type: `string`):

Paste a column of websites (newlines, commas, or spaces). Merged with the list above.

## `keepSubdomains` (type: `boolean`):

If false (default), blog.example.com collapses to example.com before crawling.

## `dropSocialHosts` (type: `boolean`):

Skip facebook, linkedin, instagram, etc. so only real company sites are crawled.

## `maxDomains` (type: `integer`):

After cleaning/deduping, only crawl the first N domains (cost control).

## `maxRequestsPerCrawl` (type: `integer`):

Hard cap on HTTP requests across all sites.

## `maxPagesPerDomain` (type: `integer`):

Home + contact/about pages per cleaned domain.

## `followContactLinks` (type: `boolean`):

Visit pages that look like contact, about, team, impressum.

## `proxyConfiguration` (type: `object`):

Optional Apify Proxy for sites that block datacenter IPs.

## Actor input object example

```json
{
  "websites": [
    "https://www.apify.com/about",
    "facebook.com/somepage",
    "https://www.example.com/contact?ref=1"
  ],
  "keepSubdomains": false,
  "dropSocialHosts": true,
  "maxDomains": 100,
  "maxRequestsPerCrawl": 50,
  "maxPagesPerDomain": 5,
  "followContactLinks": true,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

## `contacts` (type: `string`):

Dataset of cleaned domains with contact fields and billable flag.

## `summary` (type: `string`):

Input/cleaned/saved/charged counts and reject reasons.

# 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 = {
    "websites": [
        "https://www.apify.com/about",
        "facebook.com/somepage",
        "https://www.example.com/contact?ref=1"
    ],
    "websitesText": ""
};

// Run the Actor and wait for it to finish
const run = await client.actor("night111/maps-to-contacts").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 = {
    "websites": [
        "https://www.apify.com/about",
        "facebook.com/somepage",
        "https://www.example.com/contact?ref=1",
    ],
    "websitesText": "",
}

# Run the Actor and wait for it to finish
run = client.actor("night111/maps-to-contacts").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 '{
  "websites": [
    "https://www.apify.com/about",
    "facebook.com/somepage",
    "https://www.example.com/contact?ref=1"
  ],
  "websitesText": ""
}' |
apify call night111/maps-to-contacts --silent --output-dataset

```

## MCP server setup

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

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/0KVBstfnrA9kq9DKV/builds/gJqPt4fFVXq31hWDN/openapi.json
