Website Email & Contact Scraper
Pricing
$8.95 / 1,000 email addresses
Website Email & Contact Scraper
Find public contact emails on websites from URLs or company details. Get one unique, normalized email per row with its source page, plus phones, social links, and addresses when published.
Pricing
$8.95 / 1,000 email addresses
Rating
5.0
(2)
Developer
Maxime Dupré
Maintained by CommunityActor stats
28
Bookmarked
1.3K
Total users
55
Monthly active users
2 days ago
Last modified
Categories
Features
Share
✉️ Find public contact emails from website pages
For sales teams, lead researchers, and developers, Website Emails Scraper finds public contact email addresses on websites. You can give it website URLs or company details. It returns one clean row for each unique, normalized email, with the source page and the website it came from. Rows can also include public phone numbers, social profile links, postal addresses, and an optional mail server (MX) check. This helps you build contact lists without opening every page by hand.
- Collect public contact emails from submitted sites with website email scraper.
- Save each address once with website emails: one row per unique email.
- Check a seed and the pages it links to with website emails: shallow by default.
- Skip repeat addresses and repeat charges with website emails with duplicate-safe billing.
- Test a short seed list before a larger crawl with website emails: small seed list first.
📬 See clean email rows with their source pages
Each saved row has an email address, the page where it was first found, the page title, and the seed URL that led to it. The email is accepted, normalized, and unique within the run. A row can also include public phone numbers with phone checks, social profile links, and a flag for disposable email domains. Turn on the mail server check to see if MX records were found for the email domain.
When available, rows can also include postal addresses, 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
- Open the Input tab. Choose how to supply websites, then add public website URLs or companies.
- Leave the email limit empty or use
0to return all available results until the source is exhausted. Set a positive limit when you want a smaller first run. - Run the Actor and open the dataset from the Output tab.
What happens in a run
The Actor checks each website and follows linked pages allowed by your path and domain settings. By default, it stays within each website. For company details, it first looks for the company website and checks it only when that website publishes the phone number you gave. 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
Choose one way to supply websites with findBy, then fill in the fields for that choice. This example is copied from the public input of a successful current-beta default-input run.
Input example
{"maxNbEmailsToScrape": 10,"findBy": "websiteUrls","urls": [{"url": "https://www.w3.org/contact/"}],"checkMailServer": false,"stayWithinWebsite": true}
Input fields
| Field | Type | What it does |
|---|---|---|
findBy | string | How you supply websites: websiteUrls or companies. Only the fields for that choice are used. Defaults to websiteUrls. |
urls | array of objects | For websiteUrls, a 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[].url | string | A 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. |
companies | array of objects | For companies, a list of companies to look up. The Actor checks contacts only when one website publishes the phone number you gave. A missing or unclear match gets a warning. |
companies[].name | string | Required full company name. |
companies[].phone | string | Company phone number. It is needed to confirm the website. Include the country code when known. |
companies[].city | string | Company city. It helps find the website. |
companies[].address | string | Company street address. It is used when no city is given. |
companies[].country | string | Optional two uppercase letters, such as US or GB, used to read the phone number. Omit it to use phoneCountryCode. |
maxNbEmailsToScrape | integer | Optional 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. |
checkMailServer | boolean | Set true to check each saved email domain for MX records and add domainReachable. Each check has its own small charge. Defaults to false. |
phoneCountryCode | string | Supported 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. |
includePaths | array of strings | Limit linked pages to these path prefixes, such as /contact. Empty or omitted allows all paths; submitted URLs are still checked. |
excludePaths | array of strings | Skip 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. |
stayWithinWebsite | boolean | Keep linked pages within each website. Set false to also check other websites that these pages link to. Defaults to true. |
includeSubdomains | boolean | Set true to allow linked pages across the same domain and its subdomains. false or omitted stays on each website host, with or without www. It applies when stayWithinWebsite is on. |
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. The email limit and page settings apply to every input choice. Path filters do not skip submitted URLs.
🧾 Output
Output fields
Rows from website URLs and company details use this shape.
| Field | Type | What it does |
|---|---|---|
email | string | One accepted, normalized email address. It appears at most once per run. |
url | string | Page URL where the first accepted match was found. |
seedUrl | string | Website URL that produced the row. For company details, this is the matched website. |
pageTitle | string | Published title of the page where the email was found. |
phoneNumbers | array of strings | Public phone or fax numbers in E.164 format found anywhere on the source page, when available. They are not always marked as phone or fax numbers on the page. |
phoneValidation | array of objects | Phone checks for the numbers found, when the country is known. |
phoneValidation[].number | string | Phone number in international E.164 format. |
phoneValidation[].isValid | boolean | Whether the number is valid for its country. |
phoneValidation[].countryCode | string | Two-letter country code of the number. |
socialLinks | array of strings | Public 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. |
addresses | array of strings | Postal addresses published in the website's structured contact data, when available. |
faxNumbers | array of strings | Fax numbers in international format from published structured contact data tied to the email, when available. |
companies | array of objects | Company details from published structured data tied to the email, when available. |
companies[].name | string | Published company name. |
companies[].legalName | string | Legal company name stated by the website. |
companies[].organizationType | string | Organization type stated by the website, such as Organization. |
companies[].logoUrl | string | Link to the logo published by the organization. |
companies[].vatNumbers | array of strings | Published VAT identification numbers. |
companies[].addresses | array of strings | Complete business addresses as published for the company. |
companies[].url | string | Public page that supports the company details. |
contactContext | array of strings | Published text near the email, such as a contact heading or company name, when available. |
isDisposableEmail | boolean | Whether the email domain is on a list of disposable email domains. Left out when this check is not available. |
domainReachable | boolean | Whether MX records were found for the email domain. Present only when checkMailServer is on and the check gives a result. |
Example website row
This complete row came from a successful current-beta run with the mail server check on.
{"url": "https://novacoastmedia.com/","seedUrl": "https://www.novacoastmedia.com/","email": "contact@novacoastmedia.com","companies": [{"name": "Nova Coast Media","url": "https://novacoastmedia.com/","organizationType": "Organization","logoUrl": "https://novacoastmedia.com/wp-content/uploads/2025/08/cropped-Web-NOVA-COAST-MEDIA-LOGO-Sample-White-scaled-2.jpg","addresses": ["92108, San Diego, CA, US"]}],"phoneNumbers": ["+18189341277"],"socialLinks": ["https://www.youtube.com/@RickRyanPhotography","https://www.instagram.com/novacoastmedia","https://www.linkedin.com/company/nova-coast-medias"],"phoneValidation": [{"number": "+18189341277","isValid": true,"countryCode": "US"}],"pageTitle": "Nova Coast Media | San Diego Real Estate Media","addresses": ["92108, San Diego, CA, US"],"isDisposableEmail": false,"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. When checkMailServer is on, each saved email that gets an MX result adds one small domain check event. See the Apify pricing panel for current rates.
Buyer-facing events
Email address
One accepted, unique email address is saved to your dataset.
Domain check
One saved email domain is checked for mail server (MX) records.
Empty searches, failed checks, company lookups, and setup work do not create an 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, postal addresses, and published text near the email when available on the source page. Phone numbers come from the text, phone links, and structured contact data of the source page. Fax numbers written in page text are included. All rows from the same page get the same phone list, and dates are not read as phone numbers.
Can I start from company details instead of a website?
Set findBy to companies and add the company name with its phone number, plus a city or address. The Actor checks a website only when that website publishes the same phone number. If no website matches, or more than one matches, you get a warning and no rows for that company.
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. Turn on checkMailServer to check MX records. 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 websites you supply, from URLs or company details, and finds emails published on those public pages. It does not guess emails from names, and 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 that led to the row. It comes from your URL list or the website matched to your company details.
📝 Actor Release Notes
v10.1 (11-11-2026)
- Phone numbers are now also read from the text of the page, not only from phone links and structured contact data. Fax numbers written in page text are included. Dates are not read as phone numbers.
- A number written without a
+country code is now kept only when it matches a local phone format, including the leading prefix that format needs. Tax IDs, register IDs, and postal codes are no longer returned as phone numbers. Some phone links that leave out the+may no longer appear inphoneNumbers.
v10.0 (30-10-2026)
spreadsheetUrls,datasetIds,websiteField,emailField,idField,keepFields, andonlyMissingEmailare removed.findBynow offers onlywebsiteUrlsandcompanies, so the Actor no longer reads CSV or Excel files or Apify datasets. There is no replacement for reading files or datasets. Remove these keys from saved inputs. To keep checking those websites, list them inurls.recordIdandbusinessFieldsare removed from rows, because they only came from the removed spreadsheet and dataset inputs. There is no replacement. Remove these keys from code that reads results.contactFormUrlsis removed from rows, because it could not be filled reliably on every website. There is no replacement field. Remove this key from code that reads results.companies[].legalForm,companies[].representatives, andcompanies[].registrations, with itscourtandnumberfields, are removed, because they worked only on websites with a matching legal notice layout. There is no replacement field. Remove these keys from code that reads results.- When you submit many websites, each website now gets a turn, so one large website no longer holds up the others.
- If the run stops at its time limit, each website it did not reach gets a warning.
- For company details, you now get a warning when the Actor could not check every possible website, so no match was confirmed.
- Reliability improvements.
v9.0 (29-10-2026)
domainReachableis no longer added by default. The mail server (MX) check now has its own small charge, so you choose when to pay for it. SetcheckMailServertotrueto keep gettingdomainReachable.- Choose how to supply websites with
findBy: website URLs, CSV or Excel files withspreadsheetUrls, Apify datasets withdatasetIds, or company details withcompanies. - For spreadsheet and dataset records, name the website field with
websiteFieldand the email field withemailField. Keep a record ID withidFieldand other fields withkeepFields. Turn ononlyMissingEmailto check only records with no email. Rows then includerecordIdandbusinessFields. - For company details, the Actor checks a website only when one website publishes the phone number you supplied. A missing or unclear match gets a warning.
- Turn off
stayWithinWebsiteto also check pages on other websites that your websites link to. - Rows can now include
pageTitle,addresses,contactFormUrls,isDisposableEmail, andphoneValidation. Company details can include the organization type, legal name, logo URL, and addresses. urlsis no longer required when you use anotherfindBychoice.- A website with a security setup that no browser can connect to is now reported as unavailable with a warning, instead of counting as a failed check.
- Reliability improvements.
v8.0 (26-10-2026)
companies[].legalFormandcompanies[].registrations, with itsnumberandregisterfields, 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
phoneCountryCodenow gets a clear message that names the problem. - Reliability improvements.
v7.0 (26-10-2026)
companies[].representativesis removed. Company details no longer include named representatives. There is no replacement field. Remove this key from code that reads results.companiesandfaxNumbersnow 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
includePathsorexcludePathsto control which linked pages are checked. - Find emails written with
[at]and[dot], including spaces around these parts. - Published addresses such as
support@yourdomain.comandhello@yourdomain.comare no longer skipped just for their names. Reserved example domains are still excluded. - Reliability improvements.
v6.0 (25-10-2026)
emailAssessmentand itsrole,websiteAffiliation,confidence, andexplanationfields are removed. Rows now usecontactContextfor 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.companiesandfaxNumbersare now limited to a narrow set of legal notice pages with a supported contact block. This keeps these details tied to a published contact block. Do not expect these fields from most websites; there is no replacement for them on other sites.- Reading email addresses from click-to-reveal code is now limited to a narrow set of supported pages. 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.confidencenow describes the public page evidence instead of returninglow,medium, orhigh. This gives the basis for the assessment. Update code that reads these ratings to accept text.- Per-site
urls[].userData.maxNbEmailsToScrapelimits are removed. Email limits now apply to the whole run. Remove this key from saved inputs. UsemaxNbEmailsToScrapefor a run-wide limit; there is no per-site replacement. phoneCountryCodenow 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 asgbtoGB, or omit the field to useUS.- Set
maxNbEmailsToScrapeto0to 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.txtare skipped. domainReachablenow 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
proxyConfigurationinput 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.comandhello@yourdomain.comare 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 🫡
🔗 Related Actors
- Website URL Crawler & Link Extractor to find public page URLs that can become seeds for email crawls.
- Product Hunt Launches Scraper to collect product websites and launch pages before checking them for public contact emails.
- Company Domain Finder to find likely company websites from company names before checking them for public emails.
- Uneed Scraper to collect product websites and public contact data before a website email check.
- Email MX Verifier to check syntax and MX records after you collect email addresses.
Made with ❤️ by Maxime Dupré