Website Email Address Scraper avatar

Website Email Address Scraper

Pricing

from $1.45 / 1,000 contact extracteds

Go to Apify Store
Website Email Address Scraper

Website Email Address Scraper

Extract displayed website emails and same-page phones with source evidence, deduplication, role and suspicious flags, syntax checks, and mail-domain DNS verification.

Pricing

from $1.45 / 1,000 contact extracteds

Rating

0.0

(0)

Developer

Stas Persiianenko

Stas Persiianenko

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

6 days ago

Last modified

Categories

Share

Extract each displayed website email address from supplied public company and organization websites, match phone numbers shown on the same pages, remove duplicates, classify shared inboxes, and verify email syntax and mail-domain DNS.

The Actor returns one source-attributed row per unique website and email pair. It is built for recurring lead-list cleanup where evidence and accuracy matter more than collecting unsupported guesses.

What this website email finder does

For every supplied website, the Actor:

  1. fetches the supplied page;
  2. follows a bounded set of same-site contact, about, team, support, privacy, sales, and legal links;
  3. extracts emails from visible text, mailto: links, and common [at] / [dot] obfuscation;
  4. associates phones displayed on the same source pages;
  5. deduplicates repeated occurrences of the same email on one website;
  6. flags role-based and obviously suspicious inboxes;
  7. checks normalized syntax and the email domain's MX or address-fallback DNS records; and
  8. saves source URLs and a short discovery context with every result.

It does not invent emails from employee names or company-domain patterns.

Who is it for?

  • Sales operations teams cleaning company URL lists before CRM import.
  • Lead researchers who need cited public evidence for every contact.
  • Recruiters and partnerships teams finding displayed business inboxes and phones.
  • Data teams normalizing contact data into JSON, CSV, Excel, or a warehouse.
  • Agencies running the same bounded extraction process across client-provided websites.
  • Compliance-conscious teams that need a distinction between domain verification and mailbox deliverability.

Why use this website email extractor

A simple page regex often loses the source page, repeats footer addresses, accepts test inboxes, or calls an address “deliverable” without evidence.

This Actor adds a reusable cleanup layer:

  • one normalized contact row per website/email pair;
  • all observed source pages retained in sourceUrls;
  • same-page phones instead of unrelated site-wide phone guesses;
  • explicit roleBased, role, suspicious, and suspiciousReasons fields;
  • MX and RFC-compatible address-fallback checks;
  • no SMTP mailbox probing and no misleading mailbox-valid claim;
  • bounded crawling and limits suitable for scheduled runs; and
  • SSRF protection that rejects local and private-network targets.

What data is extracted

FieldMeaning
websiteUrlSupplied public website URL
websiteDomainNormalized supplied website domain
emailNormalized displayed email address
emailDomainDomain part of the email
sourceUrlFirst page where the email appeared
sourceUrlsEvery crawled page where that email appeared
phoneNumbersPhones shown on those same source pages
contextShort visible text or link context
roleBasedWhether the address is a common shared inbox
roleRecognized role such as sales or support
suspiciousObvious fake, placeholder, test, or no-reply signal
suspiciousReasonsReasons behind the suspicious classification
syntaxValidSyntax validation result; emitted rows are valid
domainStatusmx, address-fallback, no-mail-records, or dns-error
domainAcceptsMailDNS evidence that the domain can accept mail
mxRecordsOrdered mail exchanger hostnames
verificationLevelsyntax-and-domain or syntax-only
mailboxDeliverabilityAlways not-tested
scrapedAtISO 8601 extraction timestamp

How to run the Actor

  1. Open the Actor input page.
  2. Add one or more real public company or organization URLs to Company website URLs.
  3. Keep the default page and depth limits for a normal contact-page crawl.
  4. Enable Exclude role-based inboxes when the downstream list requires person-like inboxes only.
  5. Keep Exclude suspicious inboxes enabled for normal cleanup work.
  6. Run the Actor.
  7. Open the Verified contacts dataset view.
  8. Export JSON, CSV, Excel, XML, or connect the dataset API to your pipeline.

The prefilled input uses real public organization contact pages and produces useful contact rows.

Input parameters

startUrls

Required list of public HTTP or HTTPS pages. Strings and request-list objects are accepted. Duplicate URLs are removed. URLs with credentials, local hostnames, literal private IPs, or domains resolving to non-public addresses are rejected.

maxItems

Maximum deduplicated email rows across the run. Default: 100. Range: 1 to 10,000.

maxPagesPerWebsite

Maximum fetched pages for each supplied website. Default: 8. Range: 1 to 50.

maxDepth

Maximum relevant-link depth from the supplied page. Default: 2. Use 0 to inspect only the supplied page.

includeSubdomains

Allows relevant links on subdomains of the supplied website. External domains are never crawled. Default: false.

excludeRoleBased

Skips recognized shared inboxes such as info@, sales@, support@, billing@, and webmaster@. Default: false, so these useful business contacts remain available with flags.

excludeSuspicious

Skips obvious fake, test, placeholder, no-reply, reserved-domain, and example inboxes. Default: true.

proxyConfiguration

Optional Apify Proxy settings. Direct HTTP is the default. The Actor does not silently turn on residential traffic or a browser fallback.

Example input

{
"startUrls": [
{ "url": "https://www.apache.org/foundation/contact" },
{ "url": "https://www.gnu.org/contact/" }
],
"maxItems": 50,
"maxPagesPerWebsite": 5,
"maxDepth": 1,
"excludeRoleBased": false,
"excludeSuspicious": true
}

For a strict CRM cleanup, set excludeRoleBased to true.

Example output

This shortened record reflects the current output shape from a real public contact page:

{
"websiteUrl": "https://www.apache.org/foundation/contact",
"websiteDomain": "apache.org",
"email": "press@apache.org",
"emailDomain": "apache.org",
"sourceUrl": "https://www.apache.org/foundation/contact",
"sourceUrls": ["https://www.apache.org/foundation/contact"],
"phoneNumbers": [],
"context": "press@apache.org",
"roleBased": true,
"role": "press",
"suspicious": false,
"suspiciousReasons": [],
"syntaxValid": true,
"domainStatus": "mx",
"domainAcceptsMail": true,
"verificationLevel": "syntax-and-domain",
"mailboxDeliverability": "not-tested",
"scrapedAt": "2026-08-30T06:41:11.690Z"
}

Download the default dataset as CSV when the final deliverable needs spreadsheet columns.

How deduplication and matching work

The deduplication key is the normalized website plus normalized email address.

When the same email appears on a home page and contact page, the Actor emits one row, retains both pages in sourceUrls, and unions phones from pages where that email was actually displayed.

The same shared address can still appear once for each separately supplied website. This preserves company attribution instead of globally discarding a valid repeated contact.

maxItems applies after filtering and deduplication. Rejected, duplicate, suspicious-filtered, and role-filtered values are not charged as contact results.

What email verification means

Verification has two bounded levels:

  • Syntax: the normalized address has a valid-looking local part and multi-label domain.
  • Domain DNS: the domain publishes MX records, or it has an RFC-compatible A/AAAA fallback when no MX record exists.

domainStatus: "no-mail-records" means DNS does not currently show a mail route. dns-error means the DNS check could not produce a definitive result.

The Actor does not send email, open SMTP conversations, verify a named mailbox, check catch-all policy, or promise delivery. mailboxDeliverability is therefore always not-tested.

How much does it cost to extract verified website contacts?

Pay-per-event pricing consists of a $0.005 start fee per run plus one contact event for each deduplicated contact row saved.

The current BRONZE contact rate is $0.002416 per contact. Higher-volume tiers decrease from FREE through DIAMOND.

Approximate BRONZE examples before optional proxy infrastructure:

Saved contactsStart feeContact eventsTotal
1$0.005$0.002416$0.007416
25$0.005$0.0604$0.0654
100$0.005$0.2416$0.2466
1,000$0.005$2.4160$2.4210

Actual billed event rates follow your Apify pricing tier. Optional proxy traffic and platform compute are separate infrastructure usage where applicable.

Recurring lead-list cleanup workflow

A repeatable workflow can be built without adding unsupported monitoring claims:

  1. keep the company website list in a dataset, spreadsheet, or key-value input;
  2. schedule this Actor daily, weekly, or monthly;
  3. export the current contact rows;
  4. compare the new dataset to the previous run in your own pipeline;
  5. route added, removed, or DNS-status-changed rows for review; and
  6. write accepted contacts into the CRM.

The Actor produces timestamped snapshots. Apify schedules runs; change detection is performed by your downstream automation.

API usage with cURL

Start a run and wait for dataset results:

curl -X POST \
"https://api.apify.com/v2/acts/automation-lab~verified-website-contact-extractor/run-sync-get-dataset-items?token=$APIFY_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"startUrls": [{"url": "https://www.apache.org/foundation/contact"}],
"maxItems": 10,
"maxPagesPerWebsite": 2
}'

Keep $APIFY_TOKEN in a secret or environment variable, never in source control.

API usage with JavaScript

import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('automation-lab/verified-website-contact-extractor').call({
startUrls: [{ url: 'https://www.apache.org/foundation/contact' }],
maxItems: 10,
maxPagesPerWebsite: 2,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);

API usage with Python

import os
from apify_client import ApifyClient
client = ApifyClient(os.environ["APIFY_TOKEN"])
run = client.actor("automation-lab/verified-website-contact-extractor").call(
run_input={
"startUrls": [{"url": "https://www.apache.org/foundation/contact"}],
"maxItems": 10,
"maxPagesPerWebsite": 2,
}
)
items = client.dataset(run["defaultDatasetId"]).list_items().items
print(items)

Use through Apify MCP

Add the Actor to Claude Code:

claude mcp add --transport http apify \
"https://mcp.apify.com?tools=automation-lab/verified-website-contact-extractor"

Claude Desktop

Add this remote MCP server in Claude Desktop's connector settings.

Cursor and VS Code

Cursor and VS Code MCP clients can use this JSON configuration:

{
"mcpServers": {
"apify": {
"url": "https://mcp.apify.com?tools=automation-lab/verified-website-contact-extractor"
}
}
}

Example prompts:

  • “Extract displayed emails and same-page phones from these company websites and show the source URL.”
  • “Run a strict cleanup that excludes role-based and suspicious inboxes.”
  • “Return only contacts whose domain DNS indicates a mail route.”

Integrations and exports

The default dataset works with:

  • CSV and Excel exports for manual review;
  • Google Sheets through an Apify integration or automation platform;
  • webhooks triggered after successful runs;
  • Make, Zapier, n8n, and custom ETL jobs;
  • Apify API clients in JavaScript and Python; and
  • dataset-to-database loading for CRM or warehouse enrichment.

Use sourceUrl as the evidence link and email plus websiteDomain as a stable downstream key.

Limits and failure behavior

  • Only anonymously reachable public HTML or plain-text pages are supported.
  • JavaScript-only contact details may not be present in server-rendered HTML.
  • CAPTCHA, authentication, consent walls, robots policy, or stable HTTP errors can prevent a page fetch.
  • The crawler follows only relevant same-site links and stops at the configured page/depth limits.
  • It does not crawl an entire domain, submit forms, log in, or solve challenges.
  • One failed page is logged while other supplied websites continue.
  • If no supplied website can be fetched, the run fails instead of reporting a misleading empty success.
  • A successful run can legitimately contain zero rows when fetched pages display no valid email.
  • DNS changes and transient resolver errors can change verification status between runs.

Legality and responsible use

Extract only contacts intentionally displayed on public pages you are permitted to access.

You are responsible for complying with website terms, robots policies, privacy and data-protection law, direct-marketing rules, anti-spam law, and the lawful basis required for your intended use. A public email address is not automatic consent for unsolicited outreach.

Use suppression lists, honor opt-outs, minimize retention, protect exports, and avoid sensitive or personal targeting. Do not use the Actor to access private networks, authenticated data, or pages you do not have permission to process.

Troubleshooting

Why did a website produce no contacts?

Confirm that its displayed email is present in server-rendered HTML, raise maxPagesPerWebsite if the contact page is deeper, and inspect the run log for HTTP or content-type errors. A visible browser page may still render its contact details only with JavaScript.

Why was info@ returned?

Role inboxes are retained by default and labeled because many business workflows want them. Enable excludeRoleBased to skip recognized shared inboxes.

Why is a valid-looking address syntax-only?

Its domain had no usable mail route or the DNS lookup was inconclusive at run time. The field does not mean the mailbox was contacted.

Why are there no phone numbers for a row?

Phones are matched only when displayed on a source page where the email also appeared. The Actor does not attach an unrelated phone from another page.

Should I enable a proxy?

Use direct mode first. Enable an appropriate Apify Proxy configuration only for sites you are authorized to access that reject the direct route. There is no hidden automatic residential fallback.

FAQ

Does it guess employee email addresses?

No. It exports only addresses displayed in fetched public page content or email links.

Does it verify mailbox deliverability?

No. It validates syntax and mail-domain DNS. mailboxDeliverability explicitly remains not-tested.

Yes. Repeated occurrences on one website become one row with merged source URLs and same-page phones.

Can it process multiple domains in one run?

Yes. Add multiple startUrls and set a suitable global maxItems limit.

Can I schedule it?

Yes. Use Apify schedules and compare timestamped output snapshots in your downstream workflow.

Does it charge for rejected duplicates?

No. The contact event is emitted only for a deduplicated row saved to the default dataset.

Choose this Actor when the input is a website list and the required output is one cleaned, source-attributed email row with same-page phone evidence.