Website Contact Scraper: Emails, Phones & Socials avatar

Website Contact Scraper: Emails, Phones & Socials

Pricing

from $2.00 / 1,000 website with contacts

Go to Apify Store
Website Contact Scraper: Emails, Phones & Socials

Website Contact Scraper: Emails, Phones & Socials

Extracts company contact details from a list of websites: role email addresses such as info@ and sales@, phone numbers and social media links. One row per website, and you pay only for websites where a contact was found. Follows robots.txt and leaves out personal addresses.

Pricing

from $2.00 / 1,000 website with contacts

Rating

0.0

(0)

Developer

Enis Bodlli

Enis Bodlli

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

2 days ago

Last modified

Share

Website Contact Scraper

Turn a list of company websites into a contact list. This website contact scraper reads each site's home page and its contact, about, imprint and legal pages, and returns one row per website with the company's email addresses, phone numbers and social media links. To try it, leave the three sample websites in the input and click Start: the run takes a few seconds.

You pay only for websites where a contact was found. A website with no contact, a site that blocks the visit and a domain that does not exist still get a row, so you can see they were checked, and cost nothing.

It returns company contact points, not people: shared mailboxes such as info@, sales@ or kontakt@, the company's phone numbers and its company pages on social networks. Addresses that look like a person's (firstname.lastname@) are left out and counted.

What you can do with a website contact scraper

  • Build a lead list from domains. Feed in the websites of companies you want to reach and get the general email address, the phone number and the contact page of each.
  • Fill gaps in a CRM. Add the missing email, phone or LinkedIn company page to accounts that only have a website.
  • Find the right channel. contactPageUrl points to the contact form when a company publishes no email address.
  • Check a list of domains. The status of each row tells a working site from one that is gone or that refuses automated visits.
  • Call it from code or an AI agent. Start the Actor through the Apify API and read the rows as JSON.

How to extract emails and phone numbers from websites

  1. Paste the websites under Websites, one per line, as domains (example.com) or URLs. Through the API, pass them as an array.
  2. Optionally change Maximum pages per website, or switch phone numbers or social links off.
  3. Click Start. Each website's row is saved as soon as that website is done, so a run you stop keeps what it finished.
  4. Open the Output tab and export the table as JSON, CSV or Excel, or read it through the API.

Pricing

You pay per website with at least one contact found (an email address, a phone number or a social media link):

Apify planPer 1,000 websites with contactsPer website
Free, Bronze$3.00$0.003
Silver$2.50$0.0025
Gold$2.00$0.002

Plus $0.00005 per run start. Platform usage is included, so there is nothing else to pay. The price does not depend on how many pages are read: a website is charged once.

  • 1,000 websites, 640 of them with a contact: 640 charges. That is $1.92 on the Free and Bronze plans, $1.60 on Silver and $1.28 on Gold. The other 360 websites are in the results at no cost.
  • 50 websites, 31 of them with a contact: 31 charges, $0.093 on the Free and Bronze plans.

Repeated domains are removed before the run, so no website is charged twice. A website is charged at the moment its row is saved. A run that is stopped, fails or is restarted continues where it left off: websites that already have a row are skipped, so they are not charged again.

You can set a maximum charge per run. The Actor then starts a website only while that limit has room for it, stops when the limit is reached, and reports how many websites it did not check.

Input

FieldWhat it does
Websites (websites)The websites to read. Required. Domains or URLs, up to 10,000 per run. Repeated domains are removed; the first entry counts. Only pages on the website's own domain (and its subdomains) are read.
Maximum pages per website (maxPagesPerSite)The home page plus the most likely contact pages. Default 8, at most 20.
Include phone numbers (includePhones)Default on. When off, phones is an empty list.
Include social media links (includeSocialLinks)Default on. When off, every entry of socialLinks is null.

Example:

{
"websites": ["hetzner.com", "basecamp.com", "g2.com"],
"maxPagesPerSite": 5,
"includePhones": true,
"includeSocialLinks": true
}

Output

One row per website, with the contacts from all its pages merged. domain identifies the row. Below is the result of the example input, from a run on 2026-10-04: a website with contacts, one without, and one that refuses automated visits. Only the first is charged.

[
{
"website": "hetzner.com",
"domain": "hetzner.com",
"status": "ok",
"statusReason": "Found 2 emails, 5 phone numbers and 5 social links on 4 pages. 3 personal-looking addresses left out.",
"emails": ["info@hetzner.com", "contact-fi@hetzner.com"],
"personalEmailsSkipped": 3,
"phones": [
{ "text": "+49 (0)9831 505-0", "digits": "4998315050" },
{ "text": "+358 (0)753259-0", "digits": "3587532590" },
{ "text": "+49 (0) 911 234226-100", "digits": "49911234226100" },
{ "text": "+49 (0) 3745 74447-100", "digits": "49374574447100" },
{ "text": "+358 753259-100", "digits": "358753259100" }
],
"socialLinks": {
"linkedin": "https://www.linkedin.com/company/hetzner-online",
"facebook": "https://www.facebook.com/hetzner.de",
"instagram": "https://www.instagram.com/hetzner.online",
"x": "https://x.com/Hetzner_Online",
"youtube": "https://www.youtube.com/user/HetznerOnline",
"tiktok": null,
"github": null
},
"contactPageUrl": "https://www.hetzner.com/support/",
"pageTitle": "Günstige Dedicated Server, Cloud & Hosting aus Deutschland",
"pagesCrawled": 4,
"checkedAt": "2026-10-04T13:12:09.893Z"
},
{
"website": "basecamp.com",
"domain": "basecamp.com",
"status": "no_contacts_found",
"statusReason": "No company email, phone number or social link on 2 pages. 1 personal-looking address left out.",
"emails": [],
"personalEmailsSkipped": 1,
"phones": [],
"socialLinks": { "linkedin": null, "facebook": null, "instagram": null, "x": null, "youtube": null, "tiktok": null, "github": null },
"contactPageUrl": null,
"pageTitle": "Basecamp",
"pagesCrawled": 2,
"checkedAt": "2026-10-04T13:12:09.639Z"
},
{
"website": "g2.com",
"domain": "g2.com",
"status": "blocked",
"statusReason": "The home page could not be read: HTTP 403 (access denied to automated visits).",
"emails": [],
"personalEmailsSkipped": 0,
"phones": [],
"socialLinks": { "linkedin": null, "facebook": null, "instagram": null, "x": null, "youtube": null, "tiktok": null, "github": null },
"contactPageUrl": null,
"pageTitle": null,
"pagesCrawled": 0,
"checkedAt": "2026-10-04T13:12:09.449Z"
}
]
FieldMeaning
websiteThe website as you entered it.
domainIts host name in lower case, without www.. One row per domain.
statusok, no_contacts_found, blocked or unreachable. See below.
statusReasonOne sentence saying why.
emailsShared and role addresses of the company, lower-cased, without repeats, addresses on the website's own domain first. At most 25.
personalEmailsSkippedHow many addresses were left out because they are not recognisably a shared mailbox.
phonesUp to 10 phone numbers: text as the site shows it, digits with digits only. An international number starts with its country code.
socialLinksThe company's page on LinkedIn, Facebook, Instagram, X, YouTube, TikTok and GitHub, or null.
contactPageUrlThe website's contact page, or null.
pageTitleTitle of the home page.
pagesCrawledHow many pages were read.
checkedAtWhen the website was checked (UTC).

Websites are read in parallel, so rows can be in a different order than your list. Match them on domain. A summary of the run (websites per status, charges, entries that were skipped) is saved as RUN_SUMMARY in the run's key-value store.

What each status means

StatusMeaningCharged
okAt least one email address, phone number or social link was found.Yes
no_contacts_foundThe site was read and shows no company contact point on the pages visited.No
blockedThe site refused the visit: HTTP 401, 403 or 429, a CAPTCHA or JavaScript challenge, or a robots.txt rule.No
unreachableThe domain does not exist, the server did not answer in time, or the home page returned an error.No

Limits

  • Personal-looking addresses are left out. An address is returned only when the part before the @ is a function or a department, in English and the major European languages. A name (jane.smith@), initials, a single first name, or any word the Actor does not know is not returned, only counted in personalEmailsSkipped. The purpose is company contact points, not personal data about individuals. This also drops some harmless addresses with unusual names.
  • Sites that block automated visits are reported, not forced. The Actor sends plain requests from Apify's servers under its own name (website-contact-scraper). It uses no proxies and no browser and solves no CAPTCHAs. A refusal is final, with one exception: when a site answers "too many requests" and names a wait of up to 30 seconds, the Actor waits that long and asks again. A site that refuses comes back as blocked.
  • JavaScript-only sites may show nothing. Pages that build their content in the browser arrive empty. They come back as no_contacts_found, with a note in statusReason.
  • Addresses a site hides on purpose are not decoded, for example Cloudflare email protection or info (at) example.com.
  • Phone numbers are taken from phone links and from numbers next to a label such as "Tel" or "Phone", or written in international form. Fax and mobile numbers, and numbers on team pages, are left out. A number without a label in a national format can be missed.
  • Pages read: the home page and the contact, about, imprint, legal and team pages linked from it, on the same domain. Privacy policies and terms are skipped, because the addresses there mostly belong to others. After 90 seconds no further page of a website is requested, and a page larger than 5 MB is not read.
  • Social links are the profiles a site links to. Personal profiles such as LinkedIn /in/ are skipped; on other networks a company page and a personal one look the same.

FAQ

The Actor reads public pages of the websites you list, the same pages a visitor sees. It follows each site's robots.txt, does not log in anywhere and does not get around blocks. It returns company contact points and leaves out addresses that look like a person's. What you do with the results is your responsibility: whether and how you may contact a company depends on the laws that apply to you and to them, such as rules on unsolicited email.

Why is there no email for a website?

Many companies publish only a contact form. Look at contactPageUrl. If personalEmailsSkipped is above zero, the site lists addresses that were left out. If statusReason mentions JavaScript, the site needs a browser.

Why is a website "blocked"?

The site answered a plain, identified request with a refusal. Large consumer sites often do. The Actor reports this and moves on; the row costs nothing.

Can I get the addresses of named people?

No. This Actor returns shared mailboxes only.

How long does a run take?

A website takes a few seconds, and ten are read at a time. In a test on 2026-10-04, 15 company websites from twelve countries took 10 seconds. A site that does not answer takes about a minute before it is reported as unreachable.

Can I check whether the addresses work?

Yes, with Email Validator & List Cleaner, which checks syntax and whether the domain receives mail.

Where do I report a problem?

Open an issue on the Issues tab of this Actor. Name the website and say what you expected to find on it. Issues are answered there.

More Actors from this developer

Contacts and lists:

Jobs:

Company registers: