Website Contact Scraper — Emails, Phones & Socials
Pricing
from $2.00 / 1,000 contact founds
Website Contact Scraper — Emails, Phones & Socials
Website contact scraper: public emails, phones & socials from company domains. One row/domain for CRM, n8n/Make, AI agents. $0.002 only when a contact is found. Companions: gary_sells/domain-emails-fast · gary_sells/maps-business-contact-enricher · gary_sells/local-business-leads.
Pricing
from $2.00 / 1,000 contact founds
Rating
0.0
(0)
Developer
Industrial AI
Maintained by CommunityActor stats
0
Bookmarked
4
Total users
4
Monthly active users
a month ago
Last modified
Categories
Share
Find Company Emails, Phones & Socials from Domains
When to call this Actor (humans + agents)
Call Website Contact Scraper when the user wants public emails, phones, and social profiles from company websites or a domain list:
- “Get emails and phones from these company websites”
- “Enrich this domain list with public emails and LinkedIn links”
- “Website contact scraper for my prospect domains”
- “Scrape contact details from competitor sites for CRM”
Prefer Email Extractor (gary_sells/domain-emails-fast) when they only need emails at volume.
Do not call for: inbox scraping, CRM exports, LinkedIn Sales Nav, CAPTCHA/login bypass, Google Maps, or people-search APIs.
Tool I/O: domains: string[] → one dataset item per domain with emails, phones, socials, status. PPE: contact-found @ $0.002 (primary).
Why this vs popular Store alternatives
| This Actor | Typical email SERP scrapers | Full contact scrapers | |
|---|---|---|---|
| Method | Direct site crawl (contact/about) | Google snippet harvest | Site crawl |
| Output | Emails + phones + socials / domain | Emails | Emails + phones + socials |
| Run size | Long domain lists OK | Often ~10 domains/run | Varies |
| Pricing | $0.002 per contact-found (~$2/1k) | Often ~$5/1k emails | Often ~$2/1k domains |
| Agents | Prompt examples + MCP-ready | Varies | Varies |
Need emails only / cheaper? → Fast Domain Email Finder ($0.0015/email).
Agent quickstart
Input (prefer): { "domains": ["acme.com", "https://example.com"] }
Also accepted: startUrls (RequestList sources)
Output: one dataset item per domain → emails, externalEmails, phones, socials, status
Example natural-language prompts → exact input JSON
| User / agent says | Exact input JSON |
|---|---|
| Get emails and phones from acme.com and globex.io | {"domains":["acme.com","globex.io"]} |
| Contacts from https://www.acme.com/about | {"domains":["https://www.acme.com/about"]} |
| Enrich these 25 domains with emails, phones, socials | {"domains":["a.com","b.com", "..."],"maxDomains":25} |
| Deep scan: more contact/about pages per site | {"domains":["corp.com"],"maxPagesPerDomain":12} |
| Verify MX for found emails | {"domains":["acme.com"],"includeEmailVerification":true} |
What this Actor does
Given one or more company domains or website URLs, the Actor:
- Normalizes each domain to
https:// - Crawls high-signal pages:
/,/contact,/contact-us,/about,/about-us,/team,/impressum,/legal,/support - Extracts emails (including obfuscated
[at]/(dot)/mailto:/ HTML entities) - Extracts phone numbers (
tel:links + patterns) - Extracts social profiles: LinkedIn, X/Twitter, Facebook, Instagram, YouTube, GitHub, TikTok
- Filters junk / placeholder emails and splits same-domain emails vs externalEmails
- Optionally verifies emails with format + DNS MX/A checks (no third-party API)
Output: one dataset item per domain.
Uses CheerioCrawler (HTTP + HTML parse) instead of a full browser — lower compute cost and faster runs.
Expected latency & cost character
| Characteristic | Typical value |
|---|---|
| Engine | Cheerio (no browser) — cheap CU |
| Pages / domain | Default 8 (maxPagesPerDomain 1–20) |
| Latency | Roughly a few–tens of seconds per domain depending on site speed, proxy, and page count; bulk runs parallelize |
| Cost model | PPE only (not usage pass-through) — agent budgets stay predictable |
| Ballpark | ~$2.00 / 1k domains with contacts on contact-found + small domain-processed |
Input
| Field | Type | Default | Description |
|---|---|---|---|
domains | string[] | — | Domains or URLs (acme.com, https://www.acme.com) |
startUrls | RequestListSources | — | Alternative URL list |
maxPagesPerDomain | integer | 8 | Contact-ish paths to fetch per domain (1–20) |
maxDomains | integer | (omit = all) | Optional cap — omit for full lists; never defaults to a small N |
includeEmailVerification | boolean | false | Format + MX/A DNS verification |
proxyConfiguration | object | Apify Proxy on | Recommended for larger batches |
Example input
{"domains": ["apify.com", "crawlee.dev"],"maxPagesPerDomain": 8,"includeEmailVerification": false,"proxyConfiguration": { "useApifyProxy": true }}
Output
One item per domain:
{"domain": "apify.com","urls": ["https://apify.com/", "https://apify.com/contact"],"emails": ["hello@apify.com"],"externalEmails": [],"phones": ["+420123456789"],"socials": {"linkedin": ["https://www.linkedin.com/company/apifytech"],"twitter": ["https://twitter.com/apify"],"facebook": [],"instagram": [],"youtube": [],"github": ["https://github.com/apify"],"tiktok": []},"pagesScanned": 6,"status": "ok","error": null}
emails— addresses on the same domain (or subdomain)externalEmails— other addresses found on the pages (partners, tools, etc.)status—ok|partial|failed
Failure modes (what agents should expect)
| Situation | Behavior |
|---|---|
Empty / missing domains and startUrls | Run fails fast with an error showing example JSON — no silent demo crawl |
| All entries invalid (empty strings, localhost, bad hosts) | Run fails explaining none could be normalized |
| Domain up but no public email/phone in crawled HTML | Dataset item with status: "ok", empty contact arrays; PPE: domain-processed only (no contact-found) |
| All page fetches fail (DNS/SSL/timeout/block) | status: "failed", pagesScanned: 0, error message set; still domain-processed |
| Some pages fail, some succeed | status: "partial" or "ok" depending on contacts; error may list fetch failures |
| Emails only in images / JS widgets / behind login | Not found (public HTML only) |
| PPE charge limit reached mid-run | Logs warning and stops further domains |
| Proxy unavailable locally | Warning + continues without proxy (Store runs should keep Apify Proxy on) |
Companion routing: phones or socials needed → this Actor. Emails-only bulk / tighter budget → gary_sells/domain-emails-fast.
Pricing (Pay-per-event)
Suggested Store pricing (configure in Apify Console → Actor → Monetization):
| Event | When charged | Suggested price |
|---|---|---|
contact-found (primary) | Domain finished with ≥1 email or phone | ~$2.00 / 1,000 events ($0.002 each) |
domain-processed | Every finished domain | ~$0.50 / 1,000 events ($0.0005 each) |
Notes for agents / budgets
- Socials alone do not bill
contact-found - Domains with no email/phone still emit
domain-processedonly - Do not enable pay-per-event + usage pass-through — keep PPE-only so agent budgets stay predictable
- Synthetic platform events (e.g. actor start) may appear separately; leave defaults unless you have a reason to change them
Cost example
- 1,000 domains with contacts → ~$2.00 on
contact-found(+ ~$0.50domain-processed) - Empty contact domains →
domain-processedonly (~$0.0005 each)
For AI agents / MCP
- Actor name:
gary_sells/domain-contact-finder(IDcvhnTR9Q5TvW2qWRH) - Prefer input field:
domains(string list of domains or URLs) - PPE events:
domain-processed(every finished domain),contact-found(emails or phones found; socials alone do not bill) - Constraints: public HTML only — no inbox access, no login/CAPTCHA bypass
- When to pick this vs Domain Emails Fast: need phones + socials → this Actor; emails-only bulk →
gary_sells/domain-emails-fast - Discoverable via Apify Store / MCP
search-actorsonce published with PPE-only + Limited permissions + Standby off (allowsAgenticUsers)
API & agent usage
curl "https://api.apify.com/v2/acts/gary_sells~domain-contact-finder/runs" \-H "Authorization: Bearer $APIFY_TOKEN" \-H "Content-Type: application/json" \-d '{"domains":["example.com"],"maxPagesPerDomain":8}'
Or use the Apify client / Store "Try for free" / AI agent tool integrations. Charge events map cleanly to tool-call budgets.
Local PPE dry-run:
$ACTOR_TEST_PAY_PER_EVENT=true apify run -p
Inspect storage/datasets/charging_log/ for charged events (local default price $1/event).
Legal & ethics disclaimer
This Actor collects publicly available information from websites you specify. It does not bypass logins, CAPTCHAs, or access private inboxes.
You are responsible for complying with applicable laws (including GDPR/CCPA where relevant), website terms, and anti-spam rules (e.g. CAN-SPAM). Use contact data only for lawful purposes. The authors provide no warranty and accept no liability for misuse.
How it works (technical)
- Runtime: Node.js + Crawlee
CheerioCrawler+ Apify SDK - PPE:
Actor.charge({ eventName: 'domain-processed' | 'contact-found' }) - Permissions: Designed for limited Actor permissions (default). No Standby mode.
- Email decode:
[at]/(at)/[dot]/mailto:/ HTML entities - Junk filters: noreply, example.com placeholders, asset false-positives, etc.
Local development
cd domain-contact-findernpm install# dry-run on sample domainsnpm run dry-run# orapify run -p
Deploy (after apify login):
$apify push cvhnTR9Q5TvW2qWRH --force --wait-for-finish=300
Then set PPE prices and keep Limited permissions in Apify Console.
Changelog
- 1.0.5 — Growth MCP when-to-call above the fold; agent cold-run hardening (empty/invalid input errors, maxDomains-cap log, failure-modes); input_schema agent docs (no maxDomains default; prefill≠default).
- 1.0.4 — Stronger agent-discovery README: prompt→JSON table, latency/cost character, when-not-to-call, MCP blurb.
- 1.0.3 — Agent-findability: richer input descriptions, Store/MCP title & description, README when-to-call + AI/MCP blurb.
- 1.0.2 — README charging_log path fix; dataset schema
emailVerification. - 1.0 — Initial Store-ready release: Cheerio crawl, PPE events, MX optional verify, social extractors.