Contact Details Scraper - Emails, Phones & Socials
Pricing
from $3.00 / 1,000 website with contacts
Contact Details Scraper - Emails, Phones & Socials
Scrape emails, phone numbers and 16 kinds of social profiles (LinkedIn, Facebook, Instagram, X, YouTube, TikTok...) from any list of websites. Contact and imprint pages first, one row per website with company name, address and contact form. Pay only for websites with contacts.
Pricing
from $3.00 / 1,000 website with contacts
Rating
0.0
(0)
Developer
Eimantas V
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
7 days ago
Last modified
Categories
Features
Share
Contact Details Scraper finds the emails, phone numbers and social media profiles of any list of websites, plus the company name, address, contact page and contact form. Paste domains or URLs, get one clean row per website, ready for your CRM or outreach tool. No login, no API key, no browser, from $3.00 per 1,000 websites, and you pay only for websites where contacts were found.
joesstonecrab.com -> Joe's Stone Crab · info@joesstonecrab.com · +1 305-673-0365 · instagram.com/joesstonecrab · Miami Beach, FLdishoom.com -> Dishoom · hello@dishoom.com (+5 more) · +44 20 7420 9327 (+12 more) · LinkedIn, Instagram, X, YouTube, TikTok · contact form
Benchmark: 300 business websites taken from Google Maps, read in 3 min 33 s. Contacts on 250 of them; phones on 86 % and emails on 62 % of the websites that loaded.
What does Contact Details Scraper do?
It reads each website the way a person looking for contact details would: the home page first, then the contact, imprint, about, team and location pages, in 15 languages, before anything else. Everything found is merged into one row per website, with each email and phone number ranked and checked.
- Emails from mailto: links, page text, Cloudflare-protected addresses and spellings like "info [at] example [dot] com". Placeholders, image file names and tracking ids are refused. Each address is flagged as a shared mailbox (info@, sales@) or a person's, on the website's own domain or not, free provider (Gmail) or not, and its domain's mail servers are checked.
- Phone numbers from tel: and WhatsApp links, the site's structured data and the page text, validated with Google's numbering-plan data and returned in international format (+44 20 7420 9327) with the national format, country and line type (mobile or landline).
- 16 social networks: LinkedIn, Facebook, Instagram, X (Twitter), YouTube, TikTok, Pinterest, Threads, Snapchat, Telegram, WhatsApp, Discord, Reddit, GitHub, Bluesky and Medium. Share buttons, single posts and theme placeholders are left out.
- Company details: name, postal address, country, language, description, logo, contact page and whether the site has a contact form.
- Only pay for real results. A website with no email, phone or profile on it, a site that is down, parked or refuses the connection: never charged.
- Built for lead lists. Paste thousands of domains, upload a CSV or link a Google Sheet. Run it on a schedule, call it from the API, or connect it to Make, Zapier, n8n, Google Sheets or an AI agent through Apify's MCP server.
Why it is fast and cheap
Pages are read over plain HTTP, the way a browser downloads them, without starting a browser: one website takes 2-10 seconds and a fraction of a cent of computing. The crawl goes to the pages that hold contact details first, so 10 pages per website find what most sites publish. A page that does not answer is retried from another address automatically.
What data can you extract from websites?
| Field | Example | What it is |
|---|---|---|
companyName | Joe's Stone Crab | The business's name, from its structured data, site name or page title |
primaryEmail | info@joesstonecrab.com | The best address for outreach: own domain first, shared inboxes next, no-reply and privacy mailboxes last |
primaryPhone | +13056730365 | The best phone number, international format |
emails | ["hello@dishoom.com", "reservations@dishoom.com"] | Every email found, best first |
phones | ["+442074209327", "+441135171712"] | Every phone number found, international format |
phonesUncertain | ["+493089004333"] | Valid-looking numbers in the text with no phone label next to them: check before use |
linkedIns, facebooks, instagrams, twitters, youtubes, tiktoks, ... | ["https://www.instagram.com/joesstonecrab"] | Profiles on 16 networks, the one shown on the most pages first |
contactPageUrl | https://www.joesstonecrab.com/contact/ | The website's contact page |
hasContactForm, contactFormUrl | true, https://www.dishoom.com/say-hello/ | Whether a page has a message form, and which |
address, country, language | 11 Washington Ave, 33139, Miami Beach, FL, US, en-US | Where the business is |
description, logoUrl | The home page's description and the logo | |
emailDetails | { "email": "info@...", "type": "role", "onWebsiteDomain": true, "freeProvider": false, "mxFound": true, "foundOn": [...] } | Per email: type, own domain, free provider, mail servers, pages found on |
phoneDetails | { "phone": "+44...", "national": "020 7420 9327", "country": "GB", "lineType": "fixed_line", "source": "link" } | Per number: national format, country, line type, where it came from |
contactsFound, pagesScraped, scrapedUrls | 9, 10 | How many contacts, how many pages read, which pages |
How to scrape contact details from websites
- Click Try for free and paste your websites into Websites, one per line:
example.com,https://www.example.com/contact, or a line copied from a spreadsheet. For a long list, upload a file or link a Google Sheet under Website list. - Leave Max pages per website at 10, or raise it for staff directories with many personal emails.
- Click Start. Expect about 1,000 websites in 12 minutes.
- Open the Output tab: one row per website, or the Emails and Phones views with one contact per row. Download as CSV, Excel or JSON.
How much does it cost to scrape contact details?
You pay per website where at least one email, phone number or social profile was found, whatever the number of pages read. The price drops on higher Apify plans:
| Apify plan | Per 1,000 websites with contacts |
|---|---|
| Free | $5.00 |
| Starter | $4.00 |
| Scale | $3.50 |
| Business | $3.00 |
- 1,000 websites from a Google Maps search on the Starter plan: about 830 have contacts, so about $3.30.
- 10,000 company domains on the Business plan, 8,000 with contacts: $24.00.
- Scrapers that charge per page read cost $20-40 per 1,000 websites at 10-20 pages each. Here the price is per website, and only when it has contacts.
- A run also costs $0.00005 to start. Websites with nothing found, websites that fail and duplicates cost nothing.
- The Free plan's $5 monthly credit covers about 1,000 websites with contacts.
Input
{"websites": ["joesstonecrab.com", "https://www.dishoom.com/", "info@lilyandloaf.com"],"maxPagesPerWebsite": 10,"excludeUrlPatterns": ["/blog"]}
| Field | Default | Notes |
|---|---|---|
| Websites | apify.com (example) | Domains, URLs, lines with a URL in them, or a business email (its domain is read). Duplicates are skipped |
| Website list | Apify's URL list: add URLs, upload a text/CSV file, or link a Google Sheet. Takes startUrls input from other contact scrapers unchanged | |
| Max pages per website | 10 | Contact, imprint and about pages are read first; up to 50 |
| Max link depth | 2 | 0 = the start page only |
| Stay on the website | on | Subdomains included. Link-in-bio pages (Linktree, Beacons...) always lead to the sites they list |
| Stop at the first email | off | Fastest way to get one email per website |
| Only pages matching / Skip pages matching | Words or regular expressions, e.g. contact, /blog | |
| Country for local phone numbers | auto | e.g. US; worked out per website when empty |
| Check email domains | on | MX lookup per email domain, free |
| Only websites with contacts | off | Leaves empty websites out of the dataset (they are never charged either way) |
| Max websites | 100,000 | Cap for the run |
| Proxy | off | Pages load from the Actor's own address and retry through Apify datacenter proxy automatically. Residential proxy is not used |
Output
Each website is one row. The Overview view shows the key columns, Social profiles all 16 networks, Emails and Phones one contact per row, Company details the firmographics.
{"recordType": "website","input": "dishoom.com","url": "https://www.dishoom.com/","domain": "dishoom.com","companyName": "Dishoom Indian Restaurants","primaryEmail": "hello@dishoom.com","primaryPhone": "+442074209327","emails": ["hello@dishoom.com", "reservations@dishoom.com", "team@dishoom.com"],"phones": ["+442074209327", "+441135171712", "+442030067013"],"linkedIns": ["https://www.linkedin.com/company/dishoom"],"instagrams": ["https://www.instagram.com/dishoom"],"twitters": ["https://x.com/dishoom"],"youtubes": ["https://www.youtube.com/user/DishoomLondon"],"tiktoks": ["https://www.tiktok.com/@dishoom_uk"],"contactPageUrl": "https://www.dishoom.com/say-hello/","hasContactForm": true,"contactFormUrl": "https://www.dishoom.com/say-hello/","country": "GB","language": "en","emailDetails": [{ "email": "hello@dishoom.com", "onWebsiteDomain": true, "type": "role", "freeProvider": false, "mxFound": true, "foundOn": ["https://www.dishoom.com/frequently-asked-questions-faq/"] }],"phoneDetails": [{ "phone": "+442074209327", "national": "020 7420 9327", "country": "GB", "lineType": "fixed_line", "source": "link", "foundOn": ["https://www.dishoom.com/say-hello/", "https://www.dishoom.com/locations/"] }],"contactsFound": 24,"pagesScraped": 10,"pagesFailed": 0,"scrapedAt": "2026-11-03T12:55:37.007Z"}
A website that cannot be read becomes a row with "recordType": "error" and an errorCode, never charged:
errorCode | Meaning |
|---|---|
NOT_FOUND | The domain does not exist, or the page and its home page are gone |
PARKED_DOMAIN | The domain is parked, for sale, suspended or shows a server's default page |
BLOCKED | The site refuses automated visitors (strict bot protection) |
TIMEOUT / NETWORK / HTTP_ERROR | The site is down, too slow or answered with an error |
NOT_A_WEBSITE | A social media profile was given instead of a website |
UNSUPPORTED_CONTENT | The address is a PDF, image or other file, not a web page |
Tips and limits
- Google Maps lists: feed the
websitecolumn of a Google Maps export straight in; tracking parameters are ignored. - One email per company, fast: turn on Stop at the first email and set Max pages per website to 5.
- No JavaScript rendering. Contacts that only appear after scripts run (some single-page apps) can be missed; most sites, including Wix, Squarespace, Shopify and WordPress, publish them in the page itself.
- Sites behind strict bot protection (about 2 % of business websites) return
BLOCKEDand are not charged. - Contact forms hide emails. Many small businesses publish only a form; the row then shows the form page, the phone and the profiles.
- No people search. It returns what the websites publish, not employee lists from a database. For follower counts and profile details, run the profiles through the scrapers below.
- Hit your spending limit? The run stops cleanly at your maximum cost per run and keeps everything it collected. Raise the limit in the run options to read more websites.
FAQ
Is it legal to scrape contact details from websites?
This Actor reads only what websites show publicly, without logging in. Business contact details are generally fine to collect, but results can include personal data (a person's email or phone), which laws such as the GDPR and CAN-SPAM protect. Collect and contact people only with a legitimate purpose, honour opt-outs, and ask a lawyer if you are unsure.
Can I use it through the API or with Make, Zapier and n8n?
Yes. Every run can be started through the Apify API and returns the dataset as JSON, CSV or Excel. Schedules, webhooks and integrations for Make, Zapier, n8n and Google Sheets are on the Integrations tab.
Can AI agents use it?
Yes. Agents connected to Apify's MCP server can find and run this Actor as a tool ("find the contact email of these companies"), with the same per-website pricing.
Why did a website return fewer contacts than I can see in my browser?
Either the contacts are on a page beyond your page limit (raise Max pages per website), they are drawn by JavaScript after the page loads, or they sit in an image. The scrapedUrls field shows which pages were read.
Why did I get fewer rows than websites?
Duplicates (two spellings of one site) are merged, values that are not website addresses are skipped with a warning, and the run stops at your maximum cost per run or Max websites. The log says which.
Related scrapers
- Instagram Profile Scraper: followers, bio, emails and phones for the Instagram profiles found here.
- Facebook Pages Scraper: emails, phones, followers and ratings of the Facebook Pages found here.
- YouTube Channel & Video Scraper: subscribers and videos of the YouTube channels found here.
- Website Tech Stack & Lead Enrichment Scraper: the technologies, ad pixels and email security of the same domains.
Support
Missing a contact you can see on the site, or found a website that does not work? Open an issue on the Issues tab with the website and the run link, and it will be looked at quickly.