Website Email & Contact Scraper avatar

Website Email & Contact Scraper

Pricing

$8.95 / 1,000 email addresses

Go to Apify Store
Website Email & Contact Scraper

Website Email & Contact Scraper

Find public contact email addresses from the website URLs you submit. Get one unique, normalized email per dataset row with the source and seed URLs attached.

Pricing

$8.95 / 1,000 email addresses

Rating

5.0

(2)

Developer

Maxime Dupré

Maxime Dupré

Maintained by Community

Actor stats

28

Bookmarked

1.3K

Total users

49

Monthly active users

a few seconds ago

Last modified

Share

✉️ Find public contact emails from website pages

For sales teams, lead researchers, and developers who already have public website URLs, Website Emails Scraper finds public contact email addresses. It returns one clean row for each unique, normalized email, with the source page and submitted seed URL. Rows can also include public phone numbers, social profile links, and MX records found for the email domain. This helps you review contact data without opening every page by hand.

📬 See clean email rows with their source pages

Each saved row has an email address, the page where it was first found, and the submitted seed URL. The email is accepted, normalized, and unique within the run. A row can also include public phone numbers, social profile links, and MX records found for the email domain.

When available, rows can also include fax numbers and company details from published structured contact data, plus published text near the email. This text can help you see what the contact is for. It does not prove mailbox delivery.

🚀 Crawl a small set of pages first

Quick start

  1. Open the Input tab and add public website URLs.
  2. Leave the email limit empty or use 0 to return all available results until the source is exhausted. Set a positive limit when you want a smaller first run.
  3. Run the Actor and open the dataset from the Output tab.

What happens in a run

The Actor checks submitted public URLs and follows linked pages allowed by your path and domain settings. It can read public contacts shown through JavaScript and common email forms such as (at) and (dot). A blocked or unreadable page does not show whether the site has an email, and it does not create a saved email row. Pages blocked by robots.txt are skipped. The first eligible occurrence of each normalized email is saved. Later matches are ignored, so they do not create another row.

⚙️ Input

Add one or more public website URLs. This example is copied from the public input of a successful current-beta default-input run.

Input example

{
"urls": [
{
"url": "https://www.w3.org/contact/"
}
],
"maxNbEmailsToScrape": 10
}

Input fields

FieldTypeWhat it does
urlsarray of objectsRequired list of one or more public website URLs to check. The form prefills the one URL in the example; this is not a schema default.
urls[].urlstringA public HTTP or HTTPS website URL. A bare domain is also accepted and uses HTTPS. The Actor checks it and follows linked pages within your path and domain settings.
maxNbEmailsToScrapeintegerOptional maximum number of accepted emails for the whole run. Use a positive integer to set a limit. Leave it empty or use 0 to return all available results until the source is exhausted. The form prefills 10; this is not a schema default.
phoneCountryCodestringSupported country code with two uppercase ISO letters for local phone numbers, such as US, GB, CA, AU, DE, FR, or IN. Omit it to use US. Numbers that start with + keep their own country code.
includePathsarray of stringsLimit linked pages to these path prefixes, such as /contact. Empty or omitted allows all paths; submitted URLs are still checked.
excludePathsarray of stringsSkip linked pages with these path prefixes, such as /privacy. Empty or omitted skips none; submitted URLs are still checked. Exclusions take precedence over included paths.
includeSubdomainsbooleanSet true to allow linked pages across the same domain and its subdomains. false or omitted stays on each submitted URL's host, with or without www.

Input rules

Set the email limit for the whole run to a positive integer. Leave it empty or use 0 to return all available results until the source is exhausted. Path filters do not skip submitted URLs.

🧾 Output

Output fields

FieldTypeWhat it does
emailstringOne accepted, normalized email address. It appears at most once per run.
urlstringPage URL where the first accepted match was found.
seedUrlstringSubmitted website URL that produced the row.
phoneNumbersarray of stringsPublic phone numbers found on the source page, when available.
socialLinksarray of stringsPublic social profile links found on the source page, when available. Excludes post, reel, story, video, sharing, and intent links. The URL host identifies the platform.
domainReachablebooleanWhether MX records were found for the email domain. This field is omitted when the check is unavailable.
faxNumbersarray of stringsFax numbers in international format from published structured contact data tied to the email, when available.
companiesarray of objectsCompany details from published structured data tied to the email, when available.
companies[].namestringPublished company name.
companies[].vatNumbersarray of stringsPublished VAT identification numbers.
companies[].addressesarray of stringsComplete business addresses as published for the company.
companies[].urlstringPublic page that supports the company details.
contactContextarray of stringsPublished text near the email, such as a contact heading or company name, when available.

Output example

This complete row came from a successful current-beta run. It shows a saved email with contact text, phone numbers, social profile links, and MX status.

{
"url": "https://www.hetzner.com/legal/legal-notice/",
"seedUrl": "https://www.hetzner.com/legal/legal-notice/",
"email": "info@hetzner.com",
"contactContext": [
"E-Mail: info@hetzner.com"
],
"phoneNumbers": [
"+4998315050",
"+4998315053"
],
"socialLinks": [
"https://www.facebook.com/hetzner.de/",
"https://www.instagram.com/hetzner.online/",
"https://www.youtube.com/user/HetznerOnline/",
"https://twitter.com/Hetzner_Online/",
"https://www.linkedin.com/company/hetzner-online/"
],
"domainReachable": true
}

💳 Pricing

This Actor uses pay-per-event pricing. You are charged one event for each accepted, unique email address saved to the default dataset. See the Apify pricing panel for current rates.

Buyer-facing event

Email address

One accepted, unique email address is saved to your dataset.

Empty searches, failed checks, and setup work do not create an email event. There is no separate Actor-start event in the pricing configuration. Duplicate addresses do not create another event.

🔌 Integrations

Review rows in the Apify Console, read the default dataset with the Apify API, or export the dataset. This short guide shows a connected Actor workflow:

❓ FAQ

Will the Actor return phone numbers or nearby page text?

It saves accepted, normalized email addresses. A row can also include public phone numbers, social profile links, and published text near the email when available on the source page.

What happens when the same email appears on more than one page?

The Actor saves the first eligible occurrence of a normalized address. Later matches are ignored, so the saved row keeps the first source page and seed URL. Later matches do not create another row or charged event.

How far does it crawl?

It checks submitted URLs and follows links from each page it reads, within your path and domain settings. There is no fixed link-depth limit. Pages that cannot be read or are blocked by robots.txt can limit coverage. Use path filters and an email limit to keep a run focused. If the run gets close to its time limit, it stops early, keeps the saved emails, and logs a warning. Increase the run timeout to check more pages.

Can I limit the number of emails?

Yes. Set the email limit for the whole run to a positive integer. Leave it empty or use 0 to return all available results until the source is exhausted.

What if a submitted URL has no email or cannot be read?

Only accepted emails from public pages are saved. A blocked or unreadable page does not show whether the site has an email, and a missing row by itself does not explain why no email was saved.

Check the run logs to tell an empty search from a failed check. Other websites can keep running when one website cannot be checked. A run can fail if unresolved access errors prevent all website checks. Confirmed unavailable websites can end with no rows and a warning.

Does it access private pages or verify mailboxes?

No. It reads public pages only. MX records show that the email domain can route mail; they do not show that a specific mailbox is active or accepts messages.

How does this differ from an email finder?

This Actor starts with website URLs you submit and finds emails published on those public pages. It does not find websites by keyword.

What do url and seedUrl mean?

url is the page where the first accepted email match was found. seedUrl is the website URL you submitted that led to the row.


📝 Actor Release Notes

v8.0 (26-10-2026)

  • companies[].legalForm and companies[].registrations, with its number and register fields, are removed. These fields only covered a narrow set of German company data. There is no replacement field. Remove these keys from code that reads results.
  • Phone numbers now come only from phone links and structured contact data on the page. Numbers written only as plain page text are no longer returned.
  • Emails are read only from page content that is shown to visitors. Emails in hidden page parts are no longer returned.
  • A website that is down for every visitor, such as one that keeps returning a server error or closing the connection, is now reported as unavailable with a warning. It no longer fails the run by itself.
  • Linked pages that do not finish loading are skipped, so the run keeps checking other pages.
  • If the run gets close to its time limit, it stops early, keeps the saved emails, and logs a warning.
  • An unsupported phoneCountryCode now gets a clear message that names the problem.
  • Reliability improvements.

v7.0 (26-10-2026)

  • companies[].representatives is removed. Company details no longer include named representatives. There is no replacement field. Remove this key from code that reads results.
  • companies and faxNumbers now come from structured contact data published on the page. Company details need a published legal name and a matching email. A legal notice alone no longer provides these fields. Handle missing company and fax details in code that reads results.
  • Emails from click-to-reveal code and encoded page data are no longer read directly. Emails can still be found in public text, email links, supported structured contact data, or rendered content. Do not rely on encoded data alone to provide an email.
  • Linked pages are checked throughout the crawl within your path and domain settings, rather than only from links on the submitted page. Set includePaths or excludePaths to control which linked pages are checked.
  • Find emails written with [at] and [dot], including spaces around these parts.
  • Published addresses such as support@yourdomain.com and hello@yourdomain.com are no longer skipped just for their names. Reserved example domains are still excluded.
  • Reliability improvements.

v6.0 (25-10-2026)

  • emailAssessment and its role, websiteAffiliation, confidence, and explanation fields are removed. Rows now use contactContext for published text near an email link, when available, instead of contact assessments. Update code that reads assessments to handle this text array. It does not provide assessed roles, website links, or confidence ratings.
  • companies and faxNumbers are now limited to contacts in Hetzner's /legal/legal-notice/ page. This keeps these details tied to that page's published contact block. Do not expect these fields from other websites; there is no replacement for them on other sites.
  • Reading email addresses from click-to-reveal code is now limited to new.fileditch.com/contact.html. Other pages can still return emails from public text, email links, structured page data, or rendered content. Do not rely on click-to-reveal code on other sites.
  • Phone numbers can be read across line breaks and in more local formats. Legal reference numbers are no longer read as phone numbers.
  • Published email addresses for outside contacts are no longer skipped just because nearby text names an authority or website designer.
  • Separate links and lines are no longer joined to make an email address. Federated social handles are no longer read as emails.

v5.0 (25-10-2026)

  • emailAssessment.confidence now describes the public page evidence instead of returning low, medium, or high. This gives the basis for the assessment. Update code that reads these ratings to accept text.
  • Per-site urls[].userData.maxNbEmailsToScrape limits are removed. Email limits now apply to the whole run. Remove this key from saved inputs. Use maxNbEmailsToScrape for a run-wide limit; there is no per-site replacement.
  • phoneCountryCode now requires a supported uppercase country code. Unsupported or lowercase values stop the run without checking websites, so invalid phone settings are not used. Update saved inputs, such as gb to GB, or omit the field to use US.
  • Set maxNbEmailsToScrape to 0 to leave the run-wide email count unlimited.
  • Contact assessments can include roles from a published Inquiry / Contact table and a general inquiry address marked “if in doubt.” These assessments use first-party email addresses.
  • Reliability improvements.

v4.1 (09-10-2026)

  • Email rows can include fax numbers and company details from public legal notices.
  • Email rows can include a contact role or website link assessment based on public page evidence.
  • Social profile links exclude more content and sharing links.
  • Find emails written with (at) and (dot).
  • Linked contact and about pages are no longer limited to the first nine matches.

v4.0 (08-10-2026)

  • Choose a country code to read local phone numbers.
  • Filter linked contact and about pages by path and, if needed, include subdomains.
  • Find emails in structured page data and some click-to-reveal links.
  • Pages blocked by robots.txt are skipped.
  • domainReachable now reports whether MX records were found.
  • emailRole, which used the email name as a role label, is removed. There is no replacement in this version. Remove this field from code that reads results.
  • Runs need at least 2048 MB of memory.

v3.0 (07-10-2026)

  • Runs now need at least 512 MB of memory.
  • You can enter a website domain without adding https://.

v2.1 (27-09-2026)

  • Email rows can include public phone numbers, social profile links, domain reachability, and email role context when available.
  • Reliability improvements.

v2.0 (10-09-2026)

  • The proxyConfiguration input is removed because the Actor now manages access to public pages. Remove this key from saved inputs; there is no replacement setting.
  • Fixed template addresses such as support@yourdomain.com and hello@yourdomain.com are not saved or charged.

v1.0 (05-09-2026)

  • You can limit emails for each website. Other valid sites keep running if one site fails.
  • Each accepted email includes the page where it was found and the website URL you submitted.

v0.0

  • Initial release.

🆘 Support

For issues, questions, or feature requests, file a ticket and I'll fix or implement it in less than 24h 🫡



Made with ❤️ by Maxime Dupré