# Email & Contact Scraper - Website Emails, Phones & Socials (`plotpointtech/website-contact-finder`) Actor

Paste company websites and get their published emails, phone numbers, 13 social networks and address, with the page each was found on. Optional browser rendering for JavaScript sites. Respects robots.txt. $1.50 per 1,000 websites.

- **URL**: https://apify.com/plotpointtech/website-contact-finder.md
- **Developed by:** [Plot Point Technologies](https://apify.com/plotpointtech) (community)
- **Categories:** Lead generation, Automation
- **Features:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.93 / 1,000 website processeds

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

## Email & Contact Scraper: Emails, Phones and Socials from Company Websites

**Paste a list of company websites and get each company's published business contact details: email addresses, phone numbers, social media profiles and street address.** One row per website, with the pages where each detail was found, so you can check any value in seconds. Flat price per website, no matter how many pages are checked.

### What can this email and contact scraper do?

- **Find emails** in `mailto:` links, visible text, schema.org structured data, Cloudflare-protected addresses and simple obfuscations such as `name [at] company [dot] com`.
- **Find phone numbers** from `tel:` and WhatsApp links, structured data and text, validated and normalized to international format with the country. Fax numbers are listed separately, and numbers that could not be confirmed go to `phonesUncertain`.
- **Collect social profiles** the site links to on 13 networks: LinkedIn, Facebook, X (Twitter), Instagram, YouTube, TikTok, Pinterest, Discord, Telegram, WhatsApp, Threads, Snapchat and Reddit. Share buttons are ignored, and nothing is fetched from the social networks themselves.
- **Read the address** when it is marked up (schema.org PostalAddress or an HTML `<address>` block).
- **Check the right pages:** the homepage plus contact, about, team, locations, imprint (Impressum), legal and support pages in many languages, up to 8 pages per site by default. Turn on **Crawl all links** to follow any page on the site, contact pages first.
- **Handle JavaScript websites:** with **Use a browser automatically for JavaScript-only sites** (on by default), a site whose homepage comes back as an empty JavaScript app is rendered in a headless Chrome browser. Turn on **Render pages in a browser** to render every page.
- **Read link-in-bio pages** (beacons.ai, bio.link, lnk.bio, taplink and similar) and the websites they list.
- **Choose one row per website or one row per page** with **One row per website** (`mergeContacts`).
- **Remove junk:** image file names, `example.com`, placeholder and tracking addresses. Emails are labelled `role` (info@, sales@), `personal` (looks like a person's name) or `other`, and personal-looking emails can be left out.

### What data do you get?

| Field | Description |
|---|---|
| `input`, `url`, `domain`, `companyName` | What you entered, the homepage loaded, its domain and the company name |
| `emails` | Unique emails, company-domain and role addresses first |
| `phones`, `phonesE164`, `phonesUncertain`, `faxes` | Phone numbers (formatted and E.164), unconfirmed numbers and fax numbers |
| `linkedIn`, `facebook`, `x`, `instagram`, `youtube`, `tiktok`, `pinterest`, `discord`, `telegram`, `whatsapp`, `threads`, `snapchat`, `reddit` | Profile links found on the website |
| `address` | Street, locality, region, postal code, country and the page it came from |
| `emailDetails`, `phoneDetails`, `socialDetails` | Each value with the pages it was found on and how it was found |
| `pagesVisited`, `pagesCrawled`, `phoneRegionAssumed` | Pages checked and the country used to read local phone numbers |

Turn on **Add alternative field names** to also get `originalStartUrl`, `scrapedUrls` and plural social fields (`linkedIns`, `twitters`, `facebooks`...) if you are switching from another contact scraper.

### Who uses it?

- **Sales and business development teams** enriching target-company lists with general emails and phone numbers.
- **Agencies and freelancers** building prospect lists from domains they already have.
- **Marketplaces and directories** keeping supplier or member records up to date.
- **Researchers** collecting official contact channels of organizations.

### How to use it

1. Click **Try for free** (or **Start**).
2. Paste **Websites**, one per line (`acme.com` or full URLs). Duplicates are removed.
3. Optionally turn on **Skip websites with no contact details** so you only pay for useful rows.
4. For JavaScript-heavy sites, turn on **Render pages in a browser**.
5. Run it and download the results as Excel, CSV or JSON, or send them to your CRM.

### Input example

```json
{
  "websites": [
    "https://www.bakerbotts.com/",
    "stripe.com",
    "https://www.patagonia.com"
  ],
  "maxPagesPerSite": 8,
  "mergeContacts": true,
  "browserFallback": true,
  "excludePersonalEmails": false,
  "skipSitesWithoutContacts": true
}
```

### Output example

```json
{
  "input": "https://www.bakerbotts.com/",
  "url": "https://www.bakerbotts.com/",
  "domain": "bakerbotts.com",
  "companyName": "Baker Botts",
  "emails": [
    "recruiting@bakerbotts.com",
    "alumni@bakerbotts.com"
  ],
  "phones": [
    "+1 214-953-6978",
    "+1 212-408-2696",
    "+1 713-229-1113"
  ],
  "linkedIn": [
    "https://www.linkedin.com/company/baker-botts-llp"
  ],
  "facebook": [
    "https://www.facebook.com/BakerBottsLLP"
  ],
  "x": [
    "https://x.com/bakerbotts"
  ],
  "instagram": [
    "https://www.instagram.com/bakerbotts"
  ],
  "youtube": [
    "https://www.youtube.com/channel/UCgys2C8DwRY-BVN079QNnwQ"
  ],
  "tiktok": [],
  "pinterest": [],
  "discord": [],
  "telegram": [],
  "whatsapp": [],
  "threads": [],
  "snapchat": [],
  "reddit": [],
  "address": null,
  "phonesUncertain": [],
  "phonesE164": [
    "+12149536978",
    "+12124082696",
    "+17132291113"
  ],
  "faxes": [],
  "emailDetails": [
    {
      "email": "recruiting@bakerbotts.com",
      "type": "role",
      "foundOn": [
        "https://www.bakerbotts.com/careers/careers-at-baker-botts/lawyer-recruiting-contacts-by-office"
      ],
      "source": [
        "obfuscated"
      ]
    },
    {
      "email": "alumni@bakerbotts.com",
      "type": "role",
      "foundOn": [
        "https://www.bakerbotts.com/aboutus/alumni"
      ],
      "source": [
        "obfuscated"
      ]
    }
  ],
  "phoneDetails": [
    {
      "phone": "+12149536978",
      "formatted": "+1 214-953-6978",
      "country": "US",
      "type": "phone",
      "certain": true,
      "source": [
        "formatted-text"
      ],
      "foundOn": [
        "https://www.bakerbotts.com/careers/careers-at-baker-botts/lawyer-recruiting-contacts-by-office"
      ]
    },
    {
      "phone": "+12124082696",
      "formatted": "+1 212-408-2696",
      "country": "US",
      "type": "phone",
      "certain": true,
      "source": [
        "formatted-text"
      ],
      "foundOn": [
        "https://www.bakerbotts.com/careers/careers-at-baker-botts/lawyer-recruiting-contacts-by-office"
      ]
    },
    {
      "phone": "+17132291113",
      "formatted": "+1 713-229-1113",
      "country": "US",
      "type": "phone",
      "certain": true,
      "source": [
        "formatted-text"
      ],
      "foundOn": [
        "https://www.bakerbotts.com/careers/careers-at-baker-botts/lawyer-recruiting-contacts-by-office"
      ]
    }
  ],
  "socialDetails": [
    {
      "network": "facebook",
      "url": "https://www.facebook.com/BakerBottsLLP",
      "foundOn": [
        "https://www.bakerbotts.com/",
        "https://www.bakerbotts.com/footer/contact-us",
        "https://www.bakerbotts.com/careers/careers-at-baker-botts/lawyer-recruiting-contacts-by-office"
      ]
    },
    {
      "network": "instagram",
      "url": "https://www.instagram.com/bakerbotts",
      "foundOn": [
        "https://www.bakerbotts.com/",
        "https://www.bakerbotts.com/footer/contact-us",
        "https://www.bakerbotts.com/careers/careers-at-baker-botts/lawyer-recruiting-contacts-by-office"
      ]
    },
    {
      "network": "linkedin",
      "url": "https://www.linkedin.com/company/baker-botts-llp",
      "foundOn": [
        "https://www.bakerbotts.com/",
        "https://www.bakerbotts.com/footer/contact-us",
        "https://www.bakerbotts.com/careers/careers-at-baker-botts/lawyer-recruiting-contacts-by-office"
      ]
    }
  ],
  "pagesVisited": [
    "https://www.bakerbotts.com/",
    "https://www.bakerbotts.com/footer/contact-us",
    "https://www.bakerbotts.com/careers/careers-at-baker-botts/lawyer-recruiting-contacts-by-office"
  ],
  "pagesCrawled": 8,
  "phoneRegionAssumed": "US"
}
```

### How much does it cost?

You pay per row saved: **$1.50 per 1,000 rows** ($0.0015 each), plus a $0.00005 start fee per run. Browser rendering costs the same.

- **One row per website on (default):** one row per website, so the price is a flat $1.50 per 1,000 websites however many pages are checked.
- **One row per website off (`mergeContacts: false`):** one row per page that was read, so a website where 8 pages are checked produces up to 8 rows and costs up to 8 times as much. Use it only when you need contacts page by page.

| You process (one row per website) | You pay |
|---|---|
| 100 websites | $0.15 |
| 1,000 websites | $1.50 |
| 10,000 websites | $15.00 |

Websites that cannot be loaded, are blocked by robots.txt or time out are not saved and not charged; they are listed in the `FAILED_WEBSITES` record of the run's key-value store. With "Skip websites with no contact details" on, empty results are free too. Use **Max pages in total** and a maximum cost per run to cap spending.

**Volume discounts on higher Apify plans.** The prices above are for the Apify Free plan. On paid plans the per-result price drops automatically: about 15% lower on Bronze, 25% lower on Silver and 38% lower on Gold and above.

### Use it via API, Make, Zapier, n8n or an AI agent

**Apify API.** Start a run and get the results back in one HTTP request (replace `YOUR_API_TOKEN` with the token from Apify Console > Settings > Integrations):

```bash
curl -X POST "https://api.apify.com/v2/acts/plotpointtech~website-contact-finder/run-sync-get-dataset-items?token=YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"websites": ["https://www.bakerbotts.com/", "stripe.com", "https://www.patagonia.com"], "maxPagesPerSite": 8, "mergeContacts": true, "browserFallback": true, "excludePersonalEmails": false, "skipSitesWithoutContacts": true}'
```

For longer jobs, start the run asynchronously and read the dataset when it finishes. Official `apify-client` libraries exist for Python and JavaScript; the **API** tab on this page has ready-made code.

**No-code automation.** Connect the tool to **Make, Zapier, n8n, Google Sheets, Slack, Airtable** or any webhook with Apify integrations, and use **Schedules** in Apify Console to run it hourly, daily or weekly.

**AI agents (MCP).** Give Claude, ChatGPT, Cursor, VS Code or any MCP-compatible agent direct access to this tool through the hosted Apify MCP server. Add this server URL to your client:

```
https://mcp.apify.com?tools=plotpointtech/website-contact-finder
```

The agent can then call the tool with the same input fields shown above and read the results.

### FAQ

**Is it legal to scrape contact details from websites?**
This tool only reads business contact details that companies publish on their own public websites, respects robots.txt (also when a browser is used) and does not log in or bypass blocking. How you use the data is regulated: you are responsible for complying with data-protection and anti-spam laws such as GDPR, CAN-SPAM and PECR, especially for emails that name an individual.

**Are the emails verified?**
They are published by the company, cleaned and de-duplicated, but not tested for deliverability. Our Local Business Leads Scraper adds MX checks if you start from a category and city instead of a domain list.

**Does it scrape LinkedIn or Facebook?**
No. It only records the profile links a company's own website links to.

**Why was no email found for a site?**
Some sites show contact details only inside images or behind contact forms, which cannot be read. If the site is a JavaScript app, turn on **Render pages in a browser**; with the default browser fallback, empty JavaScript homepages are already rendered automatically.

**How fast is it?**
Usually a few seconds per website over plain HTTP, with up to 10 websites processed in parallel. Browser rendering is slower.

### Related tools from Plot Point Technologies

- [Local Business Leads Scraper - MX-Checked Emails & Phones](https://apify.com/plotpointtech/local-business-leads): local businesses by category and city with checked emails.
- [Website Tech Stack Detector - CMS, Analytics & 290+ Techs](https://apify.com/plotpointtech/website-technology-detector): CMS, ecommerce, analytics, pixels and hosting of any website.
- [SEC Form D Scraper - New Startup Funding Leads Daily](https://apify.com/plotpointtech/sec-form-d-fundraise-feed): companies that just raised money, from SEC Form D filings.
- [WHOIS & Domain Lookup - Bulk RDAP, DNS, SSL & Mail Provider](https://apify.com/plotpointtech/bulk-domain-lookup): registrar, expiry, DNS, email provider and SSL for any domain list.

Plot Point Technologies is not affiliated with any website you process, the social networks named above, or Apify.

***

If this tool saved you time, we would be grateful for a short review on this page; it helps other people find it. If something did not work as expected, please open an issue on the **Issues** tab and we will look into it quickly.

# Actor input Schema

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

Company websites or bare domains, one per line, e.g. acme.com or https://www.acme.com.

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

Pages loaded per website: the homepage plus the most likely contact, about, team, locations and imprint pages (or any page when 'Crawl all links' is on), up to this many. Also accepted as maxRequestsPerStartUrl.

## `maxDepth` (type: `integer`):

How many clicks away from the start page to follow links. 0 = only the start page, 1 = pages linked from it, 2 = also pages linked from those.

## `crawlAllLinks` (type: `boolean`):

Off: only follow links that look like contact, about, team, locations, imprint or support pages (fastest, cheapest). On: follow any page on the site, contact-type pages first, until the page limit is reached.

## `sameDomain` (type: `boolean`):

Only follow links on the website's own domain. Link-in-bio pages (for example beacons.ai, bio.link, lnk.bio) are an exception when 'Follow link-in-bio pages' is on. Social networks and big platforms are never crawled; their links are only recorded.

## `followLinkInBio` (type: `boolean`):

Read link-in-bio pages (beacons.ai, bio.link, lnk.bio, taplink and similar) given as start URLs or linked from a website, and crawl the websites they list. Pages whose robots.txt forbids crawling (Linktree does) are skipped.

## `mergeContacts` (type: `boolean`):

On: all pages of a website are merged into one row (you pay per website). Off: one row per page that was read, each with the contacts found on that page (you pay per page row).

## `excludePersonalEmails` (type: `boolean`):

Drop addresses that look like an individual's name, such as jane.smith@ or j.smith@, and keep role addresses (info@, sales@, support@) and other company addresses.

## `skipSitesWithoutContacts` (type: `boolean`):

Do not save (or charge for) websites where no email, phone, social link or address was found.

## `phoneCountry` (type: `string`):

Two-letter country code (US, GB, DE ...) used to read phone numbers written without a country code. Leave empty to detect it per website from its domain, language and international numbers.

## `useBrowser` (type: `boolean`):

Load every page in a headless Chrome browser so contacts added by JavaScript are found. Slower; use it for sites built as JavaScript apps. Plain HTTP is used when off.

## `browserFallback` (type: `boolean`):

When a homepage loaded over plain HTTP is an empty JavaScript app shell, render that website in a browser instead. Normal websites are unaffected.

## `waitUntil` (type: `string`):

Only used when a browser renders the page.

## `considerChildFrames` (type: `boolean`):

Also read pages embedded in iframes (for example embedded contact forms or maps). Can pick up content from third-party widgets.

## `maxRequests` (type: `integer`):

Stop loading new pages after this many in the whole run. Leave empty for no limit.

## `maxConcurrency` (type: `integer`):

How many websites to process in parallel.

## `compatibilityFields` (type: `boolean`):

Also output originalStartUrl, scrapedUrls and plural social fields (linkedIns, twitters, facebooks, instagrams, youtubes, tiktoks, pinterests, discords, telegrams, whatsapps, snapchats, reddits), so this tool can replace other contact scrapers without changing your downstream code.

## Actor input object example

```json
{
  "websites": [
    "https://www.bakerbotts.com/"
  ],
  "maxPagesPerSite": 8,
  "maxDepth": 2,
  "crawlAllLinks": false,
  "sameDomain": true,
  "followLinkInBio": true,
  "mergeContacts": true,
  "excludePersonalEmails": false,
  "skipSitesWithoutContacts": false,
  "phoneCountry": "",
  "useBrowser": false,
  "browserFallback": true,
  "waitUntil": "domcontentloaded",
  "considerChildFrames": false,
  "maxConcurrency": 5,
  "compatibilityFields": false
}
```

# Actor output Schema

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

No description

# 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.bakerbotts.com/"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("plotpointtech/website-contact-finder").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.bakerbotts.com/"] }

# Run the Actor and wait for it to finish
run = client.actor("plotpointtech/website-contact-finder").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.bakerbotts.com/"
  ]
}' |
apify call plotpointtech/website-contact-finder --silent --output-dataset

```

## MCP server setup

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

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/q52OfxfEnQTm3VhPE/builds/GrFdM6lOLZJ3UN4Tq/openapi.json
