Website Contact Finder - Emails, Phones & Socials avatar

Website Contact Finder - Emails, Phones & Socials

Pricing

from $5.00 / 1,000 company with contacts

Go to Apify Store
Website Contact Finder - Emails, Phones & Socials

Website Contact Finder - Emails, Phones & Socials

Find emails, phones and social profiles for a list of company websites, plus each site's platform, Google Ads tag, Meta pixel and booking widget. One row per company. Pay only when contacts are found.

Pricing

from $5.00 / 1,000 company with contacts

Rating

0.0

(0)

Developer

Snappy

Snappy

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

9 days ago

Last modified

Categories

Share

Website Contact Finder – Emails, Phones & Socials per Company

Give it a list of company websites and get back one row per company with:

  • the emails it found
  • phone numbers, formatted for your CRM
  • LinkedIn, Facebook, Instagram, X and other social profiles
  • the contact page, contact form and address
  • the site's platform (WordPress, Shopify, Wix, Squarespace and others) and its marketing tags: Google Analytics, Google Ads, Meta pixel, plus any booking or chat widget

It checks the homepage, then picks the pages most likely to list contact details: contact, about, team, imprint and locations. It doesn't crawl the whole site. Your own columns (company name, CRM ID, owner) come back on the same row, so you can match results to your list.

You're only charged for websites where it finds an email or phone number. Dead domains, parked domains and sites with nothing published are free, and every row says what happened.

Contacts plus site signals, in one row

Agencies don't just want an email. They want to know who to pitch and what to pitch. The same pages the tool reads for contacts also show how the business runs its website, so each row tells you:

FieldWhat it tells youExample use
platformWordPress, Shopify, Wix, Squarespace, Webflow, GoDaddy, Duda, Framer and morePitch a WordPress care plan only to WordPress sites
ecommerceShopify, WooCommerce, BigCommerce, Magento and moreFind businesses that sell online
hasGoogleAdsA Google Ads tag (the advertiser's conversion or remarketing tag, not AdSense) is on the siteBusinesses already paying for ads, or ones that aren't yet
hasMetaPixelA Meta (Facebook) pixel is on the siteSell Facebook ads to those without one
hasGoogleAnalyticsGoogle Analytics is installedSpot sites nobody is measuring
hasGoogleTagManagerTags are loaded through Google Tag ManagerSee the note below
bookingWidgetAbout 30 booking tools, including Calendly, HotDoc, Fresha, Cliniko, OpenTable, ServiceM8 and Square AppointmentsFind clinics or trades that still take bookings by phone
chatWidgetIntercom, Tawk.to, Tidio, LiveChat, HubSpot, Zendesk, Podium and othersSell chat or AI receptionist services
techDetectedEverything above as one listQuick filtering in a spreadsheet

It costs nothing extra: no additional pages are loaded, and the price per company stays the same.

From a real run on 153 Melbourne plumbing websites: 85 were on WordPress, 58 loaded tags through Google Tag Manager, 18 had a Google Ads tag on the page, and only 6 had a Meta pixel on the page.

Note on Google Tag Manager: when a site loads its tags through Tag Manager, tags added inside it only appear once a browser runs the page. In that case, a tag that wasn't seen is reported as null ("can't tell"), not false, so you never get a wrong "no pixel".

Why one row per company matters

Many contact scrapers return one row per page. A company with eight pages gives you eight rows of mostly duplicate data, which you then have to merge, and you pay for every page. This tool merges everything for you and charges once per company.

One row per pageThis tool
Rows per companyOne per page crawled, merged later with another toolOne
You pay forEvery page crawledEach company where an email or phone was found
Pages it visitsDepends on crawl depth settingsHomepage plus the likeliest pages: contact, about, team, imprint, locations
Your own columns (CRM ID, owner)Not on the output rowCopied to every row
Sites with no contactsA row per pageOne free row that says why

It also finds emails that are easy to miss:

  • addresses hidden by Cloudflare's email protection ([email protected] on the page)
  • addresses written as info [at] acme [dot] com or info(at)acme.com
  • addresses in mailto: links, the page text, schema.org data and the page source

And it leaves out the junk that pattern matching picks up, like logo@2x.png, you@example.com, example addresses in form fields, error-tracking IDs and no-reply addresses.

What data you get

One row for every website in your list. Rows arrive as each website finishes, and inputIndex gives each row's position in your list, so you can sort them back into your order. Use the Primary contacts, All contacts, Site signals and Status per website tabs in the Output, or export everything as CSV, Excel or JSON.

FieldWhat it isExample
websiteWhat you enteredacme-plumbing.com.au
companyNameFrom the site's own name, schema data or titleAcme Plumbing
primaryEmailThe best address to contact the company: own domain first, then general inboxes like info@ and hello@. A gmail or bigpond address counts, the web designer's address in the footer doesn'tinfo@acme-plumbing.com.au
primaryPhoneBest phone number, in international format+61391234567
allEmails, allPhonesEverything found, comma separated (easy for spreadsheets)
emailsEach email with type (general or personal), ownDomain (the site's domain or the same brand on another domain, like acme.com for acme.com.au), domainAcceptsMail and the page it was foundOn
phonesEach number as e164 (+61391234567), national ((03) 9123 4567), country and foundOn
socialslinkedin, facebook, instagram, x, youtube, tiktok, pinterest, bluesky, threads, whatsapphttps://www.linkedin.com/company/acme
linkedinPeoplePersonal LinkedIn profiles linked from the site (staff pages)
contactPageUrl, contactFormUrlThe contact page, and the page with a contact form if there is one
addressPostal address, when the site publishes it as structured data1 Glenferrie Rd, Hawthorn VIC 3122, AU
platform, ecommerce, hasGoogleAnalytics, hasGoogleAds, hasMetaPixel, hasGoogleTagManager, bookingWidget, chatWidget, techDetectedSite signals, see aboveWordPress, true, Calendly
status, statusMessagecomplete, no data, failed or skipped, with a plain-English reasonFound 3 emails, 2 phone numbers and 4 social profiles on 4 pages.
pagesChecked, finalUrlHow many pages were read, and where the homepage ended up after redirects
Your columnsAnything you passed in with the websitecrmId, owner

A run summary (websites checked, found, failed, charged) is saved as OUTPUT in the key-value store.

How to use it

  1. Click Try for free.
  2. Paste your websites into Websites, one per line. Domains are fine (acme.com.au). Or put a link to a CSV in Or a link to a list, or pick a dataset from another Apify run.
  3. Click Start.
  4. Open the Primary contacts tab, or export the dataset to CSV or Excel.

Straight from Google Maps Scraper

Run Google Maps Scraper (or any tool whose results have a website field), then pick that run's dataset in Or a dataset from another Apify tool. Each place's website is checked, and its name, phone, address and place ID are copied onto the row. Places without a website come back as free failed rows, so your list stays complete.

Bring your own columns

From a spreadsheet: publish your Google Sheet as CSV (File → Share → Publish to web → CSV) and paste the link into Or a link to a list. If the sheet has a column called url, website or domain, every other column comes back on the output row.

From the API, n8n, Make, Zapier or Clay: send objects in Websites with your own columns:

{
"websitesWithData": [
{ "url": "acme-plumbing.com.au", "crmId": "C-1042", "owner": "Sam" },
{ "url": "https://www.example-bakery.com", "crmId": "C-1043", "owner": "Alex" }
]
}

If one of your fields has the same name as an output field (for example status), it comes back as input_status.

Useful options

  • What to find: switch off emails, phones, social profiles or site signals if you don't need them.
  • Only company-domain emails: keeps jane@acme.com for acme.com, and leaves out the web designer's address or a personal gmail.
  • Check email domains can receive mail (on by default): looks up each email domain's MX records. Emails on domains that can't receive mail are flagged with domainAcceptsMail: false. This checks the domain, not the individual mailbox.
  • Max pages per website (default 8): more pages finds more on big sites, but costs more time.
  • Extra pages to check: paths like /locations or /support to check on every site.
  • Country for phone numbers: numbers written without a country code need one. "Automatic" works it out from the domain (.com.au, .co.uk, .de), then the site's address or language, then falls back to the United States. If your list is mostly .com sites from one country, pick that country.

Input example

{
"websites": ["acme-plumbing.com.au", "https://www.example-bakery.com"],
"maxPagesPerSite": 8,
"getEmails": true,
"getPhones": true,
"getSocials": true,
"getSiteSignals": true,
"onlyCompanyDomainEmails": false,
"checkEmailDomains": true,
"defaultCountry": "auto"
}

Output example

A real row from a test run on eff.org (the staff list and some fields shortened):

{
"inputIndex": 1,
"website": "eff.org",
"companyName": "Electronic Frontier Foundation",
"primaryEmail": "info@eff.org",
"primaryPhone": "+14154369333",
"allEmails": "info@eff.org, press@eff.org, membership@eff.org, ...",
"allPhones": "+14154369333, +15102438020",
"emails": [
{ "email": "info@eff.org", "type": "general", "ownDomain": true, "domainAcceptsMail": true, "foundOn": "https://www.eff.org/about/contact" },
{ "email": "membership@eff.org", "type": "general", "ownDomain": true, "domainAcceptsMail": true, "foundOn": "https://www.eff.org/about/contact" }
],
"phones": [
{ "e164": "+14154369333", "national": "(415) 436-9333", "country": "US", "foundOn": "https://www.eff.org/about/contact" },
{ "e164": "+15102438020", "national": "(510) 243-8020", "country": "US", "foundOn": "https://www.eff.org/about/contact" }
],
"socials": {
"linkedin": "https://www.linkedin.com/company/eff",
"facebook": "https://www.facebook.com/eff",
"instagram": "https://www.instagram.com/efforg",
"youtube": "https://www.youtube.com/efforg",
"tiktok": "https://www.tiktok.com/@efforg",
"bluesky": "https://bsky.app/profile/eff.org",
"threads": "https://www.threads.net/@efforg",
"x": null, "pinterest": null, "whatsapp": null
},
"contactPageUrl": "https://www.eff.org/about/contact",
"status": "complete",
"statusMessage": "Found 79 emails, 2 phone numbers and 7 social profiles on 8 pages.",
"pagesChecked": 8,
"finalUrl": "https://www.eff.org/"
}

Site signals from two real Melbourne plumbers in the same test (other fields left out). The first loads its tags through Google Tag Manager, so Analytics and Google Ads show null ("can't tell") while the Meta pixel, written straight into the page, is true:

{ "platform": "WordPress", "hasGoogleAnalytics": null, "hasGoogleAds": null, "hasMetaPixel": true, "hasGoogleTagManager": true, "bookingWidget": null, "techDetected": ["WordPress", "Meta Pixel", "Google Tag Manager"] }
{ "platform": "GoDaddy Website Builder", "hasGoogleAnalytics": true, "hasGoogleAds": false, "hasMetaPixel": false, "hasGoogleTagManager": false, "bookingWidget": "ServiceM8", "techDetected": ["GoDaddy Website Builder", "Google Analytics", "ServiceM8"] }

A place from Google Maps whose "website" is really a Google link:

{
"inputIndex": 38,
"status": "failed",
"statusMessage": "\"https://www.google.com/maps/search/?api=1&query=...\" is a Google link, not the company's own website. Not charged."
}

Pricing

$5.00 per 1,000 companies with contacts found ($0.005 each), plus Apify's standard $0.00005 start fee. There's no separate platform usage charge.

A company counts when at least one phone number, or an email on the company's own domain (or a free mail inbox like gmail), is found. These are free:

  • websites where nothing was found
  • dead domains, parked domains and sites that wouldn't load
  • duplicates in your list
  • websites where the only emails are on domains that can't receive mail
  • websites where the only emails belong to another business, like the web designer credited in the footer
  • websites with only social profiles (unless you switched emails and phones off and asked for social profiles only)

A real test: 200 plumbers in Melbourne from Google Maps Scraper. 167 had a real website, and the tool found an email or phone for 151 of them (90%): 129 with an email, 148 with a phone number. The run took about 6 minutes and cost $0.76 (151 × $0.005). The other 49 rows were free.

What you runExample cost
100 business websites, about 90 with contactsabout $0.45
1,000 business websites, about 900 with contactsabout $4.50
10,000 business websites, about 9,000 with contactsabout $45

The page count doesn't change the price. Checking 8 or 20 pages on a site costs the same.

If you set a maximum cost per run, the tool stops starting new websites when it gets close. Websites it didn't get to are listed as skipped with a note, and aren't charged, so you can run just those again.

What it can't do (yet)

  • Some JavaScript-only sites. Some sites build their pages entirely in the browser. The tool doesn't run a browser, but it reads the site's own JavaScript files for email addresses, phone links and social profiles, which finds them on many of these sites. If the details are loaded from somewhere else, the site comes back as no data with that reason. Most business sites publish their contact details in the page itself and work fine.
  • Strong bot protection. If a site blocks direct visits, the tool retries through Apify's datacenter proxy automatically. A few sites block those too. They come back as no data with the reason, and you can try them again with residential proxies (Advanced → Proxy).
  • Mailbox checks. "Check email domains" confirms the domain accepts mail. It doesn't confirm the specific mailbox exists.
  • Logging in. It only reads public pages.
  • Guessing emails. It only returns addresses the site actually publishes. It doesn't make up firstname.lastname@ patterns.

Integrations

Run it from Apify's API, schedule it, or connect it to n8n, Make, Zapier, Clay or Google Sheets through Apify's integrations. AI agents can call it through the Apify MCP server. Send a CSV link or a list of objects, and use inputIndex or your own ID column to join the results back to your data.

FAQ

Why didn't it find an email I can see on the site? Open an issue with the website and the run link. The usual causes are a JavaScript-only page, an email shown as an image, or a contact page more than "Max pages per website" deep. The status message says which pages were checked. If it's a pattern I can fix, I'll fix it for everyone.

Does it follow every link on the site? No. It reads the homepage, then ranks links by how likely they are to hold contact details (contact, about, team, imprint, locations, support, privacy) and visits the best ones up to your page limit. If a site has no obvious contact link, it checks the sitemap and tries /contact and /contact-us.

What's the difference between general and personal emails? general is a shared inbox like info@, sales-au@ or a location inbox like melbourne@. personal looks like a named person, like jane.smith@. It's based on the address only, so treat it as a hint.

Which phone number is the primary one? The number the site repeats most (header, footer, contact page) usually wins, with extra weight for clickable "tel:" links, the site's structured data and the contact page. All numbers found are in phones. Fax numbers, ABNs, VAT numbers and other look-alikes are left out, and so are numbers that only appear in the privacy policy (usually a regulator's).

Is it legal to collect this? The tool only reads information businesses publish on their own public websites. But some of what it finds, like a named employee's email address, counts as personal data under laws like the GDPR, and email marketing is regulated in most countries (the Spam Act in Australia, CAN-SPAM in the US, PECR in the UK). You're responsible for how you use the results. If in doubt, ask a lawyer.

What does null mean for the pixel and Google Ads fields? "Can't tell". The site loads its tracking through Google Tag Manager, and tags added inside Tag Manager only appear when a browser runs the page. true and false are only used when the tool can actually see the answer in the page.

How accurate is the platform and tag detection? It looks for each tool's own code in the page (for example fbevents.js for the Meta pixel, /wp-content/ for WordPress, a book.servicem8.com link for ServiceM8). If a site hides or renames those, it won't be detected, and you'll get null or false rather than a guess.

Something isn't working? Open an issue on the Issues tab with your input and the run link. I usually reply within one business day.