Website Email & Phone Contact Extractor
Pricing
from $0.59 / 1,000 website scanneds
Website Email & Phone Contact Extractor
Extract public emails, valid phone numbers, social profiles, contact pages, forms, addresses, and VAT IDs from company websites. Get one CRM-ready row per domain with transparent scoring and source URLs. Use fast HTTP crawling by default, with optional JavaScript fallback and email verification.
Pricing
from $0.59 / 1,000 website scanneds
Rating
0.0
(0)
Developer
Daniel Valev
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
10 days ago
Last modified
Categories
Share
Website Email & Phone Contact Extractor is a bulk website contact scraper for lead enrichment. Paste company domains to extract public emails, valid phone numbers, social profiles, contact and Impressum pages, forms, addresses, VAT IDs, and scored source records. Every deduplicated domain returns one CRM-ready row, including explicit failure, timeout, and budget statuses.
The default HTTP scan costs $0.005 + $0.0008 per successfully scanned website, so one run can process up to 6,243 HTTP-only websites with the free $5 Apify credit. JavaScript fallback and email verification are optional paid events.
How to find emails and phone numbers from websites
- Open the Actor, click Try for free, and paste one website per line.
- Keep the default HTTP-only scan, or enable paid email verification and JavaScript fallback when needed.
- Click Start and export the resulting Dataset to JSON, CSV, Excel, XML, or your integration.
{"urls": ["konditorei-buchwald.de"],"maxPagesPerSite": 10,"verifyEmails": false,"jsFallback": false,"includePersonalNames": false}
Inputs are case-insensitively deduplicated by registrable domain. www.example.com and shop.example.com therefore share one output row for example.com.
What data can this website contact scraper extract?
| Data | What you receive |
|---|---|
| Emails | Primary and deduplicated public emails, 0–100 quality score, source URL, domain-match, role-account, free-provider, and disposable-domain flags |
| Phone numbers | Valid international numbers normalized to E.164, with original text and source page |
| Social profiles | LinkedIn company and people profiles, X, Facebook, Instagram, YouTube, GitHub, TikTok, and Pinterest |
| Contact routes | Contact, legal, support, team, and Impressum pages plus detected contact forms and form fields |
| Company data | Organization names, structured postal addresses, and explicitly published VAT or tax IDs |
| Run metadata | Status, pages crawled, duration, JavaScript fallback usage, timestamp, and actionable failure reason |
Website contact scraper use cases
- Enrich company domains exported from Google Maps, LinkedIn, directories, or a CRM.
- Build a bulk business email and phone list while preserving one result row per input domain.
- Find German and multilingual Impressum or legal-page contacts.
- Detect contact-form-only companies instead of treating them as failed leads.
- Refresh contact data on a schedule and export it to JSON, CSV, Excel, Google Sheets, Make, Zapier, or n8n.
- Provide structured website contact data to AI agents through the Apify API or MCP server.
Website contact scraper output example
The default Dataset contains exactly one record per deduplicated input domain. The overview view shows the six fields an SDR usually needs first: websiteUrl, primaryEmail, allEmails, primaryPhone, linkedin, and status.
{"websiteUrl": "https://www.konditorei-buchwald.de/","primaryEmail": "info@konditorei-buchwald.de","allEmails": ["info@konditorei-buchwald.de"],"primaryPhone": "+49303915931","linkedin": null,"status": "success"}
Email source precision is ordered as JSON-LD, mailto:, Cloudflare protection, plain text, and obfuscation. Scores are deterministic: source confidence, domain match, contact-page placement, repetition across pages, role-account status, free-provider status, and disposable-domain status all affect the 0–100 score.
Website contact scraper input
| Parameter | Type | Default | What it controls |
|---|---|---|---|
urls | string array | required | 1–10,000 bare domains or full URLs. Tracking parameters are removed and inputs are deduplicated by registrable domain. |
maxPagesPerSite | integer | 20 | Hard cap of 1–200 attempted pages per website. It does not affect the event price. |
verifyEmails | boolean | false | Verifies each extracted email. Charged per email that completes verification. |
maxConcurrency | integer | 5 | Parallel page requests within one website; requests to the same host stay sequential. |
maxWebsitesConcurrency | integer | 5 | Number of separate websites processed in parallel. |
requestTimeoutSecs | integer | 15 | Per-request timeout from 5 to 60 seconds. |
maxSiteDurationSecs | integer | 90 | Hard per-site wall-clock limit from 20 to 600 seconds. |
respectRobotsTxt | boolean | true | Honors robots.txt. Disable only when you have a lawful reason and permission. |
jsFallback | boolean | false | If HTTP finds no email, renders only the best contact page and homepage. Charged only after a browser pass completes. |
useProxy | boolean | false | Uses the configured proxy. Proxy traffic can add charges from your proxy plan. |
proxyConfiguration | object | Apify Proxy | Proxy groups or custom proxy URLs, used only when useProxy is enabled. |
verificationLevel | format, mx, or smtp | mx | Format is local; MX checks mail servers; SMTP probes a mailbox and a random catch-all address. |
smtpFromAddress | string | none | Optional own-domain SMTP sender address. Used only for SMTP verification. |
includePersonalNames | boolean | true | Associates mailto addresses with nearby names and job titles where possible. |
How much does website contact scraping cost?
This Actor uses pay per event. A normal HTTP page count does not change the website price.
| Event | When it is charged | Free-tier price |
|---|---|---|
actor-start | Once when the run starts | $0.0050 |
website-scanned | After a successful success or no_contacts record is stored | $0.0008 |
email-verified | For each email that completes the selected verification level | $0.0015 |
js-fallback-used | For each website whose opt-in browser fallback completes | $0.0030 |
Without verification or JavaScript fallback, the formula is $0.005 + $0.0008 × successfully scanned websites.
| Websites in one run | Worked cost |
|---|---|
| 1 | $0.0058 |
| 10 | $0.0130 |
| 100 | $0.0850 |
| 1,000 | $0.8050 |
For 100 websites with one verified email each, the cost is $0.005 + $0.080 + $0.150 = $0.235. If all 100 also need JavaScript fallback, add $0.300, for a total of $0.535.
With the free $5 Apify credit, one HTTP-only run can scan up to 6,243 successful websites at Free-tier event prices. Actual capacity is lower when verification, JavaScript fallback, paid proxy traffic, or multiple run starts are used. Bronze, Silver, and Gold tiers discount every event by approximately 5%, 12%, and 26%; higher tiers receive further discounts.
Failed scans are stored as reconciliation rows but are not charged as website-scanned. When a maximum run cost or paid-item limit is reached, the remaining domains receive skipped_budget rows instead of disappearing.
Why this website email scraper finds more contacts
- JSON-LD and schema.org microdata for
Organization,LocalBusiness,Person, andContactPoint - Cloudflare
/cdn-cgi/l/email-protectionanddata-cfemaildecoding name [at] domain [dot] com, entity-encoded, and split inline addresses- Multilingual contact, legal, team, and impressum pages
- Valid E.164 phone numbers with country inference
- LinkedIn, X, Facebook, Instagram, YouTube, GitHub, TikTok, and Pinterest profiles
- Share-link and social-intent exclusion
- Contact-form detection when no direct email is published
- Optional JavaScript rendering and format, MX, or SMTP verification
Honest limitations
Expect roughly 20–30% of websites to publish no extractable email. Some companies intentionally offer only a contact form; those results can still return contactForm. Emails inserted only after complex interaction, login, consent, or CAPTCHA may remain unavailable even with JavaScript fallback. The Actor does not bypass access controls.
jsFallback is opt-in because a browser is slower and has its own paid event. It runs only when the HTTP pass finds zero emails, and only for the homepage and best contact-page candidate.
Google Workspace, Microsoft 365 and Yahoo reject or greylist SMTP probing from cloud IPs. For those providers cap confidence at 45 and never set isVerified: true. Many cloud hosts also block outbound port 25 entirely — detect ECONNREFUSED/ETIMEDOUT on connect and return smtpAvailable: false rather than silently reporting everything as invalid. Overstating verification accuracy is the fastest way to earn 1-star reviews.
MX verification proves that a domain accepts email, not that an individual mailbox exists. Catch-all SMTP domains accept random recipients, so their individual addresses remain unverified.
Integrations
Export directly to Google Sheets or connect the Dataset to Make, Zapier, n8n, and Apify webhooks. Scheduled Actor runs can refresh a CRM enrichment list on a daily, weekly, or monthly cadence. API and webhook consumers should use domain as the reconciliation key and inspect status before starting outreach.
API
Node.js
import { ApifyClient } from 'apify-client';const client = new ApifyClient({ token: process.env.APIFY_TOKEN });const run = await client.actor('valev-lab/website-contact-extractor').call({urls: ['apify.com', 'wordpress.org'],verifyEmails: true,verificationLevel: 'mx',});const { items } = await client.dataset(run.defaultDatasetId).listItems();console.log(items);
Python
import osfrom apify_client import ApifyClientclient = ApifyClient(os.environ["APIFY_TOKEN"])run = client.actor("valev-lab/website-contact-extractor").call(run_input={"urls": ["apify.com", "wordpress.org"],"verifyEmails": True,"verificationLevel": "mx",})items = client.dataset(run["defaultDatasetId"]).list_items().itemsprint(items)
cURL
curl --request POST \"https://api.apify.com/v2/acts/valev-lab~website-contact-extractor/runs?token=$APIFY_TOKEN&waitForFinish=120" \--header "Content-Type: application/json" \--data '{"urls": ["apify.com", "wordpress.org"],"verifyEmails": false}'
Read the Dataset with GET https://api.apify.com/v2/datasets/{defaultDatasetId}/items?clean=true.
Use from MCP and AI agents
$claude mcp add --transport http apify "https://mcp.apify.com?tools=valev-lab/website-contact-extractor"
Example prompts:
- “Enrich these 200 company domains with their best public email, phone number, and LinkedIn company page.”
- “Find the German Impressum contacts for this domain list and return only domain-matching emails with scores above 50.”
- “Check these prospect websites, verify their emails at MX level, and separate contact-form-only companies.”
Legality and compliance
This Actor extracts data that websites publish publicly and does not log in, bypass access controls, solve CAPTCHAs, or access private profiles. You are responsible for having a lawful purpose, respecting website terms and robots.txt, honoring GDPR and other privacy rights, following CAN-SPAM and similar outreach laws, maintaining suppression lists, and using the output responsibly. Public availability does not automatically grant permission for unsolicited marketing.
FAQ
How do I scrape email addresses from a list of websites?
Paste the domains into urls and run the Actor. It prioritizes structured data, mail links, Cloudflare-protected addresses, visible text, and common obfuscation, then returns one row per deduplicated domain.
How can I find business phone numbers from company websites?
The Actor checks tel: links, JSON-LD telephone fields, and visible text. It validates candidates with libphonenumber-js and returns only valid E.164 numbers plus their original text.
Can I scrape emails from German Impressum pages?
Yes. German Impressum and Kontakt paths receive the highest crawl priority, alongside multilingual legal and contact-page terms.
Does this website email scraper work on JavaScript websites?
The default path uses fast HTTP requests. Enable jsFallback to render the best contact page and homepage when HTTP found zero emails.
Can this Actor decode Cloudflare protected email addresses?
Yes. It decodes both Cloudflare email-protection links and data-cfemail attributes using Cloudflare's XOR format.
How accurate is SMTP email verification?
SMTP is a useful signal, not a guarantee. Catch-all servers, greylisting, cloud-IP blocks, and providers such as Google Workspace, Microsoft 365, and Yahoo limit mailbox-level certainty.
Why does a website return no email but a contact form?
Some businesses deliberately publish only a form. The Actor reports a compatible form's URL, method, and fields so your workflow can distinguish “form only” from a failed scan.
Will the Actor return a row when a website is down?
Yes. Invalid, failed, timed-out, and budget-skipped inputs still produce explicit rows for reconciliation; only duplicate registrable domains are combined.
Does increasing maxPagesPerSite increase the price?
No. Page count does not change the website-scanned event price, although larger crawls can run longer.
Can I send the extracted contacts to Google Sheets, Zapier, Make, or n8n?
Yes. Use Dataset exports, native Apify integrations, webhooks, or the REST API to send results to those tools and your CRM.
Changelog
0.1.0 — 2026-08-24
- Initial production release.
- Added HTTP-first crawling, multilingual page scoring, JSON-LD and microdata, Cloudflare and obfuscation decoding, phone and social extraction, forms, optional Playwright fallback, three verification levels, migration-safe state, budget guards, complete schemas, and pay-per-event billing.