Website Email & Contact Scraper - Scored Leads avatar

Website Email & Contact Scraper - Scored Leads

Pricing

from $6.00 / 1,000 contact founds

Go to Apify Store
Website Email & Contact Scraper - Scored Leads

Website Email & Contact Scraper - Scored Leads

Find the e-mail, phone and socials behind any list of websites - plus a technical profile (CMS, SSL, mobile, analytics, site age) and a lead score telling you who is worth contacting first. Pay only for contacts found.

Pricing

from $6.00 / 1,000 contact founds

Rating

0.0

(0)

Developer

Gezgin Data

Gezgin Data

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

6 days ago

Last modified

Share

Find the e-mail address, phone number and social profiles behind any list of websites — and, in the same run, learn which of those businesses are actually worth contacting. Paste in domains, get back contactable, scored leads. No API key, no browser, no LLM.

Most contact scrapers stop at the address. This one also reads what the website says about the business running it — which CMS it uses, whether it has SSL, whether it works on a phone, when it was last touched, whether anyone is measuring anything — and turns that into two auditable scores. Those few fields are the difference between an address list and a work list.

On fresh test batches it had never seen — roofing contractors in Essen, Germany and Austin, Texas — it found an e-mail address for 78% and 80% of them respectively. The measurement, and an honest list of what it gets wrong, are further down.

What it does

Give it example.com (or a full URL — both work) and for every site it will:

  1. Fetch the homepage and look for contact details in descending order of confidence: mailto: links, Cloudflare-obfuscated addresses, schema.org structured data, the raw source, then the visible text. Addresses written as name [at] example [dot] com are decoded.
  2. Follow the contact page when the homepage came up short — the discovered link plus the paths most business sites have anyway (/kontakt, /impressum, /contact, /contacto, …).
  3. Profile the site from HTML it already downloaded — no extra requests, no extra time.
  4. Score the lead on two separate questions, and show its work.

Give it a link-in-bio hub instead — linktr.ee/name, Beacons, Stan, Taplink and a couple of dozen others — and it opens the hub, finds the real website behind it and audits that. This matters more than it sounds: pointed at a Linktree, a scraper that does not resolve reads the hub's own page and returns whatever it finds there. On a live test that produced a Linktree advertiser's address as the contact for a Berlin tattoo studio. Resolved, the same input returns the studio's own address on its own domain. Businesses whose entire web presence turns out to be a hub come back tagged linktree_only — for anyone selling web work, those are the best rows in the file.

How the scoring works

Two scores, deliberately not merged. A flawless website that answers every channel is a poor lead for a web agency; a neglected one you can barely reach is a good one. One number would hide exactly that.

contactabilityScore — can you reach them?

SignalPoints
E-mail, personal (jan.meier@…)50
E-mail, role (info@, kontakt@, office@, hello@)40
E-mail, department (press@, jobs@, support@, datenschutz@)15
E-mail, noreply@0
Phone from a tel: link25
Phone from labelled text ("Tel: …")20
Contact form15
Any social profile10

E-mail points are multiplied by how much the source can be trusted: 1.0 for a mailto: link, structured data, a Cloudflare-obfuscated address or a contact page — these were published as contact points on purpose. 0.75 for a regex hit in the raw source or page text, which could be anything. The result is reported as emailConfidence: high | medium.

Capped at 100.

opportunityScore — do they visibly need help?

FindingPoints
site_unreachable — the website did not respond40
stale_site_severe — copyright 6+ years old35
no_ssl — still on http28
not_mobile_friendly — no viewport meta tag25
stale_site — copyright 3–5 years old20
outdated_cms_hint — Wix or Squarespace12
no_analytics — no GA, Meta Pixel, Hotjar or LinkedIn Insight10
no_social_presence — no social links found8
no_contact_form — only ever reported if a contact page was actually opened7

Capped at 100. Every finding that fired is listed in opportunityTags.

leadPriority

contactabilityScore == 0cold (no way to act on it)
contactability ≥ 50 and opportunity ≥ 25 → hot
contactability ≥ 50 and opportunity ≥ 10 → warm
contactability ≥ 50 or opportunity ≥ 25 → warm
otherwise → cold

It shows its work

Every row carries a scoreBreakdown naming each contribution, so the ranking can be audited rather than believed:

{
"website": "https://www.maler-stefanbeckmann.de/",
"email": "hallo@malermeister-stefanbeckmann.de",
"emailType": "role",
"emailConfidence": "high",
"contactabilityScore": 85,
"opportunityScore": 57,
"leadPriority": "hot",
"opportunityTags": ["stale_site_severe", "outdated_cms_hint", "no_analytics"],
"scoreBreakdown": {
"email:role": 40, "phone": 25, "social_profiles": 10,
"opportunity:stale_site_severe": 35,
"opportunity:outdated_cms_hint": 12,
"opportunity:no_analytics": 10
}
}

Read plainly: reachable by e-mail, phone and social, on a Wix site last touched six years ago with no analytics installed. That is a conversation waiting to happen.

These weights are reasoned judgements, not learned values, and they assume you sell websites, hosting or marketing. If you sell something else, ignore opportunityScore and sort by contactabilityScore and emailType instead — the raw fields are all there.

Who it is for

Agencies and freelancers building a prospect list: the tags say who needs a new website, who runs no tracking, and who is invisible on a phone.

Sales teams turning a list of company domains into something they can mail or call.

Anyone holding the output of another scraper. Google Maps, directories, marketplaces — nearly every scraper returns websites but no e-mail addresses. This is the step that comes after, and it takes that output directly.

AI agents and automations. One required field, everything else defaulted, a flat JSON row per website and a machine-readable RUN_STATUS record. An empty result always states its reason, so a failed run can never be mistaken for "this business has no contact details".

How to use it

  1. Paste your websites into Websites, one per line. Plain domains are fine.
  2. Leave Also profile the website on unless you only want raw contacts.
  3. Run it, then sort the output by leadPriority and start at the top.

Duplicates pointing at the same host are removed, so you are never billed twice for one business.

Input

FieldDefaultWhat it does
startUrlsWebsites to process. Domains, full URLs, or link-in-bio hubs. Required.
resolveLinkHubstrueOpen a Linktree, Beacons, Stan or Taplink URL and audit the real website behind it instead of the hub itself
enrichSitetrueProfile the site (CMS, SSL, mobile, age, analytics, socials)
maxContactPages5How hard to look when the homepage yields nothing. 0 = homepage only
onlyWithContactfalseDrop rows where nothing was found
maxConcurrency10Sites fetched in parallel
maxRunTimeSecs3000Stops cleanly before this and keeps everything found

Output

One row per website, whether or not something was found. Download as JSON, CSV, Excel or HTML, or pull it through the API.

FieldMeaning
inputUrl, websiteWhat you supplied, and what was actually audited. They differ only when the input was a link hub and the real site behind it was found
websiteSourceinput or link_hub — how the audited site was arrived at
statusNoteOne plain sentence explaining a row that looks empty: a hub with no site behind it, a hub that rate-limited us, a dead domain, or a host that refused us
hub, hubUrl, hubStatus, hubFetchStatus, hubLinksWhich hub was opened, what came of it, and every link it carried
finalUrlWhere the audited site ended up after redirects
siteReachable, fetchStatusok, http_403, timeout, dns_error, connect_error. Only a genuine non-answer counts as a sales signal — a 403 means the host refused us, which says nothing about the business
email, emailSource, emailType, emailConfidenceAddress, where it was found, who is behind it, how much to trust it
phone, phoneSourceNormalised number, from a tel: link or a labelled line
contactPageUrl, contactPageCheckedWhich contact page was opened, if any
socialLinksFacebook, Instagram, LinkedIn, X, TikTok, YouTube
cmsDetected from structural evidence only, never a brand name mentioned in text
copyrightYearLatest year in the footer; ranges like "© 2004–2026" handled correctly
hasSsl, mobileFriendlyFrom the final URL after redirects, and the viewport meta tag
hasTracking, trackingToolsGoogle Analytics, Meta Pixel, Hotjar, LinkedIn Insight
hasContactFormA form carrying an e-mail field or a textarea
contactabilityScore, opportunityScore, opportunityTags, leadPriority, scoreBreakdownThe scoring above

The key-value store also holds RUN_STATUS with the outcome, how many websites were processed and the e-mail hit rate for the run.

Pricing

You pay per contact found and per site profiled. A website that yields nothing costs nothing — charging for a miss would be charging for our own failure. Any single run can be capped from the Apify console.

What it does well, and where it falls short

Every scraper listing claims to be accurate. Here is what was actually measured, and what is genuinely wrong with this one — you will find out either way, and it is cheaper for both of us if you find out before you pay.

Measured on samples it had never seen

Both test batches were pulled fresh from Google Maps after development finished, so none of them influenced the code. Nine roofing companies in Essen, Germany, and ten in Austin, Texas:

GermanyUSA
E-mail found78%80%
Phone found78%90%
Refused entry (403)01

A sample of records was then checked by hand against the live sites. That check found one real defect — a phone number mangled by a URL-encoded space in a tel: link — which has been fixed and re-verified. Everything else held, including the cases where "nothing found" turned out to be the correct answer rather than a miss.

What it does better than the alternatives

It ranks leads, and shows why. Every other contact scraper hands you addresses. This one tells you which businesses are worth the call and prints its arithmetic in scoreBreakdown, so you can disagree with it on the evidence rather than on faith.

It declares what it does not know. emailConfidence separates an address published in a mailto: link from a regex hit in body text. fetchStatus distinguishes "their site is down" from "their host refused us". likelyJsRendered marks pages we could not really read. An empty result always carries a reason in RUN_STATUS.

It costs almost nothing to run — around two seconds per website, no browser, no proxy required, comfortably inside the free tier.

Where it falls short

About 5% of hosts refuse it outright. The Actor already retries with several browser fingerprints, which cleared two thirds of the refusals seen in testing, but some WAFs check for JavaScript execution and cannot be talked around. Those rows say fetchStatus: http_403 and deliberately carry no opportunity signal — the Actor will not tell you a business has a broken website when the truth is it would not let us in. A residential proxy usually gets through them.

Sites that build themselves in the browser come back empty. Being browser-free is what makes this fast and cheap; the cost is that a single-page app hands us a shell. Those rows are flagged likelyJsRendered, and the "no social presence" and "no contact form" findings are suppressed for them, because we never actually saw the page.

Link hubs throttle, and there is no way around it. Linktree serves roughly ten to eleven requests per run before answering HTTP 429. Measured: fifteen hub URLs in one run left four unresolved; a longer backoff changed nothing except the runtime, and routing through Apify's shared datacenter proxy made it worse, not better. Those rows come back hubStatus: fetch_failed with hubFetchStatus: http_429, carry no opportunity signal, and cost you nothing — you are billed for contacts found and sites profiled, never for a hub we could not open. If your list is unusually hub-heavy, split it across runs. On ordinary lead lists, where hubs are a small minority of rows, you will not meet this limit.

no_analytics can still misfire. Twelve analytics products are detected, including Matomo, Plausible and Cloudflare Insights. Server-side tracking leaves no trace in the HTML and is undetectable by anyone, including this Actor.

The scoring weights are reasoned judgements, not learned values. They were set by argument, not by measuring which leads actually converted — nobody has that data yet. They also assume you sell websites, hosting or marketing. If you sell something else, the opportunity signals mean little to you; sort by contactabilityScore and emailType instead.

Phone extraction is deliberately conservative. It reads tel: links and numbers sitting behind a "Tel:"-style label, and ignores unlabelled digits on a page. That loses a few real numbers rather than inventing wrong ones, because you are billed per contact found.

Results are a snapshot. A host that times out today may answer tomorrow. And the verification above rests on two batches of around ten sites, with a handful checked by hand — enough to find the error classes, not enough to put a confidence interval on the hit rate.

It is new. No usage history, no ratings, no track record. Judge it on the run, not on the listing.

The Actor reads publicly available pages, the way a browser does. Business contact details published in an imprint or on a contact page are public information, but what you may do with them afterwards is regulated — under GDPR in the EU, and in Germany unsolicited B2B e-mail advertising generally requires prior consent under the UWG. Please make sure your intended use is lawful where you operate.

Found a bug, or need another signal in the output? Open an issue on the Issues tab.