Contact Details Scraper: Emails, Phones & Socials per Website
Pricing
from $1.50 / 1,000 domains
Contact Details Scraper: Emails, Phones & Socials per Website
Paste a list of websites and get the emails, phone numbers and social profiles (LinkedIn, X, Facebook, Instagram, YouTube) published on each one. One flat price per website, all crawled pages included. A website where nothing is found is free. No login or API key. MCP-ready for AI agents.
Pricing
from $1.50 / 1,000 domains
Rating
0.0
(0)
Developer
The Mine Works
Maintained by CommunityActor stats
0
Bookmarked
14
Total users
2
Monthly active users
2 days ago
Last modified
Categories
Share
From The Mine Works, makers of Threads Scraper and B2B Leads Finder, with over 140,000 runs across 170+ public actors.
Paste a list of websites. For each one you get a single row with the email addresses, phone numbers and social profiles (LinkedIn, X, Facebook, Instagram, YouTube) that the business publishes on its own site. Bare domains, www. forms and full links all work, and repeats are merged, so https://www.basecamp.com/about and basecamp.com count as one website.
Why choose this actor?
- One flat price per website, however many pages it reads. In our 2 October test of 20 websites, 17 came back with at least one contact: 11 with an email, 14 with a social profile. You pay once per website with a contact, from $1.50 per 1,000 on Gold, whether the actor read 1 page or 25.
- Websites with nothing found are free. A site that publishes no contact, cannot be reached or blocks the request still gets a row, with the reason in plain words (for example "The website refused the request (HTTP 403)"), and that row costs nothing.
- No login, no API key, no proxy bill. The actor reads public pages over plain HTTP, without a browser, so it is cheap to run on long lists.
Part of The Mine Works Leads and business directories family: B2B Leads Finder, Google Maps Email Scraper, Skip Trace Lookup, JustDial Scraper, 2GIS Places Scraper, IndiaMART Scraper.
Try it in one minute
Paste this into the JSON tab of the input page and press Start. It returns one row per website in well under a minute.
{"domains": ["bluebottlecoffee.com", "zingermansdeli.com", "ghost.org"],"maxPagesPerSite": 5}
Give websites in domains, one per line, in any form: stripe.com, www.stripe.com or https://stripe.com/contact. Each entry is reduced to its domain. Moving over from another contact scraper? The actor also reads websites from startUrls (plain strings or {"url": "..."} objects), urls and websites, and a page limit from maxPagesPerDomain or maxRequestsPerStartUrl.
Apify's free plan includes $5 of credit every month, which covers about 1,950 websites with contacts at this actor's Free tier price ($2.50 per 1,000 websites with contacts, plus the $0.005 start fee on each run, in runs of 100). Websites where nothing is found do not use up that credit.
Copy to your AI assistant
themineworks/website-contact-finder on Apify. Reads each website you give it (homepage, contact, about and team pages, footer links) and returns one row per website with the emails, phone numbers and social profiles (linkedin, twitter, facebook, instagram, youtube) it publishes. Call ApifyClient("TOKEN").actor("themineworks/website-contact-finder").call(run_input={...}), then client.dataset(run["defaultDatasetId"]).list_items().items. Required: domains (array of domains or URLs). Optional: maxPagesPerSite (integer 1 to 25, default 5). Each row has domain, contactsFound, emails, phones, socials, pagesScanned, siteReachable, scrapedAt, and error when no page could be read. Only rows with contactsFound true are charged. Rows with _type "summary" or "info" are run reports and are never billed. Full spec: GET https://api.apify.com/v2/acts/themineworks~website-contact-finder/builds/default (Bearer TOKEN), which returns inputSchema and readme. Token: https://console.apify.com/account/integrations
Key features
- Up to 25 pages per website. The homepage first, then
/contact,/about,/contact-usand/team, then links in the footer and links whose address mentions contact, about, team, company or support. The actor stops early once a site has given an email, a phone number and a social profile. - Emails from links and text. Addresses in
mailto:links and in the page text, including ones hidden behind HTML entities, deduplicated across the pages read. - Phone numbers from
tel:links and text, with filters that skip prices, years, IDs and tax numbers. When the same number appears in national and international form, the international form is kept. - 5 social networks, one profile each. LinkedIn (company, personal and school pages), X or Twitter, Facebook, Instagram and YouTube. Share buttons and bare homepages are ignored.
- Clear reasons for misses. A site that cannot be read gets a plain explanation: the name does not resolve, it timed out, it refused the request (HTTP 403), it rate limited (HTTP 429) or it had a server error.
- Fast on long lists. Each website has a 45 second ceiling, and if the bare domain does not answer the actor tries the
www.form and plainhttp://before giving up. After 10 unreachable websites in a row the run stops, since that usually means a bad list.
How to use it
Basic: a short list of websites
{"domains": ["stripe.com", "apify.com", "mozilla.org"],"maxPagesPerSite": 5}
A long list in one run
{"domains": ["company-one.com", "company-two.co.uk", "https://www.company-three.de/kontakt", "..."],"maxPagesPerSite": 5}
Paste hundreds or thousands of websites; they are crawled one after another and each finishes within 45 seconds. Filter the dataset on contactsFound to keep only the ones that returned something.
Enrich a Google Maps or directory export
Most business listings carry a website but no email. Put the website column of your export into domains, then join the results back on domain. If you are starting from Google Maps itself, our Google Maps Email Scraper does the search and the email lookup in one step.
Sites that bury their contact page
{"domains": ["bigcorp.com", "university.edu"],"maxPagesPerSite": 15}
A higher page limit lets the actor follow more footer and "about" links on large sites. The price is per website, so this changes run time, not cost.
Weekly refresh of a CRM's published contacts
Save your account list as a task and schedule it weekly (for example 0 6 * * 1). Compare each week's emails, phones and socials with the last to spot changed phone numbers and new social profiles.
Input parameters
| Parameter | Type | Default | What it does |
|---|---|---|---|
domains | array of strings | none (form prefill: stripe.com, https://www.basecamp.com/) | The websites to check, one per line. Bare domains, www. forms and full URLs are all reduced to the domain; repeats are merged. Entries that are not a website are skipped and listed in the log. |
maxPagesPerSite | integer (1 to 25) | 5 | How many pages to read on each website. The price is per website, not per page. |
The input schema marks no field as required, but a run needs at least one website. Older field names from other contact scrapers also work: startUrls, urls and websites for the list, and maxPagesPerDomain or maxRequestsPerStartUrl for the page limit (used when maxPagesPerSite is left at 5).
How long a run takes. On Apify, a typical website takes a few seconds: a 7 website run on 19 September, on an earlier build, took 46 seconds. Slow or dead sites can take up to the 45 second ceiling each. The default run timeout is one hour; if a run is about to reach it, it stops cleanly and the summary row reports how many websites were skipped, so you can run the rest again.
What data do you get?
One row per website, with these fields:
domain: the website, as a bare domain.contactsFound:truewhen at least one email, phone number or social profile was found. Only these rows are charged.emails: deduplicated email addresses, as published. An address on another domain (an agency, a personal inbox) can appear when the site publishes it.phones: deduplicated phone numbers, as published.socials: profile links keyed by network:linkedin,twitter,facebook,instagram,youtube.pagesScanned: how many pages were read successfully.siteReachable:falsewhen no page could be fetched at all.error: why nothing could be read, in plain words. Present only whenpagesScannedis 0.scrapedAt: ISO timestamp.
emails and phones are always present, as an empty list when nothing was found, and socials as an empty object.
Check phone numbers and emails before you use them. Contacts are taken from page text, so what a site prints is what you get. In our 2 October test, 2 of 20 sites (basecamp.com and airtable.com) returned runs of calendar dates, such as 15 16 17 18 19 20 21, as phone numbers, and one site returned a template address (name@company.com) printed on its pages. Most phone numbers come back as published, such as 734-663-3400 or 020 7420 9327. Emails are not verified; run them through an email verifier before a large send.
Each run ends with a _type: "summary" row (domains_requested, domains_processed, domains_skipped, domains_with_contact, domains_unreachable, charged_for and ended_on_deadline) and a _type: "info" row. Neither is ever charged.
Stable fields for automations
These 8 fields were present in every website row we sampled (22 rows from the current build: our 2 October test and two platform runs):
| Field | What it holds |
|---|---|
domain | The website, as a bare domain |
contactsFound | true when any contact was found; only these rows are charged |
emails | List of email addresses (may be empty) |
phones | List of phone numbers (may be empty) |
socials | Object of profile links by network (may be empty) |
pagesScanned | Pages read successfully |
siteReachable | false when no page could be fetched |
scrapedAt | ISO timestamp |
We will not rename these fields. New fields may be added over time; existing ones keep their names.
Output examples
Real rows from our 2 October test run.
A restaurant group that publishes phone numbers and two social profiles:
{"domain": "zingermansdeli.com","contactsFound": true,"emails": [],"phones": ["+17346633354", "734-926-4005", "734-663-5282", "734-663-3400", "734-230-2300"],"socials": {"instagram": "https://www.instagram.com/zingermansdeli","facebook": "https://www.facebook.com/ZingermansDeli"},"pagesScanned": 5,"siteReachable": true,"scrapedAt": "2026-10-02T08:29:12.826Z"}
A brand with a support email and four social profiles:
{"domain": "bluebottlecoffee.com","contactsFound": true,"emails": ["support@bluebottlecoffee.com"],"phones": [],"socials": {"facebook": "https://www.facebook.com/bluebottlecoffee","twitter": "https://www.twitter.com/bluebottleroast","instagram": "https://www.instagram.com/bluebottle","youtube": "https://www.youtube.com/channel/UCyki4e6RG84BT_xzi4oYkRw"},"pagesScanned": 5,"siteReachable": true,"scrapedAt": "2026-10-02T08:29:50.718Z"}
A website that refused the request (free):
{"domain": "canva.com","contactsFound": false,"emails": [],"phones": [],"socials": {},"pagesScanned": 0,"siteReachable": false,"error": "The website refused the request (HTTP 403), usually bot protection.","scrapedAt": "2026-10-02T08:34:29.444Z"}
The summary row of the run (never charged; run locally, so charged_for reads 0; on Apify it equals the websites charged; internal counters trimmed):
{"_type": "summary","domains_requested": 20,"domains_processed": 20,"domains_skipped": 0,"domains_with_contact": 17,"domains_unreachable": 2,"charged_for": 0,"ended_on_deadline": false,"scrapedAt": "2026-10-02T08:37:00.084Z"}
Pricing
Pay per event: you pay once for each website that returned at least one contact, plus a small start fee per run.
| Event | Free | Bronze | Silver | Gold and above |
|---|---|---|---|---|
domain-processed, per website with contacts | $0.0025 | $0.002 | $0.00175 | $0.0015 |
domain-processed, per 1,000 websites with contacts | $2.50 | $2.00 | $1.75 | $1.50 |
apify-actor-start, per run | $0.005 per GB of run memory, minimum one event | same | same | same |
The start fee, exactly. Apify's apify-actor-start event is charged once when a run starts, at $0.005 for each GB of memory the run uses, with a minimum of one event. This actor runs on 1 GB by default, so a default run pays one event: $0.005.
Worked examples. Our 20 website test would cost 17 × $0.0025 = $0.0425 plus $0.005 on the Free tier. 1,000 websites where 700 publish a contact cost $1.75 plus $0.005 on the Free tier, or $1.05 plus $0.005 on Gold.
Never charged: websites with no contact found, websites that could not be reached or refused the request, repeats in your list, pages read, and the summary and info rows. The charge happens only after the row is saved in your dataset.
There is no scheduled price change for this actor. The Pricing tab on this page always shows the rate for your own plan; if it and this table ever differ, the Pricing tab is right.
FAQ
What does this actor read? The public pages of each website you give it: the homepage, the usual contact, about and team pages, and contact related links from the footer. It does not log in, fill in forms or open pages behind a password.
How many websites can I put in one run?
There is no fixed cap. Websites are processed one after another, each within 45 seconds, inside the run's one hour default timeout; raise the timeout in the run options for very long lists. If a run is about to time out, it stops cleanly and the summary row's domains_skipped tells you how many to run again.
Am I charged for a website with no contacts, or one that fails?
No. The charge happens only when a website's row contains at least one email, phone number or social profile, and only after the row is saved. Websites that publish nothing, time out, do not resolve or block the request get a free row with contactsFound: false, and an error when nothing could be read.
Does it work on JavaScript heavy websites or sites with bot protection? It reads pages over plain HTTP without a browser or proxy, which keeps it fast and cheap. Most business websites print their contact details in the page and work fine. Sites that build their content only in the browser can come back with fewer contacts, and sites that block automated visitors return a free row with the reason: in our test, canva.com refused with HTTP 403.
Are the emails and phone numbers verified? No. They are returned as the website publishes them, after filtering out obvious junk such as image file names. Some pages print example or staff addresses, and on 2 of 20 sites in our test calendar dates were picked up as phone numbers, so review phones before dialling and run emails through a verifier, such as our Email Verifier, before a large send.
Which social networks does it find? LinkedIn, X (Twitter), Facebook, Instagram and YouTube, one profile per network per website. A link counts only when it points at an actual profile, so share buttons and bare network homepages are ignored.
Can I run it on a schedule?
Yes. Save your input as a task, then in Apify Console open Schedules, click Create new and pick a cron expression such as 0 6 * * 1 for Mondays. Each scheduled run is billed like a manual one, per website with contacts.
What happens if many websites in a row cannot be reached? After 10 unreachable websites in a row the run stops, because that pattern usually means the list is bad. The summary row gives the reason and the number of websites not attempted, and none of them is charged. A website that answers but publishes nothing does not count toward this limit.
How do I export the data?
From the run's Storage tab as JSON, CSV, Excel, XML or HTML, or through the Apify API. In CSV and Excel, emails, phones and socials are spread over numbered or named columns. Skip rows that have a _type field if you want websites only.
Can I use it from Claude, ChatGPT or another AI assistant?
- Connector URL:
https://mcp.apify.com/?tools=themineworks/website-contact-finder. - Claude: Settings > Connectors > Add custom connector, paste the URL, sign in with Apify.
- ChatGPT: developer mode, add an MCP connector with the URL, sign in with Apify.
- Cursor or VS Code: add it as an HTTP MCP server with that URL.
- Claude Code:
claude mcp add -t http website-contact-finder "https://mcp.apify.com/?tools=themineworks/website-contact-finder".
It is also one of the tools inside our Lead Generation MCP server.
Is it legal to scrape contact details from websites? The actor reads only contact details a business has chosen to publish on its own public website, and it never logs in. Some addresses and numbers belong to named people, which makes them personal data. Whether and how you may contact them depends on where you and they are, including GDPR, CCPA and anti spam rules, so make sure you have a lawful basis for your outreach. This is general information, not legal advice.
Integrations
- Google Sheets: export a run to a sheet, or append each scheduled run to your account list.
- Make, Zapier and n8n: use the Apify app or node to start a run on new CRM accounts and write the contacts back.
- Webhooks: have Apify call your URL when a run succeeds, then fetch the dataset.
- API and client libraries: start runs and read datasets from Python, JavaScript or any HTTP client. The "Copy to your AI assistant" block above has the exact call.
- MCP clients: Claude, ChatGPT, Cursor, VS Code and Claude Code can call the actor through
https://mcp.apify.com.
Do not have the websites yet? Our Company Domain Finder turns company names into official websites.
More from The Mine Works
Leads and business directories
- B2B Leads Finder
- Google Maps Email Scraper
- Skip Trace Lookup
- JustDial Scraper
- 2GIS Places Scraper
- IndiaMART Scraper
- Yandex Maps Scraper
- US Business Registry
- Google Maps Scraper
- Yellow Pages Scraper
- Lead Generation MCP
- Google Maps Reviews Scraper
Social media and video
Marketing, SEO and reviews
Real estate
Science, health and government data
Jobs and hiring
E-commerce and marketplaces
Company and business data
Food and local services
Developer and AI tools
More tools
- Tennis Match & Player Data Scraper
- Google Hotels Prices Scraper
- LandWatch Scraper
- Taobao Products Scraper 淘宝 天猫
Support
Found a bug or need a field we do not return yet? Open an issue on the Issues tab of this page and we will reply there. To ask for a new data source, email dmineworks@gmail.com. A guide and FAQ for this actor also live at themineworks.com.
Contact Details Scraper turns a list of websites into one clean row each of emails, phone numbers and social profiles, and charges only for websites that returned a contact.

