Website Contact & Email Scraper: Emails, Phones & Socials avatar

Website Contact & Email Scraper: Emails, Phones & Socials

Pricing

from $17.00 / 1,000 results

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

Website Contact & Email Scraper: Emails, Phones & Socials

Turn company websites into contacts. Per site, extract public emails, phones, WhatsApp, 15 social profiles (LinkedIn, X, Facebook, Instagram, YouTube, TikTok and more), contact people, company name and address, plus the page each contact came from. Export to JSON, CSV or Excel.

Pricing

from $17.00 / 1,000 results

Rating

0.0

(0)

Developer

Scrapers Lat

Scrapers Lat

Maintained by Community

Actor stats

0

Bookmarked

5

Total users

2

Monthly active users

7 days ago

Last modified

Share

Website Contact & Email Scraper

Website Contact & Email Scraper

Here is one real result (the addresses, contacts and pagesScanned arrays are trimmed to the first entries to keep the example short; all values are real):

{
"website": "https://stripe.com",
"originalStartUrl": "stripe.com",
"domain": "stripe.com",
"companyName": "Stripe",
"description": "Stripe is a financial services platform that helps all types of businesses accept payments, build flexible billing models, and manage money movement.",
"emails": ["jane.diaz@stripe.com", "sales@stripe.com"],
"phones": [],
"phonesUncertain": ["+13024732533"],
"whatsapp": null,
"telegram": null,
"linkedin": "https://www.linkedin.com/company/stripe",
"twitter": "https://twitter.com/stripe",
"facebook": "https://www.facebook.com/StripeHQ",
"instagram": "https://www.instagram.com/stripehq",
"youtube": "https://youtube.com/@stripe",
"tiktok": null,
"pinterest": null,
"github": "https://github.com/stripe",
"discord": null,
"contactName": "John Collison",
"contactJobTitle": null,
"contactPersons": [
{ "name": "John Collison", "jobTitle": null, "email": null },
{ "name": "Patrick Collison", "jobTitle": null, "email": null }
],
"address": "354 Oyster Point Blvd, South San Francisco, CA 94080, US",
"addresses": ["354 Oyster Point Blvd, South San Francisco, CA 94080, US"],
"contacts": [
{ "type": "email", "value": "jane.diaz@stripe.com", "sourceUrl": "https://stripe.com/contact", "depth": 1 }
],
"contactPageUrls": ["https://stripe.com/contact"],
"aboutPageUrls": ["https://stripe.com/about"],
"foundContactDetails": true,
"sourceUrl": "https://stripe.com/contact",
"pagesScanned": ["https://stripe.com/", "https://stripe.com/contact", "https://stripe.com/about"],
"pagesFailed": 0,
"emailVerification": null,
"source": "Website Contacts",
"observedAt": "2026-08-25T14:39:53.311Z"
}

The most complete website contact scraper on Apify. Give it a list of company websites and it returns one clean record per site with the public business emails, phone numbers, WhatsApp and Telegram, 15 social platforms (LinkedIn, Twitter/X, Facebook, Instagram, YouTube, TikTok, Pinterest, GitHub, Discord, Snapchat, Threads, Reddit, Yelp, Google Business), contact people with job titles, postal address, company name and description, and the exact page each contact was found on. It gives you more input filters, more valid output fields and wider social coverage than any competing actor, runs HTTP-only for speed, and only charges for records it actually returns.

📥 Input · 📤 Output · 💰 Pricing · ▶️ Examples

Apify Coverage Output Billing

Table of contents

What it does

Give the actor a list of company websites. For each one it reads the homepage plus a few likely contact, about, and team pages, and extracts the public business emails, phone numbers, WhatsApp click-to-chat number, social profiles, and postal addresses it can find. It returns one clean, deduplicated record per website. Emails are validated and stripped of placeholder and asset noise (no example.com, no image filenames), addresses are read from structured JSON-LD data, and the pagesScanned list records exactly which pages produced the contacts. Missing values are returned as null or empty arrays, never invented.

This is a lead-enrichment tool: feed it domains from any list and get back contact records ready for a CRM.

How we compare

An objective look at this actor next to the most popular website contact and email extractors on the Apify Store. Every claim below reflects each actor's own public listing.

CapabilityThis actorvdrmota contact-info-scraperpracticaltools contact-details-scraperautomation-lab website-contact-details-extractorcreative_tablecloth extract-email-phone-social
Input filters15 (depth, page cap, same-domain, subdomains, include/exclude URL globs, paths, concurrency, renderJs, dry run and more)~12~8~61
Emails + phonesYes, plus low-confidence phonesUncertainYesYesYesYes
Social platforms15 (LinkedIn, X, Facebook, Instagram, YouTube, TikTok, Pinterest, GitHub, Discord, Snapchat, Threads, Reddit, Yelp, Google Business, plus WhatsApp and Telegram)~14~988 (incl. Yelp, Google)
Per-contact source URL + depthYes, on every email and phone (contacts[])No (domain-level)Page-level onlyNoNo
Contact person name + job titleYes, native (contactPersons[])Paid enrichment add-onNoNoNo
Company name + postal addressYesPartialNoYesNo
Contact / about page URLsYesNoNoYesNo
Email deliverability checkOptional MX add-onPaid add-onNoNoNo
Cloudflare / WAF pagesOptional solver (renderJs)Optional browserHeadless browserNoNo
EngineHTTP-only (fast)HTTP or browserHeadless browserHTTP-onlyNot disclosed
No charge on empty / failed runYesCharges per page scannedCharges per resultCharges per recordRental plus usage
Spend cap (maxTotalChargeUsd)Yes, enforcedNot advertisedNot advertisedNot advertisedNot advertised
PricingPay per result (see pricing tab)~$0.00105 per page~$0.0045 per result~$0.0036 per website plus start feeRental ~$20 per month plus usage

Where a competitor genuinely wins: several actors are cheaper per record. automation-lab at roughly $0.0036 per website and practicaltools at roughly $0.0045 per result undercut our per-result price, and creative_tablecloth is cheapest of all on a rental. We do not try to be the cheapest. We return more valid fields per record (per-contact source URL and depth, contact people, wider social coverage, company and address), run HTTP-only so a large list finishes faster, and never charge for an empty or failed run, so the cost per usable contact is lower even when the sticker price per record is higher.

Quickstart

Open the actor, paste this into the input, and press Run. It enriches two websites, scanning up to 6 pages each.

{
"maxWebsites": 10,
"websites": ["stripe.com", "apify.com"],
"maxPagesPerSite": 6
}

Enter each website as a bare domain or a full URL. Every input field is optional except that at least one website must be provided.

Input reference

FieldTypeRequiredDefaultDescription
websitesstring[]yes*["stripe.com", "apify.com"]One or more company websites to enrich. Enter a domain (example.com) or a full URL. Each website returns one contact record.
startUrlsobject[]no(empty)Same as websites, in Apify start-URL format ({"url": "https://example.com"}). Merged with websites.
domainstringno(empty)A single domain to enrich, in addition to or instead of the list above.
pathsstring[]no(empty)Extra paths visited on every website, for example /contact, /about-us.
maxWebsitesintegerno10Maximum number of websites to enrich in this run.
maxPagesPerSiteintegerno6Pages to read per website (homepage plus likely contact, about, and team pages). Range 1 to 30. Aliases: maxPagesPerDomain, maxCrawlPages.
maxDepthintegerno1Link-hops to follow within a site. 0 = homepage only, 1 = homepage plus its linked contact/about pages, 2+ = deeper. Range 0 to 4.
sameDomainOnlybooleannotrueOnly crawl pages on the same domain as each seed.
includeSubdomainsbooleannofalseAlso crawl subdomains (for example blog.example.com).
includeUrlGlobsstring[]no(empty)Only crawl page URLs matching these globs (supports * and ?).
excludeUrlGlobsstring[]no(empty)Skip page URLs matching these globs.
stopWhenContactsFoundbooleannotrueStop crawling a site once enough contacts are found. Faster.
renderJsbooleannofalseFor Cloudflare / AWS WAF pages, route the request through our browser solver. Paid plans only.
withEmailVerifybooleannofalsePaid add-on: check each email domain MX records and return a deliverability status.
concurrencyintegerno8Websites enriched in parallel. Range 1 to 10.
dryRunbooleannofalseParse and return records without charging the result event.

*At least one website (via websites, startUrls, or domain) must be provided.

Output reference

One dataset item per website. Types: string, string[], object, or null when the value is absent.

FieldTypeDescription
websitestringNormalized site origin, for example https://stripe.com.
originalStartUrlstringThe website/URL exactly as provided in the input.
domainstringBare domain with www. stripped.
companyNamestringCompany name from page metadata, or null.
descriptionstringShort company description from meta tags (up to 400 characters), or null.
emailsstring[]Validated public business emails (up to 50). Empty array when none found.
phonesstring[]Phone numbers from tel: links (up to 25). Empty array when none.
phonesUncertainstring[]Phone-like numbers found in page text (lower confidence, up to 25).
whatsappstringWhatsApp click-to-chat number, or null.
telegramstringTelegram profile or channel URL, or null.
linkedinstringLinkedIn company or profile URL, or null.
twitterstringTwitter/X profile URL, or null.
facebookstringFacebook page URL, or null.
instagramstringInstagram profile URL, or null.
youtubestringYouTube channel URL, or null.
tiktokstringTikTok profile URL, or null.
pintereststringPinterest profile URL, or null.
githubstringGitHub organization or user URL, or null.
discordstringDiscord invite URL, or null.
snapchatstringSnapchat profile URL, or null.
threadsstringThreads profile URL, or null.
redditstringReddit profile or community URL, or null.
yelpstringYelp business URL, or null.
googleBusinessstringGoogle Business / Maps profile URL, or null.
contactNamestringPrimary contact person name from JSON-LD, or null.
contactJobTitlestringPrimary contact person job title, or null.
contactPersonsobject[]Contact people with name, jobTitle, and email when published.
addressstringFirst postal address found, or null.
addressesstring[]Postal addresses parsed from JSON-LD (up to 10).
contactsobject[]Every email and phone with the sourceUrl and depth it was found on.
contactPageUrlsstring[]Scanned pages identified as contact pages.
aboutPageUrlsstring[]Scanned pages identified as about/team pages.
foundContactDetailsbooleanTrue when any email, phone, WhatsApp, or main social was found.
sourceUrlstringPage URL where the primary contact was found.
pagesScannedstring[]The exact page URLs the actor read for this website.
pagesFailedintegerNumber of pages that could not be fetched.
emailVerificationobject[]Per-email MX deliverability results (only with the withEmailVerify add-on), else null.
sourcestringData source label: Website Contacts.
observedAtstringISO 8601 timestamp of when the record was collected.
errorstringPresent only when a website could not be fetched.

Example output record

See the hero example at the top of this page. It is a real record from a live run with input {"maxWebsites": 10, "websites": ["stripe.com", "apify.com"], "maxPagesPerSite": 6}, with the addresses and pagesScanned arrays trimmed for readability. A live run returns every address found and the full list of scanned pages.

Run via API and CLI

Start a run and wait for it to finish, then read the dataset. Replace <TOKEN> with your Apify API token.

Run synchronously and get dataset items in one call:

curl -X POST "https://api.apify.com/v2/acts/scrapers_lat~website-contacts-scraper/run-sync-get-dataset-items?token=<TOKEN>" \
-H "Content-Type: application/json" \
-d '{"websites":["stripe.com","apify.com"],"maxPagesPerSite":6}'

Start a run asynchronously:

curl -X POST "https://api.apify.com/v2/acts/scrapers_lat~website-contacts-scraper/runs?token=<TOKEN>" \
-H "Content-Type: application/json" \
-d '{"websites":["acme.com","globex.com","initech.com"],"maxWebsites":50}'

Apify CLI:

apify call scrapers_lat/website-contacts-scraper \
--input '{"domain":"stripe.com","maxPagesPerSite":10}'

Fetch results

Every run writes to a dataset. Fetch items as JSON, CSV, or Excel by changing format:

# JSON
curl "https://api.apify.com/v2/datasets/<DATASET_ID>/items?token=<TOKEN>&clean=true&format=json"
# CSV
curl "https://api.apify.com/v2/datasets/<DATASET_ID>/items?token=<TOKEN>&clean=true&format=csv"
# Paginate large datasets
curl "https://api.apify.com/v2/datasets/<DATASET_ID>/items?token=<TOKEN>&offset=1000&limit=1000"

<DATASET_ID> is returned as defaultDatasetId in the run object. Use offset and limit to page through large result sets. clean=true drops empty and internal fields.

Billing and limits

  • Pay per result. You are charged per website record returned (result event). See the pricing tab for the current per-result price.
  • Optional email verification add-on. Turn on withEmailVerify (paid plans) to check each email domain MX records. Charged per record only when at least one email is verified, never on failure.
  • No charge on failure. If a website cannot be fetched, the record is written with a populated error field. Empty runs cost nothing.
  • Spend cap respected. Set maxTotalChargeUsd on the run; once reached, the actor stops emitting and charging further billable results.
  • Free Apify plans are capped at 10 websites per run, and paid add-ons (withEmailVerify, renderJs) are disabled. Upgrade for higher maxWebsites and add-ons.

FAQ and troubleshooting

Which pages does it read? The homepage plus likely contact, about, and team pages (up to maxPagesPerSite). The exact URLs read are listed in pagesScanned on each record.

How are emails validated? Emails are matched from mailto: links and page text, then filtered to remove placeholders (example.com, yourdomain), asset filenames, and tracking noise, so you only get real business addresses.

Why are some fields null or empty? The website did not publish that contact publicly on the pages scanned. Missing values are returned as null or empty arrays, never invented. Raise maxPagesPerSite to search more pages.

Can I enrich many domains at once? Yes. Pass an array of domains in websites (each returns one record) and raise maxWebsites.

Is this an official tool of the websites scraped? No. This actor is independent and reads only data that is publicly available on each website. Use it in accordance with each site's terms of service and applicable law.

More scrapers at scrapers.lat

Built and maintained by scrapers.lat, where we publish scrapers for US and Latin American public platforms: company registries, government data, finance, e-commerce and more. Browse the catalog or request a custom scraper at scrapers.lat.


Independent tool. Reads only data that is publicly available on each website. Use in accordance with each site's terms of service and applicable law.