# Free Email Domain Scraper - Extract Emails From Any Website (`scrapers-hub/free-email-domain-scraper`) Actor

Free Email Domain Scraper crawls any website and extracts every public email address per domain, with a configurable per-domain cap. 📧 A zero-cost way to build outreach lists, enrich CRM records and find contact addresses fast.

- **URL**: https://apify.com/scrapers-hub/free-email-domain-scraper.md
- **Developed by:** [Scrapers Hub](https://apify.com/scrapers-hub) (community)
- **Categories:** Lead generation, Automation, Developer tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.99 / 1,000 results

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?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

### 📧 Free Email Domain Scraper – Extract Emails From Any Website Domain

The Free Email Domain Scraper extracts email addresses from any website you point it at, taking a plain list of domains and returning every contact address it can find published on those sites. Feed it `microsoft.com`, `nu.nl` or a thousand domains exported from your CRM, and it returns a flat two-column dataset of domain and email — the simplest possible shape for lead lists, contact enrichment and outreach pipelines.

Most email extraction tools want a URL, a crawl depth, a regex and a coffee break. This email domain scraper wants a domain name. It fetches the homepage, harvests any addresses it finds in the markup and in `mailto:` links, then follows the pages where companies actually publish contact details — contact, about, support, help, press, media, privacy, legal, corporate, imprint and terms pages — until it has collected as many emails as you asked for. No headless browser, no login, no cookies.

***

### 📊 What Data Can You Extract with This Email Domain Scraper?

The output schema is intentionally minimal. Each dataset item is one email address attributed to one domain.

| Category | Fields | What it gives you |
| --- | --- | --- |
| 🌐 Source domain | `domain` | The domain the address was harvested from, echoed on every row so results stay joinable to your input list |
| ✉️ Contact address | `email` | A single email address discovered on that domain's public pages |
| 🔗 Attribution | `domain` + `email` | Together these form the unit of the dataset — one row per address per domain, never a comma-joined blob |
| 📥 Volume control | governed by `max_emails_per_domain` | How many addresses at most are returned for each domain in your list |
| 📤 Export shape | flat two-field records | Two scalar columns, so a CSV export drops straight into a spreadsheet or a CRM importer |

The genuinely useful property here is the one-row-per-email structure. Many email scrapers return an array of addresses stuffed into a single cell, which then has to be split before it is usable. Because this scraper emits a separate record for every address, deduplicating by `email`, counting addresses per `domain`, or joining the results back onto an account list are all one-line operations in SQL or a spreadsheet.

***

### 🌟 Key Features of the Email Domain Scraper

| Feature | Description |
| --- | --- |
| 📋 Bulk domain input | Pass an array of domains in one run — the scraper processes each in turn and attributes every address it finds back to its source domain |
| 🧭 Contact-page discovery | After reading the homepage, it identifies internal links containing keywords such as contact, about, support, help, press, media, privacy, legal, corporate, imprint and terms, then scrapes those pages too |
| 🔗 mailto link harvesting | Addresses hidden behind `mailto:` hyperlinks are extracted from the `href` attribute, catching contacts that never appear as visible page text |
| ✂️ Per-domain cap | `max_emails_per_domain` stops the scraper as soon as it has enough addresses for a domain, which keeps runs short and results focused |
| 🧪 Address validation | Candidate strings are checked against a validity filter before being emitted, cutting obvious non-addresses out of the results |
| 🛡️ Browser impersonation | Requests are made through `curl_cffi` with a Chrome fingerprint, which gets past the basic bot checks that block naive HTTP clients |
| 🔀 Redirect handling | Redirects are followed automatically, so domains that bounce to `www`, to HTTPS or to a regional variant still resolve to the right site |
| 🚫 No browser overhead | There is no headless Chrome in the loop, so runs are fast and cheap compared with rendering-based email extractors |
| 📤 Standard Apify exports | Results land in an Apify dataset, downloadable as JSON, CSV, XLSX, XML or HTML, or retrievable through the API |

***

### 🚀 Why Choose This Email Domain Scraper?

**Domains in, emails out.** There is no crawl configuration to tune, no start-URL list to assemble and no selector to write. The only two decisions you make are which domains to process and how many addresses you want per domain, which makes this email scraper usable by a sales operations analyst as easily as by an engineer.

**It looks where contact details actually live.** Homepages rarely carry an email address. The scraper's link-discovery step deliberately targets the pages that do — contact, about, support, press, imprint and legal pages — which is why it finds addresses that homepage-only extractors miss entirely.

**A hard budget per domain.** The `max_emails_per_domain` setting is a genuine stop condition, not a post-filter. Once the cap is reached for a domain the scraper stops fetching further subpages for it, so a run over a large domain list stays predictable in both duration and cost.

**Flat output that needs no post-processing.** Two fields, one row per email. You can import a CSV export into a CRM, run a `SELECT DISTINCT email` over it, or pivot address counts by domain without writing a single line of transformation code.

***

### 📥 Input

The email domain scraper takes a list of domains and an optional per-domain limit.

```json
{
  "domains": [
    "microsoft.com",
    "nu.nl",
    "bol.com"
  ],
  "max_emails_per_domain": 10
}
```

#### 🔧 Email Domain Scraper Input Fields

| Field | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `domains` | array | ✅ Yes | prefilled with `microsoft.com`, `nu.nl`, `bol.com` | List of domains to scrape. Entered as a string list, one domain per line. |
| `max_emails_per_domain` | integer | ❌ No | `10` | Maximum number of emails to extract per domain. The scraper stops fetching pages for a domain once this many addresses have been collected. |

#### 💡 Input Examples

**Quick single-domain check**

```json
{
  "domains": ["logitech.com"],
  "max_emails_per_domain": 5
}
```

**Wide sweep across a prospect list**

```json
{
  "domains": [
    "microsoft.com",
    "bol.com",
    "nu.nl",
    "logitech.com"
  ],
  "max_emails_per_domain": 25
}
```

**Minimal input using the default limit**

```json
{
  "domains": ["example.com", "example.org"]
}
```

***

### 📤 Output

Each dataset item pairs one email address with the domain it was found on. Below is a real item from an actual run of the email domain scraper.

```json
{
  "domain": "logitech.com",
  "email": "core@2.11.8"
}
```

That example is also a useful warning. Email extraction works by pattern matching over page source, and some strings in modern web bundles — version identifiers, sourcemap references, template placeholders — are shaped exactly like email addresses. The scraper filters obvious non-addresses, but a validation pass on your side is still worth running before anything hits an outreach tool.

#### 🧾 Email Domain Scraper Output Fields

| Field | Type | Description |
| --- | --- | --- |
| `domain` | string | null | Domain name the address was harvested from |
| `email` | string | null | Email address found on that domain's public pages |

Because there is one item per address, a run over five domains with a cap of ten returns at most fifty rows. Group by `domain` to see coverage, and deduplicate on `email` to build a clean sending list.

***

### 💻 How to Use the Email Domain Scraper (Step by Step)

#### Step 1: Open the Email Scraper on Apify

Sign in to Apify and open the Free Email Domain Scraper Actor. Everything runs on Apify's platform, so there is no local installation, no Python environment to build and no dependency to keep patched. The Actor page presents a simple input form, a live run log, and the dataset where results accumulate as the run progresses.

#### Step 2: Paste In Your Domain List

Click the **Domains** field and enter the domains you want to scrape, one per line. Bare domains such as `microsoft.com` work best; the scraper prepends `https://` automatically and follows redirects from there. If you are pasting a column from a spreadsheet, strip any protocol prefixes and trailing paths first so each line is a clean hostname.

#### Step 3: Set Your Per-Domain Email Limit

Decide how many addresses you want from each domain and set `max_emails_per_domain` accordingly. The default of `10` is a sensible balance for lead generation: enough to capture the general enquiry address plus a few departmental ones, without spending time crawling every legal page on a large corporate site. Raise it when you are researching a small number of domains in depth, lower it when you are sweeping thousands.

#### Step 4: Start the Run

Press **Start** and watch the log. The scraper works through your domains sequentially, fetching each homepage, harvesting addresses from the markup and from `mailto:` links, then visiting the contact-style subpages it discovered. Domains that fail to respond are logged with a warning and skipped, so a single unreachable site never stops the whole run.

#### Step 5: Inspect the Dataset

Open the **Dataset** tab to see the two-column result table. Scan a few rows per domain to gauge quality: a good result set usually contains a general enquiry address, sometimes a press or support alias, and occasionally an individual's address published on a team page. Anything that looks like a version number or a template variable is a pattern-matching artefact worth filtering out.

#### Step 6: Clean and Deduplicate

Before using the results, deduplicate on `email` and apply a validation check. Remove addresses at obviously non-contact domains, strip anything that fails a syntax check, and consider dropping catch-all patterns that will not reach a person. This step takes minutes and dramatically improves the deliverability of anything you send afterwards.

#### Step 7: Export or Automate

Download the cleaned dataset as CSV for a one-off campaign, or wire the Actor into a recurring workflow. Apify's scheduler can re-run the email scraper on a cadence, and integrations or webhooks can push each finished run straight into Google Sheets, a CRM or your own service.

***

### 🔌 API Access & Integrations

Trigger the email domain scraper and get the dataset back in the same HTTP call:

```bash
curl -X POST "https://api.apify.com/v2/acts/scrapers-hub~free-email-domain-scraper/run-sync-get-dataset-items?token=YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "domains": ["microsoft.com", "bol.com"],
    "max_emails_per_domain": 10
  }'
```

The same thing with the official Python client:

```python
from apify_client import ApifyClient

client = ApifyClient("YOUR_TOKEN")

run = client.actor("scrapers-hub/free-email-domain-scraper").call(
    run_input={
        "domains": ["microsoft.com", "bol.com", "nu.nl"],
        "max_emails_per_domain": 10,
    }
)

seen = set()
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    email = item.get("email")
    if email and email not in seen:
        seen.add(email)
        print(item["domain"], "→", email)
```

Results can also be routed automatically to Zapier, Make, Google Sheets and Slack, or delivered to any HTTP endpoint you control using Apify webhooks triggered on run completion.

***

### 💡 Best Use Cases for Email Domain Data

#### 🎯 B2B Lead Generation

Take a list of target-account domains from your ICP research and run it through the email domain scraper to build a first-contact list. Because each row carries both `domain` and `email`, the results map one-to-one onto accounts already in your CRM, so enrichment is a join rather than a manual matching exercise.

#### 🤝 Partnership and Business Development Outreach

Business development teams routinely need the right inbox at hundreds of companies. Scraping the contact, press and corporate pages surfaces the general and departmental aliases that companies actually monitor, which reach a human far more reliably than guessed patterns like `firstname.lastname@`.

#### 📰 PR and Media Contact Discovery

Publications and brands publish press addresses on dedicated media pages. Running a list of publisher domains and keeping the results whose `email` local part looks editorial gives PR teams a targeted media list without paying for a subscription database.

#### 🛒 Supplier and Vendor Sourcing

Procurement researchers can turn a directory of supplier domains into a contactable list in one run. Setting `max_emails_per_domain` low keeps the output to the primary enquiry addresses, which is exactly what an initial RFQ needs.

#### 🧹 CRM Data Enrichment and Hygiene

Accounts in a CRM often have a domain but no working contact address. Run the stale domains through the scraper and use the `domain` field to write results back onto the matching records, replacing bounced addresses with ones currently published on the site.

#### 🔬 Market and Competitor Research

Analysts mapping a sector can collect published contact points across an entire competitive set, then look at patterns: which companies publish direct addresses versus contact forms, which use departmental aliases, and which have no reachable address at all. Those signals say something about company size and maturity.

#### 🧾 Compliance and Imprint Verification

In several European jurisdictions, sites must publish an imprint with a contact address. Because the scraper explicitly visits imprint and legal pages, it can be used to check at scale whether a portfolio of domains carries a reachable published contact.

***

### ⚙️ Tips for Better Email Scraping Results

- **Submit bare hostnames.** Enter `example.com` rather than `https://example.com/en/contact`. The scraper builds the URL and follows redirects itself, and clean hostnames avoid landing on a page with no outbound contact links.
- **Tune the cap to your goal.** A limit of 3–5 is right for wide prospecting sweeps; 20–30 makes sense when you are researching a handful of domains thoroughly. A high cap on a large list mostly buys you duplicate aliases.
- **Always validate before sending.** Pattern-based extraction can pick up strings that merely look like addresses. Run a syntax and MX check on the output before it reaches any email platform, or you will damage your sending reputation.
- **Split very large domain lists.** Rather than one enormous run, break the list into batches of a few hundred domains and schedule them. Batches finish sooner, fail smaller, and are easier to re-run selectively.
- **Expect nothing from contact-form-only sites.** Many companies deliberately publish no address. An empty result for a domain is usually a true negative, not a scraper failure.
- **Deduplicate across the whole run, not per domain.** Shared corporate aliases can appear under multiple domains in a portfolio. A global `DISTINCT` on `email` prevents the same inbox being contacted several times.

***

### 🛠️ Troubleshooting

**A domain returned no emails at all — is something broken?**
Usually not. Plenty of sites publish only a contact form, use JavaScript to assemble their address, or render contact details as an image. The scraper reads server-returned HTML, so addresses that only exist after client-side rendering will not be found.

**Why did I get results that are clearly not email addresses?**
Extraction is pattern-based over page source, and build artefacts such as version strings can match the pattern. The included validity filter removes obvious cases but not all of them — apply a stricter validation pass before using the list.

**The run finished with far fewer rows than domains submitted.**
Rows are only emitted where an address was found, so domains with no published contact simply contribute nothing. Check the run log for warnings naming domains that failed to load, which indicates a network or blocking issue rather than an empty site.

**Some domains time out or are skipped.**
Requests use a fixed timeout, and slow or geo-restricted sites can exceed it. Failures are logged as warnings and the run continues. Re-run just the failed domains in a smaller batch — they often succeed on a second attempt.

**Can I get more addresses from a domain I care about?**
Raise `max_emails_per_domain` and run that domain on its own. The cap is what stops the scraper visiting further contact-style subpages, so a higher limit means a deeper sweep of that one site.

***

### ❓ Frequently Asked Questions About Email Domain Scraping

**What does the Free Email Domain Scraper do?**
It is an email domain scraper that takes a list of domains, visits each site's homepage and contact-style subpages, and returns every publicly published email address it finds as a flat list of `domain` and `email` pairs.

**Which pages does the email scraper actually visit?**
It starts at the domain's homepage, then follows internal links whose URLs contain keywords such as contact, about, support, help, press, media, privacy, legal, corporate, imprint and terms — the pages where contact details are normally published.

**Do I need to provide full URLs or just domains?**
Just domains. Enter `example.com` and the scraper builds the request itself, defaulting to HTTPS and following any redirects. Full URLs are also accepted if they already begin with `http`.

**How many emails will I get per domain?**
At most `max_emails_per_domain`, which defaults to `10`. The actual number depends entirely on how much contact information the site publishes — many domains yield one or two addresses, some yield none.

**Does the scraper find addresses hidden in mailto links?**
Yes. It reads `href` attributes on anchor tags and extracts addresses from `mailto:` links, which catches contacts that are never rendered as visible text on the page.

**Are the extracted emails verified or deliverable?**
No. The scraper reports what is published on the site and applies a basic validity filter. It performs no MX lookup, no SMTP probe and no deliverability check, so run your own verification before sending.

**Why does an email look like a version number?**
Some strings in JavaScript bundles and sourcemaps happen to match the shape of an email address. This is an inherent limitation of pattern-based extraction; filter the output before use.

**Can I scrape thousands of domains in one run?**
The `domains` array has no fixed cap, but domains are processed sequentially, so very large lists take a long time. Splitting into scheduled batches of a few hundred is more reliable and easier to resume.

**Does this email scraper need proxies or cookies?**
No. It makes direct HTTP requests with a Chrome browser fingerprint via `curl_cffi`, and requires no login, cookies or credentials of any kind.

**Will it find personal addresses of individual employees?**
Only if those addresses are published on the site's own public pages, for example on a team or press page. The scraper does not access directories, private databases or any authenticated source.

**What formats can I export the results in?**
Apify datasets export to JSON, CSV, XLSX, XML, RSS and HTML, and the same data is available programmatically through the dataset API endpoint.

**Can I schedule the email domain scraper to run automatically?**
Yes. Use Apify's scheduler to run it on any cron expression, and attach a webhook or an integration so completed runs push results to Google Sheets, Slack, Zapier, Make or your own endpoint.

**Does it use a headless browser?**
No. It uses plain asynchronous HTTP requests with browser impersonation, which is why runs are fast and inexpensive relative to rendering-based email extraction tools.

**How do I join results back to my account list?**
Join on the `domain` field, which is present on every row and matches the value you submitted. This makes writing results back into a CRM or a warehouse table straightforward.

**Is scraping published email addresses legal?**
Collecting publicly published data is generally permitted, but how you subsequently use email addresses is regulated — particularly under the GDPR and equivalent laws. Ensure you have a lawful basis for contact and honour opt-outs.

***

### 🆘 Support & Feedback

Hit a bug, or seeing consistently poor extraction on a particular type of site? Open a ticket on the **Issues** tab of this Actor and include the run ID plus an example domain — reports filed there are tracked and fixed fastest.

Need a custom version of this email domain scraper — deeper crawling, role-based address classification, verification built in, or delivery straight into your own database? Email **scraperhubapi@gmail.com** with your requirements.

If the Free Email Domain Scraper is useful to you, please leave a review on the Actor page. Ratings and written feedback determine what gets improved next.

***

### ⚖️ Disclaimer

This email domain scraper collects only publicly published information from websites you specify. It does not log in, bypass authentication, defeat access controls or read anything that is not served to an ordinary visitor of the site.

You are responsible for how you use the extracted data. Email addresses frequently constitute personal data, so if you process them under the GDPR, the UK GDPR, the CCPA, PECR, CAN-SPAM or comparable regimes, you must establish a lawful basis for contact, provide clear identification and opt-out mechanisms in every message, respect suppression requests, and apply sensible retention limits. Unsolicited bulk email may be unlawful in your recipients' jurisdictions even where the address itself was public.

Respect the terms of service of every website you scrape and comply with all applicable laws and regulations. An address appearing in these results means it was published on a public page, not that its owner consented to receiving marketing.

If you believe your personal data has been collected through this Actor and you would like it removed, contact **scraperhubapi@gmail.com** and we will handle the request.

# Actor input Schema

## `domains` (type: `array`):

List of domains to scrape

## `max_emails_per_domain` (type: `integer`):

Maximum number of emails to extract per domain

## Actor input object example

```json
{
  "domains": [
    "microsoft.com",
    "nu.nl",
    "bol.com"
  ],
  "max_emails_per_domain": 10
}
```

# Actor output Schema

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

Records scraped by Free Email Domain Scraper - Extract Emails From Any Website, stored in the run's default dataset.

# 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 = {
    "domains": [
        "microsoft.com",
        "nu.nl",
        "bol.com"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("scrapers-hub/free-email-domain-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 = { "domains": [
        "microsoft.com",
        "nu.nl",
        "bol.com",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("scrapers-hub/free-email-domain-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 '{
  "domains": [
    "microsoft.com",
    "nu.nl",
    "bol.com"
  ]
}' |
apify call scrapers-hub/free-email-domain-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,scrapers-hub/free-email-domain-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/3yXCprg4FnzzCalwq/builds/Qt5pNplV1yUTYfA0G/openapi.json
