# Website Email Scraper (`automly/website-email-scraper`) Actor

Find email addresses on any website: the start page plus its contact, about, team, imprint and legal pages, including addresses hidden by email protection or written as name \[at] domain. Bulk website lists, one row per email, and a real-time API.

- **URL**: https://apify.com/automly/website-email-scraper.md
- **Developed by:** [Automly](https://apify.com/automly) (community)
- **Categories:** Lead generation
- **Stats:** 1 total users, 0 monthly users, 0.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $3.00 / 1,000 emails

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.

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 Scraper

### What is Website Email Scraper?

**Website Email Scraper** is a tool that lets you **find email addresses on any website**: it reads the page you give it plus the website's contact, about, team, imprint and legal pages, and returns every address it finds with the page it was on. Paste website links or domains, click **Start**, and download the emails as Excel, CSV or JSON.

- ⚡ **Speed:** 357 websites and 3,291 emails in under 2 minutes in our test
- 🕵️ **Hidden addresses too:** reads emails protected by Cloudflare and addresses written as `name [at] domain [dot] com`
- 🌍 **Contact pages in many languages:** Contact, Kontakt, Impressum, Mentions légales, Contacto, Chi siamo and more
- ✅ **Clean lists:** one row per address per website, lowercase, with image names, placeholders and tracking codes left out
- 🔓 **No login:** no account, API key or browser extension needed

### What can Website Email Scraper do?

- **Extract emails from a list of websites** in one run, from a few to thousands
- **Find contact emails of small businesses**, law firms, clinics, agencies, hotels, universities and local governments
- Scrape email addresses from **contact, about, team, staff, imprint, privacy and support pages** automatically
- **Decode Cloudflare-protected emails** ("\[email protected]" on the page)
- Find **obfuscated emails** such as `info [at] acme [dot] com`, `info(at)acme.de` or `info {at} acme.com`
- Keep **only the website's own addresses** (info@acme.com for acme.com), or also Gmail and other addresses it lists
- Limit the number of **emails per website** and **emails per run**
- Get emails **in seconds over the real-time API**, without starting a run
- Export to Excel, CSV, JSON, HTML or XML, or send them to Google Sheets, Make, Zapier and more

### What data can you extract from websites?

| | | |
|---|---|---|
| ✉️ Email address | 🌐 Email domain | ✔️ Website's own address or not |
| 📄 Page the email was found on | 🏠 Website you entered | 🏷️ Website domain (after redirects) |

### How to scrape emails from websites

1. [Create a free Apify account](https://console.apify.com/sign-up) (no credit card needed).
2. Open **Website Email Scraper**.
3. Paste one or more **website links or domains**, for example `acme.com` or `https://www.w3.org/contact/`, or upload a CSV or text file with your list.
4. Click **Start**.
5. When the run finishes, download the emails as Excel, CSV, JSON, HTML or XML.

### Why use Website Email Scraper?

Compared with the most-used website email scraper on Apify Store (checked against its input settings in September 2026):

| | Website Email Scraper | Most-used alternative |
|---|---|---|
| Limit emails per run and per website | ✅ | ✅ |
| Choose how many pages to read per website | ✅ | ❌ |
| Keep only the website's own addresses | ✅ | ❌ |
| Email domain and "website's own address" columns | ✅ | ❌ |
| List of websites that show no email address | ✅ | ❌ |
| Same input field names (`urls`, `maxNbEmailsToScrape`) | ✅ | ✅ |

You can move an existing input over without changing it.

### ⬇️ Input

Websites can be a domain (`acme.com`), a home page (`https://www.acme.com`) or any page of the site (`https://www.acme.com/contact`). The scraper starts at the page you give and then reads the website's most promising pages for contact details.

| Setting | What it does |
|---|---|
| Website URLs | The websites to find emails on. Paste them, upload a CSV or text file, or link to one |
| Maximum emails | Stop after this many emails for the whole run. Empty = all emails found |
| Maximum emails per website | Keep at most this many emails from each website, the website's own addresses first. Empty = all of them |
| Pages per website | How many pages to read on each website, best first. Default 10, up to 50 |
| Only the website's own emails | Skip addresses at other domains, such as Gmail addresses or a web designer's address |

Example:

```json
{
  "urls": [
    { "url": "https://www.w3.org/contact/" },
    { "url": "https://www.apache.org/foundation/contact" },
    { "url": "https://www.ietf.org/" }
  ],
  "maxPagesPerWebsite": 10,
  "onlyWebsiteDomainEmails": true
}
```

To cap one website only, give it its own limit: `{ "url": "acme.com", "userData": { "maxNbEmailsToScrape": 3 } }`.

### ⬆️ Output

You get one row per email address per website. You can view them as a table in Apify Console or download them as Excel, CSV, JSON, HTML or XML.

```json
{
  "email": "support@ietf.org",
  "emailDomain": "ietf.org",
  "websiteDomain": "ietf.org",
  "sameDomain": true,
  "url": "https://www.ietf.org/contact/",
  "seedUrl": "https://www.ietf.org/",
  "fetchedAt": "2026-09-26T08:55:49Z"
}
```

`seedUrl` is the website exactly as you entered it, so you can join the emails back to your own list. `sameDomain` is `true` when the address is at the website's own domain, including its subdomains: info@mail.acme.com for acme.com, and any stanford.edu address for cs.stanford.edu.

Each run also saves a short report: how many websites and emails it covered, every website it could not read with the reason (for example, a domain that does not exist), and the websites that show no email address at all.

### How can I use website email data?

- **Lead generation:** turn a list of company websites into a list of contact emails for outreach
- **CRM enrichment:** add a contact email to every account that only has a website
- **Local business research:** collect the contact addresses of dentists, lawyers, contractors or hotels in a region
- **Public sector and education contacts:** gather department addresses from city, county and university websites
- **Data cleaning:** check which websites in your list still publish a contact email

### Real-time email finder API

Need a website's emails right away inside your app? Call the actor's API and get them back in the response, without starting a run:

```
GET https://<your-actor-standby-url>/emails?url=acme.com
Authorization: Bearer <YOUR_APIFY_TOKEN>
```

Add `maxPagesPerWebsite`, `maxEmailsPerWebsite` or `onlyWebsiteDomainEmails=true` to the query. Each call reads one website and usually answers in a few seconds; for a list of websites, start a run.

You can also run the actor from your own code with the [Apify API](https://docs.apify.com/api/v2) or the Python and JavaScript clients:

```python
from apify_client import ApifyClient

client = ApifyClient("<YOUR_APIFY_TOKEN>")
run = client.actor("automly/website-email-scraper").call(run_input={
    "urls": [{"url": "https://www.w3.org/contact/"}, {"url": "https://www.ietf.org/"}],
    "onlyWebsiteDomainEmails": True,
})
for row in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(row["seedUrl"], row["email"], row["url"])
```

### ❓FAQ

#### How much does it cost to scrape emails from websites?

You pay only for the emails you get, per 1,000 emails. Websites without an email address cost nothing. See the **Pricing** tab for the current price. Every Apify account gets $5 of free usage each month, so you can try it at no cost.

#### How many emails will I get per website?

It depends on the website. In our test of 357 websites (small businesses, agencies, hotels, universities and local governments), 76% showed at least one email address. A small business usually has one to five addresses; a university or city website can list hundreds.

#### Why did a website return no emails?

Many websites publish only a contact form or a phone number, show their address as an image, or load their contact details only after the page opens in a browser. Those websites are listed in the run report under websites without emails, and they cost nothing.

#### Why was a website listed as failed?

The run report gives the reason for each one: the domain does not exist, the website did not answer in time, or it refused the visit (some websites show visitors a security check). The run continues with the other websites.

#### Which pages does it read?

The page you entered, then the website's own pages whose link or address points to contact details, best first: contact, imprint and legal notice pages, then about, team, staff and support pages, then privacy and terms pages. It stays on the website you entered (or the one it forwards to) and its subdomains: for cs.stanford.edu it reads cs.stanford.edu pages, not the rest of stanford.edu. Set **Pages per website** to read more or fewer pages.

#### Which emails are left out?

Anything that only looks like an email address: image names such as `logo@2x.png`, script and style file names, template placeholders such as `you@example.com` or `john.doe@...`, and codes that error-tracking tools put in pages. Every address is lowercased and appears once per website.

#### What if the same email is on two websites?

You get one row for each website, so every website in your list gets its full set of contacts.

#### Can it find emails hidden from scrapers?

Yes. It reads addresses protected by Cloudflare's email protection, addresses written with HTML codes, and addresses spelled out as `name [at] domain [dot] com`, `name(at)domain.de` or `name {at} domain {dot} com`. In one of our test runs it found 221 Cloudflare-protected and 57 spelled-out addresses that simple email extractors miss.

#### Do I need an account or API key for the websites?

No. It reads only the public pages that anyone can open in a browser.

#### Is it legal to scrape emails from websites?

It collects only addresses that websites publish on their public pages. Addresses that identify a person are personal data under GDPR and similar laws, so only collect and use them for a legitimate reason and follow the anti-spam rules that apply to you. Ask a lawyer if you are unsure. You can read more in [Is web scraping legal?](https://blog.apify.com/is-web-scraping-legal/)

#### Something isn't working. What should I do?

Open the **Issues** tab and tell us the website and what you expected. We usually reply within a day.

# Actor input Schema

## `urls` (type: `array`):

Websites to find emails on: a domain (acme.com) or any page of the site (https://www.acme.com/contact). Upload a text or CSV file or link one to add many at once. To cap one website, add its own maxNbEmailsToScrape under the URL's user data.

## `maxNbEmailsToScrape` (type: `integer`):

Stop after this many emails for the whole run. Leave it empty to get every email found.

## `maxEmailsPerWebsite` (type: `integer`):

Keep at most this many emails from each website. The website's own addresses come first. Leave it empty for all of them.

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

How many pages to read on each website: the page you gave plus its contact, about, team, imprint, legal and support pages, best first. More pages find more addresses on big websites and take longer.

## `onlyWebsiteDomainEmails` (type: `boolean`):

Return only addresses at the website's own domain (info@acme.com for acme.com) and skip others such as Gmail addresses or a web designer's address.

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

The default works for most runs.

## Actor input object example

```json
{
  "urls": [
    {
      "url": "https://www.w3.org/contact/"
    },
    {
      "url": "https://www.apache.org/foundation/contact"
    },
    {
      "url": "https://www.ietf.org/"
    }
  ],
  "maxPagesPerWebsite": 10,
  "onlyWebsiteDomainEmails": false,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

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

No description

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

No description

## `report` (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 = {
    "urls": [
        {
            "url": "https://www.w3.org/contact/"
        },
        {
            "url": "https://www.apache.org/foundation/contact"
        },
        {
            "url": "https://www.ietf.org/"
        }
    ],
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("automly/website-email-scraper").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 = {
    "urls": [
        { "url": "https://www.w3.org/contact/" },
        { "url": "https://www.apache.org/foundation/contact" },
        { "url": "https://www.ietf.org/" },
    ],
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("automly/website-email-scraper").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 '{
  "urls": [
    {
      "url": "https://www.w3.org/contact/"
    },
    {
      "url": "https://www.apache.org/foundation/contact"
    },
    {
      "url": "https://www.ietf.org/"
    }
  ],
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call automly/website-email-scraper --silent --output-dataset

```

## MCP server setup

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

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/TvhrCaR4Wg6VNnbK8/builds/X6pYs0IYzzOYgBLug/openapi.json
