# Website Email Extractor - Find Emails on Any Website List (`pipiagent/website-email-extractor`) Actor

Extract email addresses from any list of websites or domains: contact, about, imprint and team pages are read, emails are deduplicated and the main company email is picked for you. Phones and social profiles included. Pay only for websites where an email was found.

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

## Pricing

from $3.50 / 1,000 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

## Website Email Extractor

Turn a list of websites or domains into a list of email addresses. Paste the websites, press Start, and get one row per company with every email the website shows publicly, plus the main company address picked for you. Sales teams, recruiters, agencies and researchers use it to build outreach lists and enrich CRM records.

- **Finds the pages that have emails.** The homepage plus contact, about, imprint, team and legal pages, in many languages (Kontakt, Contacto, Impressum, お問い合わせ, 联系我们 and more).
- **The right email first.** `primaryEmail` is the company's own general address (info@, contact@, hello@) when there is one, and `ownDomainEmails` keeps only addresses on the company's domain.
- **Hidden emails decoded.** Cloudflare email protection, HTML entities and addresses written as `name [at] company [dot] com`.
- **Pay only for websites with an email.** Websites without an email, unreachable or blocked websites are saved for free with a status that says why.
- **Phones and social profiles included** at no extra cost: phone numbers in international format, LinkedIn, Facebook, Instagram, X and more.
- **Low price.** $5 per 1,000 websites with an email.

### How to use it

1. Click **Try for free**.
2. Paste your websites into **Websites**. Domains like `example.com` and full URLs both work, and you can paste a whole column from a spreadsheet at once.
3. Click **Start**.
4. Download the results as CSV, Excel or JSON.

### Input examples

```json
{
    "websites": ["timwendelboe.no", "https://www.sacher.com", "kofola.cz"]
}
```

Keep only websites where an email was found, and read more pages per website:

```json
{
    "websites": ["example-dental.com", "example-plumbing.co.uk"],
    "maxPagesPerWebsite": 20,
    "includeEmptyResults": false
}
```

### Output example

```json
{
    "website": "https://timwendelboe.no/",
    "domain": "timwendelboe.no",
    "status": "ok",
    "companyName": "Tim Wendelboe Coffee",
    "primaryEmail": "hello@timwendelboe.no",
    "emails": ["hello@timwendelboe.no", "press@timwendelboe.no"],
    "ownDomainEmails": ["hello@timwendelboe.no", "press@timwendelboe.no"],
    "emailCount": 2,
    "emailsFoundOn": [
        {"email": "hello@timwendelboe.no", "pageUrls": ["https://timwendelboe.no/pages/contact-us"]},
        {"email": "press@timwendelboe.no", "pageUrls": ["https://timwendelboe.no/pages/press"]}
    ],
    "primaryPhone": "+4740004062",
    "phones": ["+4740004062"],
    "facebook": ["https://www.facebook.com/TimWendelboeCoffee"],
    "instagram": ["https://www.instagram.com/timwendelboe"],
    "contactPageUrl": "https://timwendelboe.no/pages/contact-us",
    "pagesCrawledCount": 6,
    "scrapedAt": "2026-10-28T10:03:16Z"
}
```

`status` is `ok` when an email was found, `noContacts` when none was found (phones and social profiles are still listed, free of charge), `unreachable` or `blocked`.

### How much does it cost?

You pay **$5.00 per 1,000 websites with at least one email** ($0.005 per website). Websites without an email, unreachable or blocked websites cost nothing. There is no start fee and no monthly rental, and reading more pages per website does not cost more.

| Run | Websites with an email (typical) | Cost |
|---|---|---|
| 100 websites | about 70 | about $0.35 |
| 1,000 websites | about 700 | about $3.50 |

The share of websites with an email depends on your list. Set a maximum charge per run in the run options and the Actor stops when it is reached.

### Limits you should know

- **Emails are not verified.** The Actor reports addresses as the website shows them. It does not check whether a mailbox exists.
- **Some websites block automated visitors.** In our tests about 8% of websites answered with a bot check or "access denied". These come back as `blocked` and are free.
- **JavaScript-only websites give fewer results.** The Actor reads the HTML the server sends and does not run a browser.
- **It reads contact-like pages, not the whole website.** Up to **Max pages per website** (default 10). Emails that appear only in blog posts or deep product pages can be missed.
- **Emails of other companies can appear**, for example the web agency named on an imprint page. Use `ownDomainEmails` when you only want the company's own addresses.
- **Speed.** About 10 to 15 websites per minute with the default settings.

### Related Actors

- [Website Contact Scraper](https://apify.com/pipiagent/website-contact-scraper): the same, charged for any website with an email, phone number or social profile.
- [Domain Checker](https://apify.com/pipiagent/domain-checker): registration data, DNS (including MX records), SSL and rank for a list of domains.

### FAQ

**Is it legal?** The Actor only reads pages that every visitor can see without logging in. Business contact details can still be personal data, for example a named employee's email. You are responsible for using the results lawfully: have a legitimate reason to process the data under the GDPR and similar laws, and follow anti-spam rules such as CAN-SPAM and the ePrivacy rules before sending marketing emails.

**Can I get one row per email instead of per website?** Not in this version. Each row lists every email in `emails` and `emailsFoundOn`, and the CSV export puts them in separate columns.

**Something is broken or missing?** Open a ticket in the Issues tab. Issues are usually answered within a day.

# Actor input Schema

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

Websites to find emails on. Full URLs (https://example.com) or bare domains (example.com) both work. Paste a whole list at once, one website per line or separated by commas. You get one result per website.

## `maxPagesPerWebsite` (type: `integer`):

How many pages to open on each website, the homepage included. The Actor opens contact, about, imprint, team and similar pages first, so 5 to 10 is enough for most websites. The price per website does not change with this number.

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

How many clicks away from the homepage the Actor may go. 0 = homepage only, 1 = pages linked from the homepage, 2 = one more step (for example Company > Team).

## `defaultCountry` (type: `string`):

Optional two-letter country code, for example US, GB or DE. Used to read local phone numbers written without a country prefix. Leave empty to detect the country from the website's domain ending and language.

## `includeEmptyResults` (type: `boolean`):

Also save a row for websites that could not be opened or showed no email, phone number or social profile, with a status that says why. These rows are free. Turn off to keep only websites with contacts.

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

How many websites to scan at the same time. Pages of one website are always opened one after another.

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

Optional. The Actor works without a proxy. Turn one on only if many websites come back as blocked.

## Actor input object example

```json
{
  "websites": [
    "https://apify.com",
    "https://www.python.org",
    "https://www.mozilla.org"
  ],
  "maxPagesPerWebsite": 10,
  "maxDepth": 2,
  "includeEmptyResults": true,
  "maxConcurrency": 10,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

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

One result per website, with every email found on it.

# 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://apify.com",
        "https://www.python.org",
        "https://www.mozilla.org"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("pipiagent/website-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": [
        "https://apify.com",
        "https://www.python.org",
        "https://www.mozilla.org",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("pipiagent/website-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": [
    "https://apify.com",
    "https://www.python.org",
    "https://www.mozilla.org"
  ]
}' |
apify call pipiagent/website-email-extractor --silent --output-dataset

```

## MCP server setup

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