Website Contact Extractor — Emails, Phones & Socials avatar

Website Contact Extractor — Emails, Phones & Socials

Pricing

from $5.00 / 1,000 website processeds

Go to Apify Store
Website Contact Extractor — Emails, Phones & Socials

Website Contact Extractor — Emails, Phones & Socials

Website contact extractor: MX-checked email, phone and social links for every domain on your list. Plain HTTP, no login. Pay per site.

Pricing

from $5.00 / 1,000 website processeds

Rating

0.0

(0)

Developer

Mohammed Samaan

Mohammed Samaan

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

2

Monthly active users

12 days ago

Last modified

Share

Website Contact Extractor

Already have a list of websites? Get the contacts behind them — MX-checked emails, phone numbers, and social profiles — one clean row per site, no browser needed.

Who it's for

  • Anyone who exported a domain list from a CRM, directory, or conference attendee sheet and needs the actual contacts behind each site
  • SDRs and recruiters enriching a list they already have rather than discovering businesses from scratch
  • Agencies and researchers who need phone + social + email in one pass

What you get

FieldWhat it is
websiteThe input site/domain
emailBest available email
emailStatusvalid / risky-role / invalid
phoneBest available phone number
facebook / instagram / linkedin / twitterSocial profile links, when includeSocials is on
allEmailsEvery email found, each tagged with its status
allPhonesEvery phone number found
emailCountHow many emails were found
extractedAtISO timestamp

Example output

One real row from a run on potent.com.au (a small Australian marketing agency). Note that phone here is wrong: the page contains numbers that are not telephone numbers and the matcher accepted them (see "Errors and limits"). It is shown as returned, not edited.

{
"website": "potent.com.au",
"email": "enquiries@potent.com.au",
"emailStatus": "risky-role",
"contactName": null,
"contactRole": null,
"phone": "33.33333333",
"facebook": "https://www.facebook.com/potentweb",
"instagram": "https://www.instagram.com/potentweb",
"linkedin": null,
"twitter": null,
"allEmails": "enquiries@potent.com.au (risky-role); updates@potent.com.au (valid); support@potent.com.au (risky-role)",
"allPhones": "33.33333333; 41.66666667; 58.33333333; 66.66666667; 00000026",
"emailCount": 3,
"siteHttps": false,
"siteMobileFriendly": true,
"siteCopyrightYear": 2026,
"siteLooksOutdated": false,
"siteHasAnalytics": true,
"siteHasFacebookPixel": false,
"siteCms": null,
"extractedAt": "2026-10-05T10:06:05.938Z"
}

emailStatus is an MX check only: valid means the domain can receive mail, not that the mailbox exists. contactName / contactRole are null when no named person with a role is found on the pages.

Input

{
"websites": ["apify.com", "github.com"],
"verifyEmails": true,
"maxEmailsPerSite": 5,
"includeSocials": true
}

websites is the list of domains or URLs, one per line. verifyEmails (on by default) runs the MX check that tags each email valid / risky-role / invalid. includeSocials also pulls Facebook, Instagram, LinkedIn, Twitter/X and YouTube links found on the pages it visits.

Pricing

$5 per 1,000 websites processed ($0.005 each), plus $2.50 per 1,000 MX-checked emails ($0.0025 each) found along the way. A run that processes 1,000 sites and finds 600 verifiable emails costs $2.60.

How it compares

No browser — the actor fetches each site's home, contact, about pages as plain HTTP requests and pattern-matches the HTML, so it's fast and cheap compared to a browser-driven scraper doing the same job. It won't pick up contact info that's only rendered client-side by JavaScript, since there's no browser to run that JavaScript.

Use with n8n / Make / Zapier

Add an Apify integration node, run this actor with your domain list as input, then read the finished dataset back into your workflow to push enriched contacts into your CRM or outreach tool.

Errors and limits

How the actor behaves when things go wrong (read from its code):

  • No input. An empty or missing websites list logs a warning and the run finishes with an empty dataset. Nothing is charged. Duplicate entries are removed (case-insensitive).
  • Pages it visits. Per site: the homepage, /contact, /contact-us and /about, one after another, each with a 12-second timeout. It reads static HTML only: no browser, no JavaScript rendering, no proxies, no retries.
  • Blocked, slow or broken sites. A 403, 404 or 5xx, a timeout or a connection error on a page is treated as "no content" for that page, silently. A site that blocks the actor on every page still produces a row with empty fields, and that row is still counted as a processed website and charged. Contacts that only appear after JavaScript runs, or that sit on other pages, are not found.
  • Bad URLs. An unparseable entry fetches no pages and returns a row with empty contact fields.
  • Email status. verifyEmails is a DNS MX lookup: invalid = the domain has no mail server, risky-role = generic inbox such as info@ or support@, valid = the domain accepts mail and the address is not a generic role. It does not confirm that the mailbox exists. With verifyEmails off, statuses are unverified.
  • Phone numbers are loose. Phones are any 7 to 15 digit pattern found in the page text (up to 5 per site), so decimals, IDs and other numbers can be returned as phones (the example row above shows this). Check them before dialling.
  • Partial results. maxEmailsPerSite (default 5) caps how many emails are kept per site, and only one is chosen as email (an AI pick when several are found and its confidence is high enough, otherwise the first valid one).
  • Charging. One website-processed event per site as its row is written, plus one email-verified event per valid email. If your max-charge limit is reached, the run stops early with the sites done so far. An aborted or timed-out run has already charged for the sites it delivered.

FAQ

Why is email sometimes null? Not every site publishes a discoverable email on its home/contact/about pages, or none of the emails found pass the MX check. The row still comes through with whatever phone and social links were found.

Does it need JavaScript to render the page? No — it's a plain HTTP fetch of a handful of likely pages per site. A site that only puts its contact info behind client-side JavaScript won't be picked up.

What counts as "risky-role"? An MX-checked email that's a generic inbox like info@ or sales@ rather than a named person — still worth having, lower reply rate.

Can I chain this after another scraper? Yes — feed it the domain column from any dataset that has one, including this account's own actors.

Does it respect site terms? It only visits each site's own public pages. You are responsible for lawful use of the contact data you collect.

Send results to Notion (new, Sep 2026)

Authorize Notion once in Apify Console → Settings → API & Integrations → MCP connectors (choose Notion, sign in). Then pick that connector in Notion connector and paste the link of any Notion page in Notion page to create the table in. The first run creates a table inside that page and fills it with the contact details (up to 500 rows per run; the full set is always in the dataset). To keep adding to the same table on later runs, paste the table ID from the log into Existing Notion table ID. This Actor never sees your Notion login: Apify's connector proxy holds it. If the Notion step fails, your dataset results are still delivered and the reason is logged.

Use it from an AI agent (MCP)

Add this Actor to any MCP client (Claude, Cursor, VS Code) with one URL:

https://mcp.apify.com?tools=leadharbor/website-contact-extractor

Or call it through the Apify API with an input like this:

{
"websites": [
"notion.so",
"linear.app"
],
"verifyEmails": true,
"includeSocials": true,
"maxEmailsPerSite": 5
}

Returns one row per website: MX-checked email, phone, contact name and social links. Results land in the run's default dataset (JSON, CSV or Excel). No login or API key is needed for the sites it reads, and pay-per-event pricing works with Apify's x402 agent payments.

API usage

Run it from your own code with an Apify API token. The input below is this actor's prefilled example.

curl (runs the actor and returns the dataset items):

curl -X POST "https://api.apify.com/v2/acts/leadharbor~website-contact-extractor/run-sync-get-dataset-items" \
-H "Authorization: Bearer $APIFY_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"websites": [
"apify.com",
"github.com"
]
}'

Python (pip install apify-client):

from apify_client import ApifyClient
client = ApifyClient("<APIFY_TOKEN>")
run = client.actor("leadharbor/website-contact-extractor").call(run_input={
"websites": [
"apify.com",
"github.com"
]
})
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
print(item)

Changelog

28 Sep 2026 — Optional Notion output; MCP agent section; wording fix (MX-checked, not "deliverable"). Plus 5 public example tasks with their own pages.

More from leadharbor


Using this actor? A quick review helps other buyers find it: website-contact-extractor

New output fields (Sep 2026)

FieldWhat it is
contactName, contactRoleThe owner / founder / principal when the website clearly names one (e.g. "Dr Adil Sarwar, Founder"). An AI model only selects among names that appear on the site — it never invents one. Empty when the site doesn't name anyone.
siteLooksOutdated, siteCopyrightYearCopyright year in the footer; true when it is 3+ years old — a common sign of a neglected site.
siteMobileFriendlyWhether the homepage declares a mobile viewport.
siteHasAnalytics, siteHasFacebookPixel, siteCmsGoogle Analytics / Tag Manager present, Meta pixel present, and the site builder (WordPress, Wix, Squarespace, Shopify, Webflow).

When a site lists several emails, the returned email is the business's own main inbox — form placeholders (example@mysite.com, you@company.com), platform addresses and jobs inboxes are no longer picked.

Find us on RapidAPI