Website Contact Extractor - Email, Phone & Social Scraper
Pricing
from $0.65 / 1,000 website scanneds
Website Contact Extractor - Email, Phone & Social Scraper
[💵 $1.00 / 1K websites, no start fee] Bulk-extract emails, phones and social profiles from company websites. Ranks contact/impressum/kontakt pages in 12+ languages, decodes Cloudflare-protected and (at)-obfuscated addresses, MX-verifies for free, and scores every address 0-100. CSV/JSON.
Pricing
from $0.65 / 1,000 website scanneds
Rating
0.0
(0)
Developer
WebData Labs
Maintained by CommunityActor stats
1
Bookmarked
2
Total users
2
Monthly active users
7 days ago
Last modified
Categories
Share
Turn a list of company websites into verified emails, dialable phone numbers and social profiles - one row per website, $1.00 per 1,000 websites, no start fee.
New Apify accounts can scan about 5,000 websites with the included $5 platform credit.
Most website email scrapers hand you a text dump and call it a lead list. You get noreply@, logo@2x.png, someone else's Facebook share button, and a "phone number" that is actually a date on a blog post. Then you spend an afternoon cleaning it before a single email goes out. This Actor does the cleaning as part of the extraction: every address is classified and deliverability-checked, every phone is validated against its country's real numbering plan, and every social link is resolved to the company's actual profile. What lands in your spreadsheet is what you can use.
✅ What you get / ❌ what this isn't
| ✅ What you get | ❌ What this isn't |
|---|---|
| Emails scored 0-100 from independent signals (mailto link, schema.org, page type, MX) | Not a flat list where a footer noreply@ looks as good as the founder's address |
| Cloudflare-protected and (at)-obfuscated addresses decoded | Not a raw-body regex that reports "no email found" on every Cloudflare site |
Contact pages found in 12+ languages - kontakt, impressum, contacto, contatti, contato, nous-contacter | Not an English-only /contact guess that misses most of Europe |
| Phones returned in E.164, validated against the real numbering plan | Not every 10-digit string on the page, dates and VAT numbers included |
| Social links resolved to the company profile | Not facebook.com/sharer.php and twitter.com/intent/tweet from the share widget |
| Free MX verification on every address, in the base price | Not a per-email verification surcharge for a DNS lookup |
| No start fee - one website costs $0.001 | Not a run fee that makes a single lookup cost 30x the data |
| Unreachable websites are not charged | Not billed regardless of whether anything was reachable |
🔎 Why use this Actor
- Confidence score, not a guess. Each address gets 0-100 from signals that have to agree: was it in a
mailto:link, was it in the site's schema.org markup, was it found on a contact page, is it on the company's own domain, does that domain publish mail servers. One boolean,outreachReady, collapses it for filtering. - Cloudflare de-obfuscation. A large share of small-business sites hide addresses behind Cloudflare Email Protection or write them as
jane (at) acme (dot) com. Both are decoded. Sites that other scrapers report as empty come back with a working address. - Multilingual page ranking. The crawl budget goes to the pages that actually hold contacts.
impressum,kontakt,contacto,contatti,contato,iletisimandyhteystiedotrank as high ascontact, so a German or Italian list yields like an English one. - Real phone validation. Numbers are parsed with the country inferred from the ccTLD, or from any international-format number on the page, and dropped unless they are valid for that numbering plan. Output is E.164, ready for a dialer.
- Junk filtering at the source.
noreply@,postmaster@,youremail@,info@example.com, image filenames, npm scopes and Sentry keys never reach your dataset. - Catch-all aware SMTP. If you enable the mailbox probe, a domain that accepts every address is flagged as catch-all instead of being sold to you as "verified".
- Priced per website, not per page. Crawling 50 pages of a site costs the same as crawling 3. Depth is a quality dial, not a cost dial.
👥 Who it's for
Sales, growth and agency teams who already have a list of company websites and need the contacts behind them.
- Enrich a Google Maps, directory or trade-association export with the email that is actually on the site.
- Clean an inherited list before a cold campaign, so bounces do not burn your sending domain.
- Build a call list from validated E.164 numbers instead of a scrape of every digit string.
- Find the LinkedIn company page for a few thousand domains in one run.
- Feed one row per contact straight into a CRM import or a mail-merge tool.
Example tasks
- Find emails from company websites
- Enrich Google Maps leads with emails
- Extract social profiles from websites
- Bulk Email Finder for a List of Company Websites
- Extract Emails from German Websites (Impressum & Kontakt)
- Export Website Contacts to CRM (One Row per Email)
- Verified Email Finder with SMTP Mailbox Check
- Agency Prospecting: Contact Emails for a Prospect List
- Fast Bulk Scan for Large Website Lists
⚙️ How to extract contacts from a list of websites
- Open the Actor and paste your websites into Websites. Bare domains (
acme.com) and full URLs both work, and duplicates are removed for you. - Leave Max pages per website at 12. It costs the same at 1 or at 100, so only lower it if you want faster runs.
- Leave Email verification on
MX check. It is free and it is what flags dead domains. Switch toMX + SMTP mailbox probeonly when you need mailbox-level proof and accept the extra charge. - Pick your Output shape: one row per website for enrichment and spreadsheets, or one row per contact email for a CRM import.
- Click Start. Results appear on the Output tab, exportable as CSV, JSON or Excel.
Getting more out of a stubborn list
If a batch comes back with many unreachable rows on sites that clearly load in your browser, turn on Use a proxy and re-run just those domains. If you need every address on a site rather than the best one, leave Stop early off (the default) and raise Max pages per website.
📥 Input
{"websites": ["basecamp.com", "sipgate.de", "https://www.cluster.gr"],"maxPagesPerSite": 12,"verificationLevel": "mx","outputMode": "website","respectRobotsTxt": true}
websites- the canonical list of company websites. Domains or URLs are deduplicated automatically.urls,domains,startUrls- compatibility aliases forwebsites. Lists are merged and deduplicated, so inputs copied from other contact Actors and agent tools work without remapping.maxPagesPerSite- crawl budget per site, 1-100, default12. Does not affect price.stopWhenEmailFound- speed switch for very large lists, defaultfalse. Stops a site once an on-domain email turns up, at the cost of its phones and socials.respectRobotsTxt- defaulttrue. Skips paths the site disallows for generic crawlers.verificationLevel-none,mx(default, free) orsmtp(billed per probe).outputMode-website(default, one row per site) orcontact(one row per email).maxWebsites- safety cap per run, default1000.websiteConcurrency/pageConcurrency/requestTimeoutSecs- advanced tuning. Defaults are fine unless a target rate-limits you.useProxy/proxyConfiguration- advanced. Off by default; most company sites do not need a proxy.
📤 Output
| domain | status | bestEmail | bestEmailConfidence | phones | contactPageUrl | |
|---|---|---|---|---|---|---|
| wpbeginner.com | ok | support@wpbeginner.com | 100 | https://www.linkedin.com/company/wpbeginner | https://www.wpbeginner.com/contact/ | |
| sipgate.de | ok | info@sipgate.de | 69 | +492116355550 | https://www.linkedin.com/company/sipgate | https://www.sipgate.de/kontakt |
| monzo.com | ok | help@monzo.com | 92 | +442038720620, +448000884040 | https://www.linkedin.com/company/monzo-bank |
Each website row also carries emails (every address found), emailDetails (per address: type personal/role/junk, confidence, mxValid, smtpAccepted, provider, isFreeProvider, isDisposable, onSiteDomain, source showing how it was found, and foundOn linking the exact page), socialLinks for LinkedIn, X, Facebook, Instagram, YouTube, TikTok, GitHub, Telegram, Pinterest and WhatsApp, plus outreachReadyEmails, pagesCrawled, finalUrl, crawledAt and error. In contact output mode the same fields arrive flattened, one row per email address, ready for a CRM import.
💵 How much does it cost?
$1.00 per 1,000 websites scanned, and no start fee. One website costs $0.001, a hundred cost $0.10, ten thousand cost $10.00 - the price scales linearly from the very first lookup, which matters if you call this from an agent or a workflow one domain at a time. Crawl depth does not change the price: a 50-page crawl of one site costs the same $0.001 as a 3-page crawl. MX verification is included. Only the optional SMTP mailbox probe is billed on top, at $0.002 per probe, and it is off by default. Websites that cannot be reached at all are not charged. Expect a company email on roughly 65-75% of ordinary business websites; the rest are contact-form-only, JavaScript-rendered, or genuinely publish no address.
| Run size | This Actor - no start fee | A tool with a $0.035 start fee plus $0.001/site |
|---|---|---|
| 1 website | $0.001 | $0.036 |
| 10 websites | $0.010 | $0.045 |
Pricing tiers
| Apify plan | Price per 1,000 websites |
|---|---|
| Free | $1.00 |
| Starter | $0.90 |
| Scale | $0.80 |
| Business | $0.65 |
| Platinum | $0.65 |
| Diamond | $0.65 |
Use with AI agents via MCP
Apify's MCP server lets an AI agent discover this Actor, run it, and read the resulting dataset without custom glue code. The Actor accepts the canonical websites field plus urls, domains, and startUrls, so agents can reuse common email-finder payloads.
Setup for Claude Code
Add the Apify MCP server to Claude Code, authenticate it with your Apify account, then ask:
Run
webdata_labs/website-contact-extractorfor these domains, return only outreach-ready emails with confidence at least 70, and include the source page.
Claude Desktop, Cursor and VS Code
Add https://mcp.apify.com as an MCP server in your client, complete Apify authentication, and select this Actor by its full ID: webdata_labs/website-contact-extractor.
Example prompts:
- "Find verified contact emails for these 20 company domains and return a CSV."
- "Enrich this Google Maps export, keep only on-domain emails, and explain every low-confidence result."
- "Scan this one website and return the best email, phone and LinkedIn page."
Use this Actor in n8n
Create an Apify credential in n8n, add the Apify node, choose Run an Actor, and enter webdata_labs/website-contact-extractor. Map your incoming domain column to websites or domains, wait for the run to finish, then read the default dataset. A common workflow is:
Google Maps or CRM -> Website Contact Extractor -> filter outreachReady -> Lead List Deduplicator -> CRM
The same input/output pattern works in Make and Zapier. For one-domain automations, the absence of a start fee keeps each event at $0.001 instead of turning a tiny lookup into a run-fee purchase.
API usage - Using the Apify API
Start a run and return its dataset items in one request:
curl "https://api.apify.com/v2/acts/webdata_labs~website-contact-extractor/run-sync-get-dataset-items?token=$APIFY_TOKEN" \-H "Content-Type: application/json" \-d '{"domains":["basecamp.com","sipgate.de"],"verificationLevel":"mx","outputMode":"website"}'
Keep APIFY_TOKEN in an environment variable or secret manager. Do not place it in source code, public tasks, screenshots, or shared workflow exports.
Is it legal to scrape website contact information?
This Actor reads contact details that organizations publish on public web pages. Whether you may collect, retain, or use a particular address depends on your jurisdiction, purpose, lawful basis, and outreach method. GDPR, UK GDPR/PECR, CAN-SPAM and local privacy or marketing rules may apply. Respect robots.txt, site terms, opt-outs, suppression lists, purpose limitation and retention requirements. This is product information, not legal advice.
Benchmark - same domains, same job
Release validation uses a fixed 50-domain list with English, German, Italian, Spanish, Portuguese and Cloudflare-fronted sites. The current cloud build produced:
| Build | Domains requested | Reachable / charged | Domains with email | Domains with outreach-ready email | Obvious false positives | Listed data charge |
|---|---|---|---|---|---|---|
0.2.6 | 50 | 41 | 23 | 20 | 0 | $0.041 |
The automated false-positive audit checks malformed addresses, asset filenames, junk mailboxes and localized placeholder domains, followed by manual inspection of every low-confidence result. The run completed in 56 seconds. Run ID: Rhq4aTR6FrQDLVbLV; dataset ID: ddkIfBZGLjkYLDLJD.
We do not publish a competitor comparison until both Actors have completed the same list under the same settings. This prevents a failed or blocked comparison run from being presented as a product result.
🔁 Run it on the Apify platform
Schedule a run to re-check a domain list weekly and catch contacts that appeared since last time, or call the Actor from the API and get results back as JSON. Every run's dataset exports to CSV, JSON, XML or Excel, and integrates with Make, Zapier, n8n, Google Sheets and webhooks, so enriched rows can land directly in your CRM without a manual download step.
⚠️ Limits and caveats
- JavaScript-rendered contacts are not visible. This Actor fetches HTML, which is what makes it fast and cheap. An address injected by a script after page load will not be found.
- Contact forms return no email. A site whose only contact route is a form has nothing to extract; you get
status: okwith zero emails and thecontactPageUrlso a human can follow up. - Addresses rendered as images are unreadable. Some sites publish contact details as a PNG specifically to defeat scrapers. That works on this one too.
- SMTP probes are frequently inconclusive. Google Workspace, Microsoft 365, Proton and Yandex accept every recipient at SMTP time, so mailbox existence cannot be proven; those come back with an explanatory
noteand the MX result rather than a fabricated verdict. Some hosts also block outbound port 25 entirely. respectRobotsTxtcosts yield. It is on by default. Sites with a blanketDisallow: /will return fewer pages until you turn it off, which is your call to make.- Phone validation is strict by design. A national-format number on a
.comsite with no other international number anywhere on the page is dropped rather than guessed at. Some German and Austrian registry numbers still pass validation because those numbering plans genuinely allow such shapes. - Roughly a quarter to a third of business websites publish no email at all. No extractor changes that. You are charged for the scan, so use
maxWebsiteson a first run to sanity-check yield on your specific list before committing a large batch.
🧩 Related Actors
Build a lead-generation pipeline: find businesses -> extract contacts -> dedupe -> enrich and prioritize.
- Google Maps Email Leads Scraper - find local businesses and extract their published emails in one run.
- Google Maps No-Website Leads Scraper - find businesses that need a website before contact enrichment.
- Google Maps No Social Media Leads - find businesses missing social profiles.
- Google Maps Reputation Leads Scraper - prioritize businesses with reputation gaps.
- Lead List Deduplicator - merge and deduplicate enriched exports before CRM import.
- Website Tech Stack Detector - enrich the same domains with technology signals for relevant outreach.
- Company Career Page Jobs API - add hiring signals to prioritize companies with active demand.
❓ FAQ
Am I charged for websites where nothing is found? Yes, if the site was reachable and scanned - the work was done. Websites that could not be reached at all are not charged.
Does the price go up if I crawl more pages?
No. Billing is per website. maxPagesPerSite changes run time and yield, never cost.
Is email verification extra? MX verification is included in the per-website price. Only the optional SMTP mailbox probe is billed separately, at $0.002 per probe, and it is off unless you turn it on.
What does confidence actually mean?
It combines how the address was found (a mailto: link and schema.org markup count for much more than loose text), whether it sits on the company's own domain, whether it came from a contact page, and what verification returned. A junk mailbox is always 0. A dead MX record caps the score at 10. Filtering on outreachReady or confidence >= 70 is the intended use.
Which languages does the contact-page detection cover? English, German, Spanish, Portuguese, Italian, French, Dutch, Polish, Czech, Swedish, Finnish, Hungarian, Turkish, Lithuanian and Catalan keywords are ranked, plus the well-known unlinked paths every CMS creates.
Can I get one row per email instead of one per website?
Yes. Set outputMode to contact.
Is this legal? It reads publicly published contact details from public web pages, which is what a person visiting the site would see. How you use those details is governed by GDPR, CAN-SPAM, PECR and their equivalents in your market. Have a lawful basis before you send.
Changelog
2026-07-27
- Added
urls,domains, andstartUrlsinput aliases for agent and workflow compatibility. - Added MCP, n8n/Make/Zapier, API, pricing comparison, legal, benchmark-method and lead-pipeline documentation.
- Published the free-credit comparison and exact six-tier pricing table.
- Added regression filters for retina asset names such as
search-icon@2x.aspxand localized placeholder domains such asejemplo.com.
2026-07-25
- Added multilingual page ranking, Cloudflare and written-address de-obfuscation, E.164 phone validation, confidence scoring, catch-all detection, and website/contact output modes.
🛠️ Support
Something wrong or missing? Open an issue on the Actor's Issues tab with the run URL, the input you used, and what you expected. That is the fastest path to a fix.
⭐ Rate this Actor
If this saved you an afternoon of list cleaning, please leave a rating on the Reviews tab. Reviews are the main trust signal other buyers have, and they decide what gets built next - requests that arrive alongside a review are the ones that get prioritised. If something is broken, please open an issue first so it can be fixed; a low rating on a bug that could have been resolved in a day helps nobody.