Domain Contact Scraper – Intelligent Email & Phone Extractor
Pricing
from $2.00 / 1,000 domains
Domain Contact Scraper – Intelligent Email & Phone Extractor
Intelligent website contact scraper that extracts emails, phone numbers, WhatsApp links, and social profiles from any domain. Uses priority-first crawling and returns one structured, consolidated result per start URL with transparent crawl metadata.
Pricing
from $2.00 / 1,000 domains
Rating
5.0
(1)
Developer
Emiliano Mastragostino
Maintained by CommunityActor stats
3
Bookmarked
871
Total users
93
Monthly active users
8 days ago
Last modified
Categories
Share
Domain Contact Scraper
Extract emails, phone numbers, WhatsApp links, and social media profiles from any website — with structured, domain-level output.
Looking for a reliable website contact details scraper?
This Apify Actor intelligently crawls websites to extract:
- 📧 Email addresses
- 📞 Phone numbers
- 💬 WhatsApp links
- 🔗 Social media profiles (LinkedIn, Facebook, Instagram, Twitter/X, and more)
Unlike generic email extractors that dump raw page data, this Actor performs priority-first crawling and returns one clean, consolidated result per domain, including crawl metadata for full transparency.
Built for developers, agencies, and automation pipelines that need predictable and structured contact discovery.
🚀 Why Try This Actor?
✔ Intelligent, signal-driven crawl strategy
✔ Multilingual contact-page detection (contact, kontakt, contacto, contato, impressum, about, legal, etc.)
✔ One structured result per start URL
✔ Unambiguous result status (completed / partial / failed) with machine-readable termination reasons
✔ Transparent crawl metadata (page counters, timing, start-page resolution, sanitized errors)
✔ Configurable crawl depth and scope
✔ Optional early-stop modes for adaptive crawling
Whether you're building a lead generation workflow, enriching business directories, or automating contact discovery, this Actor provides structured, reliable output ready for integration.
🔍 What This Contact Scraper Does
For each start URL:
- Prioritizes high-value pages (contact, about, legal, multilingual equivalents)
- Crawls within a controlled scope (hostname, domain, origin, or all links)
- Extracts contact details
- Aggregates all results in memory
- Outputs exactly one structured result per domain
No fragmented per-page records. No messy datasets.
📦 Output Structure
Each start URL produces one result:
{"schemaVersion": 1,"status": "completed","hasContacts": true,"startUrl": "https://example.com","finalUrl": "https://www.example.com","contacts": {"emails": ["info@example.com"],"phones": ["+1 555 123 4567"],"socials": [{"type": "linkedin","value": "https://linkedin.com/company/example"}],"whatsapps": ["+15551234567"]},"crawl": {"pagesVisited": 4,"pagesAttempted": 4,"pagesSucceeded": 4,"pagesFailed": 0,"visitedSample": ["https://example.com", "https://example.com/contact"],"stoppedReason": "early-stop","terminationReason": "early_stop","startPageFinalUrl": "https://www.example.com/","startPageHttpStatusCode": 200,"startedAt": "2026-01-01T12:00:00.000Z","finishedAt": "2026-01-01T12:00:04.200Z","durationMs": 4200,"error": null,"updatedAt": "2026-01-01T12:00:04.200Z"}}
Result Delivery and Ordering
Results are written to the dataset as each domain finishes, not all at once at the end of the run:
- You see the first results within seconds of the run starting, and can stream them while the run continues.
- Results already written stay available even if the run is later aborted or times out.
- Dataset rows follow completion order, not the order of your input list. Fast domains appear before slow ones. Always match rows to your input by the
startUrlfield rather than by row position. - A normal, completed run still produces exactly one row per valid start URL.
Key Benefits of This Structure
- One consolidated result per domain
- Unambiguous result
statusandhasContactsfor workflow routing - Crawl transparency via page counters, timing, and a machine-readable
terminationReason - Structured contacts object for easy automation
- Versioned schema (
schemaVersion: 1) for stability
Contact Data Quality
Every contact is validated and deduplicated before it reaches the output:
- Emails — junk that looks like an address is rejected: asset filenames (
logo@2x.png), version strings from bundled code (@1.6.8), tracking IDs, and placeholder domains (example.com,yourdomain.com). Unusual-but-real addresses are kept.mailto:links carrying a query string or several recipients are recovered rather than dropped. - Socials — values are canonical URLs (
https, nowww., no tracking parameters,x.comfolded intotwitter.com), so the same profile is never reported twice. Share, login and hashtag pages are dropped; genuine handles (@someone) pass through unchanged. - Phones — validated with
libphonenumber-js: E.164 when the country is known (from the number itself, the site ccTLD, ordefaultPhoneCountry), otherwise a safe local form. Local and international spellings of one number collapse into a single entry, and IDs, order numbers and year ranges are rejected.
Result Status Semantics
Every result carries a top-level status:
| Status | Meaning |
|---|---|
completed | The crawl reached a normal configured end after at least one page was successfully processed. |
partial | Some pages succeeded, but the crawl was interrupted before its normal end. |
failed | No page was successfully processed for this domain. |
Contact presence never affects status: a fully crawled site with no contacts is completed with
hasContacts: false — use hasContacts to route empty results.
crawl.terminationReason explains why crawling ended, with stable machine-readable values:
crawl_completed, early_stop, page_limit_reached, global_request_limit_reached,
start_url_unreachable, start_url_blocked, request_failures, run_timed_out, user_aborted,
internal_error.
When a domain fails, crawl.error carries a sanitized diagnostic:
{"code": "DNS_ERROR","message": "The URL hostname could not be resolved.","retryable": true,"url": "https://does-not-resolve.invalid/"}
Error codes: DNS_ERROR, CONNECTION_ERROR, TLS_ERROR, HTTP_BLOCKED, HTTP_ERROR,
REQUEST_TIMEOUT, MAX_RETRIES_EXCEEDED, RUN_TIMEOUT, INTERNAL_ERROR.
Field notes:
crawl.pagesVisitedequalscrawl.pagesSucceeded; the invariantpagesAttempted = pagesSucceeded + pagesFailedalways holds (retries and redirects never inflate counters).crawl.startPageFinalUrlis the authoritative post-redirect URL of the start page; the legacy top-levelfinalUrlkeeps its historical behavior (last visited page).crawl.stoppedReasonis a legacy diagnostic kept for backward compatibility — new integrations should usecrawl.terminationReason.
🧩 Input Examples
Basic Usage (Quick Start)
{"startUrls": [{ "url": "https://apify.com" }]}
That’s it. The Actor will:
- Crawl the site
- Prioritize contact-related pages
- Return structured contact data
Advanced Configuration
{"maxPagesPerStartUrl": 8,"maxDepth": 1,"enqueueStrategy": "same-hostname","earlyStopMode": "balanced","proxyConfigurationOptions": {"useApifyProxy": true},"startUrls": [{ "url": "https://apify.com" }]}
Key Options Explained
-
maxPagesPerStartUrl Limits pages visited per domain.
-
maxDepth Controls how deep links are followed.
-
enqueueStrategy Defines crawl scope:
- same-hostname (default)
- same-domain (includes subdomains)
- same-origin
- all
-
earlyStopMode (optional)
- off (default)
- balanced
- aggressive
Balanced and aggressive modes allow the crawl to stop once sufficient direct contact signals are discovered or when exploration becomes stale.
-
defaultPhoneCountry (optional) ISO 3166-1 alpha-2 country code (e.g.
"IT","GB","US") used to validate and normalize local phone numbers when the website provides no reliable country context. It has no default. -
proxyConfigurationOptions Optional proxy settings for improved reach.
🧠 Intelligent Priority-First Crawling
This is not a simple depth-first or breadth-first scraper.
The Actor:
- Scores links before enqueuing
- Prioritizes high-value contact pages
- Supports multilingual detection (contact, kontakt, contacto, contato, impressum, about, etc.)
- Uses adaptive early-stop logic (optional)
This results in faster, more disciplined contact discovery.
🌍 SEO & Lead Generation Use Cases
This website contact scraper is ideal for:
- Lead generation workflows
- Business directory building
- Sales prospecting automation
- Agency outreach campaigns
- CRM enrichment
- Data collection pipelines
- Email extraction from company websites
⚙️ Designed for Developers & Automation
- Clean JSON output with multi-format export (CSV, Excel, XML, HTML)
- Domain-level aggregation
- Deterministic crawl behavior
- No per-page dataset fragmentation
- Works seamlessly with Apify API, webhooks, and SDKs
⚠️ Limitations
- Uses HTML parsing (Cheerio-based). Heavy client-side-rendered sites may require a browser-based crawler.
- Does not perform email verification (while it does perform basic email and phone validation)
- Does not identify specific individuals or job titles.
- Dataset rows are ordered by completion, not by input order — join on
startUrl, not on row position. - Duplicates are possible if a run is migrated or restarted by the platform. Each result is written at most once per run attempt. If the platform moves a long run to another server, the Actor restarts the crawl from scratch, and domains that were already written may be written a second time. If you need exactly-once semantics, deduplicate on
startUrlwhen consuming the dataset.
🚧 Roadmap & Upcoming Improvements
This Actor is continuously evolving. Key upcoming features include:
-
Browser-Based Crawling: Introducing Playwright Crawler to handle dynamic SPAs (React, Vue, Angular) while retaining lightweight HTML crawling as the high-speed default.
-
Email Verification: Optional features for MX record validation, SMTP checks, and deliverability indicators to enhance lead quality.
🏁 Summary
If you're looking for a reliable email extractor, phone number scraper, or website contact details scraper, this Actor provides:
- Structured, domain-level output
- Intelligent crawl prioritization
- Transparent crawl metadata
- Configurable exploration control
Built for predictable, disciplined website contact discovery — not blind scraping.
Support
This Actor is actively maintained. Need help or want to customize it?