# Website Contact & Email Extractor – Emails, Phones, Socials (`rt-solutions/website-contact-email-extractor`) Actor

Extract emails, phone numbers, social profiles (Facebook, Instagram, LinkedIn, X, YouTube, TikTok, WhatsApp…), contact page and contact form from any list of websites. Checks that email domains receive mail. Enrich another run's dataset. $1.50 per 1,000 websites with contacts found.

- **URL**: https://apify.com/rt-solutions/website-contact-email-extractor.md
- **Developed by:** [RT SOLUTIONS](https://apify.com/rt-solutions) (community)
- **Categories:** Lead generation, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.00 / 1,000 website with contacts

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

## Website Contact & Email Extractor – Emails, Phones, Socials

Give a list of websites (or the dataset of another run, e.g. a Google Maps scrape) and get for each one: **emails**, **phone numbers**, **social profiles** (Facebook, Instagram, LinkedIn, X/Twitter, YouTube, TikTok, Pinterest, WhatsApp, Telegram), the **contact page URL** and whether the site has a **contact form**.

**$1.50 per 1,000 websites — charged only when contacts are found**, whatever the number of pages read. No start fee. Websites with nothing found, unreachable or blocked are free.

### Real test

600 dentists from Google Maps in Chicago → 486 unique websites → **80 % with contacts**: 220 with emails, 344 with phones, 306 with Facebook, 324 contact pages, 198 contact forms — in 8.5 minutes.

### What it does

- Reads the home page + the most useful internal pages (contact, about, legal/imprint, team — in English, French, German, Spanish, Italian, Portuguese…), up to 10 pages per site.
- Finds emails in links, text, obfuscated forms (`name [at] domain`) and **Cloudflare-protected emails**.
- Removes junk: image file names, template addresses (`you@company.com`, `info@mysite.com`), form placeholders.
- **Checks email domains** (public MX record): emails on domains that cannot receive mail are moved to `emailsInvalidDomain`.
- Sorts emails with the website's own domain first; option to keep only those.
- Same domain listed several times (chains, groups) → analysed and charged once, every input row returned.

### Input

```json
{
  "websites": "apify.com\nhttps://www.example-dentist.com\nshop.example.fr",
  "maxPagesPerSite": 4,
  "checkEmailDomains": true
}
```

**Enrich another run:** pick its dataset in "Or enrich a dataset from another run" and set the field holding the website (`website`, `url`, `domain`…). Each item comes back with its original fields + contacts — perfect after a Google Maps, Yelp or directory scrape.

### Output (one row per website)

`url`, `domain`, `finalUrl`, `status` (`ok`, `blocked`, `unreachable`, `http_404`…), `title`, `emails`, `emailsInvalidDomain`, `phones`, `contactPageUrl`, `hasContactForm`, `facebooks`, `instagrams`, `linkedIns`, `twitters`, `youtubes`, `tiktoks`, `pinterests`, `whatsapps`, `telegrams`, `pagesScraped`, `noContactsFound`.

### Pricing

| Apify plan | Per 1,000 websites with contacts |
|---|---|
| Free | $1.50 |
| Bronze | $1.30 |
| Silver | $1.20 |
| Gold and above | $1.00 |

Set a maximum cost per run and the Actor stops there.

### Limits

- Public pages only, no login. Sites protected by an anti-bot challenge are marked `blocked` (and not charged).
- Contacts shown only as images or loaded by JavaScript after page load are not read.
- Email domain check = the domain accepts mail; it does not send emails or test the mailbox.

### Use cases

- **Lead generation**: turn a Google Maps, Yelp or directory scrape into a list with emails, phones and social profiles.
- **Sales outreach**: get the contact page and know whether each prospect has a contact form.
- **Marketing agencies**: see which local businesses are on Instagram, Facebook, TikTok or LinkedIn before pitching them.
- **CRM clean-up**: flag emails on domains that cannot receive mail before importing them.
- **Partnership and PR outreach**: find the public contact details of a list of websites in one run.

### Use with AI agents (MCP)

You can call this Actor from Claude, ChatGPT, Cursor or any other MCP client through the Apify MCP server (https://mcp.apify.com), using the Actor ID `rt-solutions/website-contact-email-extractor`. For example: *"Find the emails, phone numbers and Instagram pages of these 50 websites and tell me which ones have a contact form."* It also works through the Apify API, Make, n8n and Zapier.

### FAQ

**How do I find email addresses from a list of websites?** Paste the websites (one per line) or pick the dataset of another run, and click Start. You get one row per website with emails, phones, socials and the contact page.

**How much does it cost to extract contacts from 10,000 websites?** At most $15 on the free plan ($1.50 per 1,000), down to $10 on Gold and above — and only websites where contacts are found are charged.

**Why were no emails found for some websites?** The site may show no email at all, show it only as an image or load it with JavaScript after page load, or be protected by an anti-bot challenge (`blocked`, not charged).

**Does it verify the emails?** It checks that the email domain can receive mail (public MX record). It does not send emails or test the mailbox.

**Can I enrich my Google Maps results?** Yes — pick the Google Maps run's dataset and set the field holding the website. Each item comes back with its original fields + contacts.

**Is it legal?** It reads public business pages. You must respect privacy and anti-spam laws (GDPR, CAN-SPAM, CASL) when contacting people.

**Need another field?** Open an issue — we answer in writing within 24 h.

### Related scrapers

- [Google Maps Scraper – Business Leads](https://apify.com/rt-solutions/google-maps-scraper-leads) — build the list, then enrich it here.
- [Google Search Results Scraper](https://apify.com/rt-solutions/google-search-results-scraper)
- [Semrush Website Traffic](https://apify.com/rt-solutions/semrush-website-traffic-scraper)

# Actor input Schema

## `websites` (type: `string`):

One per line: example.com or https://example.com/page. Duplicates (same domain) are removed.

## `startUrls` (type: `array`):

Same as above, as a list or uploaded file.

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

Pick the dataset of another Actor run (e.g. a Google Maps scrape). Each item is returned with its original fields + contacts.

## `urlField` (type: `string`):

Name of the field holding the website (website, url, domain…). Nested fields with dots: e.g. company.website.

## `maxPagesPerSite` (type: `integer`):

Home page + contact / about / legal / team pages. Price is per website, not per page.

## `checkEmailDomains` (type: `boolean`):

Keep only emails whose domain can receive mail (public MX record). Others go to emailsInvalidDomain.

## `sameDomainEmailsOnly` (type: `boolean`):

Drop gmail/outlook and third-party addresses.

## `keepInputFields` (type: `boolean`):

When enriching a dataset, return its original fields too.

## `maxWebsites` (type: `integer`):

0 = all.

## Actor input object example

```json
{
  "websites": "apify.com\nhttps://www.shopify.com",
  "urlField": "website",
  "maxPagesPerSite": 4,
  "checkEmailDomains": true,
  "sameDomainEmailsOnly": false,
  "keepInputFields": true,
  "maxWebsites": 0
}
```

# Actor output Schema

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

One row per website.

## `overview` (type: `string`):

Main fields.

# 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": `apify.com
https://www.shopify.com`
};

// Run the Actor and wait for it to finish
const run = await client.actor("rt-solutions/website-contact-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 = { "websites": """apify.com
https://www.shopify.com""" }

# Run the Actor and wait for it to finish
run = client.actor("rt-solutions/website-contact-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 '{
  "websites": "apify.com\\nhttps://www.shopify.com"
}' |
apify call rt-solutions/website-contact-email-extractor --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,rt-solutions/website-contact-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/CCuB3QbuxmrJQVDvT/builds/Yi4NSiOW7ppsx8PlK/openapi.json
