# Website Contact & Social Finder: Emails, Phones, Socials (`hydrocore/website-contact-social-finder`) Actor

Turn a list of websites into contact data: one row per domain with company emails (info@, sales@...), phone numbers, postal address, 20+ social profile links (LinkedIn, Facebook, Instagram, X, TikTok, YouTube...) and an MX check. Pay only for websites where contacts are found.

- **URL**: https://apify.com/hydrocore/website-contact-social-finder.md
- **Developed by:** [Hydrocore Data](https://apify.com/hydrocore) (community)
- **Categories:** Lead generation, Automation
- **Security:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.72 / 1,000 website with contacts

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Website Contact & Social Finder: Emails, Phones, Socials

Paste a list of company websites and get **one tidy row per company**: business emails (info@, sales@, support@), phone numbers, postal address and links to 21 social networks (LinkedIn, Facebook, Instagram, X, TikTok, YouTube and more). Each email domain is checked to make sure it can receive mail. **You pay only for websites where contacts were found**, so dead, blocked or empty sites cost nothing.

No login and no browser extension. The finder visits only the public pages of each website, the way a visitor would.

**Sample result** (real row from a test run on `pipedrive.com`, trimmed):

```json
{ "domain": "pipedrive.com", "companyName": "Pipedrive", "primaryEmail": "support@pipedrive.com",
  "linkedin": "https://www.linkedin.com/company/pipedrive", "x": "https://x.com/pipedrive",
  "youtube": "https://www.youtube.com/@pipedrive", "socialLinkCount": 5, "status": "contacts-found" }
```

### What is this, in plain words?

Finding a company's contact details by hand means opening the website, hunting for the "Contact" or "About" page, scrolling to the footer and copying emails, phones and social links into a spreadsheet. This tool does that for you, for one website or for 10,000. For each website it reads the homepage and up to a few of the most useful pages (contact, imprint, about, locations), then puts everything it found into one row. You download the result as Excel, CSV or JSON, or send it to Google Sheets or your CRM with Apify integrations.

### What data do I get?

One row per website (domain):

- **Company name** (from the website itself)
- **Emails**: generic business addresses such as `info@`, `sales@`, `hello@`, `support@`, with `primaryEmail` as the best one. For each email you also see where it was found, whether it is on the company's own domain and whether that domain accepts mail (`mxValid`).
- **Phones**: in international format (`+18003155939`), plus how they were written on the page and where
- **Address**: from the site's structured data or address block, split into street, city, postal code and country when the site provides it
- **Social profiles**: one column each for LinkedIn (company page), Facebook, Instagram, X/Twitter, TikTok, YouTube, Pinterest, GitHub, Threads, Snapchat, Telegram, WhatsApp, Discord, Reddit, Medium, Vimeo, Yelp, Xing, Tumblr, Bluesky and Trustpilot, plus a `socialLinks` list with all of them
- **Contact page link**, the **pages checked** and a plain-English **status** for every site (`contacts-found`, `no-contacts`, `blocked`, `unreachable`, `timeout`, `parked`...)

Fake and placeholder addresses (`user@domain.com`, `email@example.com`, image file names that look like emails) are filtered out. Emails hidden with Cloudflare's email protection or written as "info (at) company (dot) com" are decoded.

### What can I use it for?

- **Lead generation**: turn a list of company websites (from a trade-show list, a directory or Google Maps) into contactable leads.
- **Enriching a CRM**: fill in missing emails, phones and LinkedIn pages for accounts you already have.
- **Agencies and freelancers**: find the right inbox and social channels of potential clients before you reach out.
- **Influencer and partner research**: collect a brand's Instagram, TikTok and YouTube in one go.
- **Data cleaning**: check which websites in a list are dead, parked or blocked, and which email domains no longer accept mail.
- **Local business research**: gather phone numbers and addresses of shops, clinics or restaurants from their sites.

### How do I use it?

1. Click **Try for free** (or **Start**).
2. Paste your **Websites**, one per line. `example.com`, `www.example.com` and `https://example.com/page` all work, and duplicates are removed automatically.
3. Leave the other settings as they are for your first run.
4. Click **Start**. 8 websites take about 5 seconds, 150 websites about 6 minutes.
5. Open the **Contacts** view and click **Export** to download.

### Input

| Field | What it does | Default |
|---|---|---|
| Websites | Domains or links, one per line | — |
| Pages to check per website | How many pages per site (homepage + best contact/about/imprint pages), 1–15 | 5 |
| Include personal emails | Also save emails of named people (`john.smith@`) and their LinkedIn profiles. Off = privacy-friendly. | off |
| Check that email domains accept mail (MX) | Adds `mxValid` to every email | on |
| Default country for phone numbers | Used to read local numbers without a `+` prefix (the site's country ending, such as `.de`, wins) | US |
| Only websites with an email | Charge and count a website only when a public email is found; sites with only phones or social links get a free `no-email` row | off |
| Also list websites without contacts | Keep a free row for every site with nothing found, so you can see why | on |
| Respect robots.txt | Skip pages the website asks robots not to visit | on |
| Websites checked at the same time | Speed, 1–40 | 10 |
| Max spend (USD) | The run stops before it costs more | — |
| Proxy (optional) | Not needed for normal use. See the FAQ. | off |

Example input:

```json
{
  "websites": ["apify.com", "https://www.sweetgreen.com", "heise.de"]
}
```

### Output example

Every row has the same columns in the same order; anything not found is `null` (empty lists too), counts are numbers and `scrapedAt` is ISO 8601 UTC. A real row from a test run on 4 November 2026, in the v1.1 column order. Empty social columns and `personalProfiles` (only filled when personal emails are on) are left out here.

```json
{
  "input": "apify.com",
  "domain": "apify.com",
  "websiteUrl": "https://apify.com/",
  "companyName": "Apify",
  "primaryEmail": "support@apify.com",
  "primaryPhone": null,
  "emails": ["support@apify.com", "hello@apify.com"],
  "emailCount": 2,
  "phones": null,
  "phoneCount": 0,
  "address": "Na Příkopě 959/27, 11000 Prague, CZ",
  "addressStreet": "Na Příkopě 959/27",
  "addressCity": "Prague",
  "addressRegion": null,
  "addressPostalCode": "11000",
  "addressCountry": "CZ",
  "addressSource": "json-ld",
  "linkedin": "https://www.linkedin.com/company/apify",
  "x": "https://x.com/apify",
  "tiktok": "https://www.tiktok.com/@apifytech",
  "github": "https://github.com/apify",
  "discord": "https://discord.com/invite/jyEM2PRvMU",
  "socialLinks": [
    "https://github.com/apify",
    "https://www.linkedin.com/company/apify",
    "https://x.com/apify",
    "https://www.tiktok.com/@apifytech",
    "https://www.tiktok.com/@apifyoffice",
    "https://discord.com/invite/jyEM2PRvMU",
    "https://discord.gg/w3e2v7rWDw"
  ],
  "socialLinkCount": 7,
  "contactPageUrl": "https://apify.com/contact",
  "status": "contacts-found",
  "statusDetail": "Found 2 email(s), 0 phone(s), 7 social link(s) on 3 page(s).",
  "charged": true,
  "emailDetails": [
    { "email": "support@apify.com", "type": "generic", "sameDomain": true, "foundOn": "https://apify.com/", "foundIn": "structured-data", "mxValid": true },
    { "email": "hello@apify.com", "type": "generic", "sameDomain": true, "foundOn": "https://apify.com/contact", "foundIn": "mailto-link", "mxValid": true }
  ],
  "phoneDetails": null,
  "personalEmailsHidden": 0,
  "pagesChecked": ["https://apify.com/", "https://apify.com/contact", "https://apify.com/contact-sales"],
  "pageCount": 3,
  "scrapedAt": "2026-11-05T04:50:36.638Z"
}
```

A site with nothing found gets a free row such as `"status": "blocked", "statusDetail": "The website blocks automated visitors (HTTP 403). Not charged."`. The run also saves a `RUN_SUMMARY` record with counts per status.

**Views.** The Output tab opens in **Overview** (domain, company, best email and phone, email count, city, country, main social links, contact page, status). There are also **All contacts**, **Address** (street, postal code, city, region, country), **Social profiles** (one column per network), **Status per website** and **Detailed** (all fields) views.

> Changed in v1.1: `checkedAt` → `scrapedAt` (same value, always the last column). `addressParts` is replaced by flat columns `addressStreet`, `addressCity`, `addressRegion`, `addressPostalCode`, `addressCountry`, `addressSource`. New count columns `emailCount`, `phoneCount`, `socialLinkCount`, `pageCount`. Empty lists are `null` instead of `[]`, and every row (including free failed or skipped ones) has the same fixed columns. New input **Only websites with an email** (`requireEmail`).

### How much does it cost?

You pay per website **with at least one contact found** (an email, a phone or a social profile). Apify platform usage is included, so there are no extra compute costs.

| Event | Apify Free plan | Paid plans (Starter and up) |
|---|---|---|
| Actor start (once per run) | $0.001 | $0.001 |
| Website with contacts found | $0.0034 ($3.40 per 1,000) | $0.00272 ($2.72 per 1,000) |
| Website with nothing found, blocked, dead or invalid | **free** | **free** |

All pages checked per site, the MX check, the address and every social network are included in that one price.

Worked examples (Free plan):

| Run | Calculation | Total |
|---|---|---|
| 8 websites, 7 with contacts | $0.001 + 7 × $0.0034 | **$0.0248** |
| 150 random websites, 64 with contacts (our test) | $0.001 + 64 × $0.0034 | **$0.2186** |
| 1,000 websites, 600 with contacts | $0.001 + 600 × $0.0034 | **$2.041** |
| A list of dead websites | start fee only | **$0.001** |

Set **Max spend (USD)** (or Apify's "Maximum cost per run") and the run stops cleanly before going over. Set a Max spend limit and the run stops cleanly before going over.

### Why this Actor?

Prices below are from the public Apify Store listings, **as of Nov 2026** (checked on 4 November 2026). Prices change, so check the listings for current figures.

| Actor | How it charges | Free plan | Paid plans |
|---|---|---|---|
| **This Actor** | per website **with contacts found**, all pages included | **$0.0034** | **$0.00272** |
| vdrmota/contact-info-scraper | per page scraped (5 pages ≈ 5 charges) + $0.001 per GB at start | $0.002 per page | $0.002 → $0.000378 per page |
| delicious_zebu/contact-info-scraper | per website (company) | $0.01 | $0.008 |
| emastra/website-contact-scraper | per website | $0.004 | $0.004 |

What you get here:

- **Competitive pricing** with pay-only-for-useful-results: empty, dead or blocked websites are free.
- **One clean row per company** instead of one row per page, so no merging in a spreadsheet afterwards.
- **Smart page choice**: contact, imprint, about and locations pages first, guessing `/contact` or `/impressum` when there is no link, and skipping login and cart pages.
- **Quality filters**: placeholder emails removed, Cloudflare-protected emails decoded, MX check on every email domain, phone numbers normalised to international format.
- **21 social networks** in their own columns, with company pages separated from personal profiles.
- **Privacy by default**: emails of named people are hidden unless you switch them on.
- **Honest status per site**: you see why a site had nothing (blocked, parked, unreachable, robots.txt...).
- **Fast and safe**: strict time limits per site, so one slow website never holds up the run, and a hard spending limit.

### FAQ

**How do I find the email address of a company from its website?**
Paste the website (for example `pipedrive.com`) into **Websites** and run. The finder checks the homepage, contact, about and imprint pages and returns the best business email as `primaryEmail`, plus every other email it found.

**Can I find social media links for a list of websites in bulk?**
Yes. Paste up to thousands of websites, one per line. Each row lists LinkedIn, Facebook, Instagram, X, TikTok, YouTube, Pinterest and 14 more networks the site links to.

**Which emails does it find?**
By default only generic business addresses (info@, sales@, contact@, support@, press@...) and emails that don't look like a person's name. Emails of named people (`anna.meier@company.com`) are counted in `personalEmailsHidden` but not saved.

**How do I get personal emails too, and is that allowed?**
Switch on **Include personal emails**. Personal emails, and LinkedIn profiles of individuals, are personal data under laws such as the GDPR (EU/UK) and CCPA (California). Only collect them if you have a legal basis, for example legitimate interest for B2B outreach, and follow anti-spam rules (opt-out, no bulk unsolicited email where it's banned). If in doubt, keep it off and ask a lawyer.

**Is scraping websites for contacts legal?**
The finder only reads public pages, respects robots.txt by default, never logs in and never solves captchas. Company contact details that a business publishes for the purpose of being contacted are generally fine to collect. You are responsible for how you use them, including privacy and anti-spam laws.

**What does `mxValid` mean?**
We ask the internet's address book (DNS) whether the email's domain has a mail server. `true` means the domain can receive email. It does not prove that the exact mailbox exists, and we never send test emails. Switch the check off if you don't need it.

**Why was a website "blocked" or "unreachable"?**
Some sites block automated visitors (HTTP 403, often Cloudflare "challenge" pages), some are down or no longer exist, and some are parked domains for sale. These rows are free. The finder doesn't try to get around blocks.

**Do I need a proxy?**
No. A few websites only block data-centre addresses. If many of your sites come back "blocked", you can try a proxy:

1. Open **Proxy (optional)** in the input.
2. Choose **Apify Proxy** and, if you have access, the **Residential** group.
3. Start the run. Proxy usage is billed by Apify separately on your account.

**Why is a phone or email missing that I can see on the site?**
The finder reads the page as the server sends it and doesn't run JavaScript. Contacts that only appear after scripts load, in images or behind a contact form can't be read. Raising **Pages to check per website** can also help on large sites.

**What does robots.txt do?**
It's a file where a website says which pages robots may visit. With **Respect robots.txt** on (the default), we skip pages it forbids. A site that forbids everything gets the free status `robots-disallowed`.

**How do I limit my spending?**
Set **Max spend (USD)**. The finder never starts a website it can't afford and stops cleanly at the limit.

### Limits

- No JavaScript rendering: contacts loaded by scripts, shown as images or hidden behind forms are not found.
- Sites that block automated visitors are reported as `blocked` (free). We never bypass blocks or captchas.
- At most 15 pages per website, 1.5 MB per page, about 60 seconds per website. Very slow sites end as `timeout` (free).
- Up to 15 phones, and up to 5 links per social network, per website.
- A social link found on a website can occasionally point to a partner or a founder rather than the company itself. Check `socialLinks` for the full list.
- `mxValid` checks the domain, not the individual mailbox.

### Ready-made examples

Open one, click **Try for free** and change the inputs to your own:

- [Find B2B emails and phones from SaaS company websites](https://apify.com/hydrocore/website-contact-social-finder/examples/saas-company-emails-phones)
- [Find Instagram, TikTok and Facebook links of ecommerce brands](https://apify.com/hydrocore/website-contact-social-finder/examples/ecommerce-brand-social-media-links)
- [Build a lead list: only websites with a working email](https://apify.com/hydrocore/website-contact-social-finder/examples/lead-list-emails-only)

### Related scrapers by hydrocore

- [ATS Job Board Scraper](https://apify.com/hydrocore/ats-job-board-scraper): find which companies are hiring, then get their contacts here
- [LinkedIn Jobs Scraper (No Login)](https://apify.com/hydrocore/linkedin-jobs-scraper-no-login): hiring companies as leads
- [Google Ads Transparency Scraper](https://apify.com/hydrocore/google-ads-transparency-scraper): companies that spend on ads
- [Website to Markdown & Text Crawler](https://apify.com/hydrocore/website-to-markdown-text): full page text for AI

### Support

Found a bug or a website where something was missed? Open an issue on the **Issues** tab, and please include the run link.

# Actor input Schema

## `websites` (type: `array`):

Company websites, one per line. A bare domain ("acme.com"), a full address ("https://www.acme.com") or a specific page all work. Duplicates are removed automatically. Social network links (facebook.com/..., linkedin.com/...) are skipped for free because they are not company websites.

## `maxPagesPerWebsite` (type: `integer`):

The home page plus the most promising contact, imprint (Impressum), about and location pages it links to. 5 finds the contacts on most sites; more pages = a bit slower, same price.

## `includePersonalEmails` (type: `boolean`):

Off (recommended): only company mailboxes such as info@, sales@, support@ or hello@ are returned, and emails that look like a person's name (john.smith@...) are hidden and only counted. Turn on only if you have a lawful reason to process personal data (for example GDPR legitimate interest) and will respect opt-out requests. Also adds personal LinkedIn profile links.

## `checkEmailMx` (type: `boolean`):

Looks up the DNS mail servers (MX records) of every email's domain, free and without sending anything. Emails whose domain cannot receive mail get mxValid = false, so you can drop them before an email campaign. This is a domain check, not a mailbox check.

## `defaultCountry` (type: `string`):

Two-letter country code (US, GB, DE, FR...) used to read local phone numbers written without a +country prefix on websites with a generic ending like .com. Country domains (.de, .co.uk, .fr...) use their own country automatically. Every phone is returned in international format (+14155550123).

## `requireEmail` (type: `boolean`):

On: a website counts as a result (and is charged) only when at least one public email is found. Websites with only phones or social links are saved as free <code>no-email</code> rows (if "Save websites without contacts" is on). Off (default): any email, phone or social link counts.

## `saveEmptyWebsites` (type: `boolean`):

On: every website gets a row, and websites with no contacts, blocked, offline or parked domains are saved with a status explaining why (these rows are free). Off: only websites with contacts are saved.

## `respectRobotsTxt` (type: `boolean`):

On (recommended): pages that a website's robots.txt asks automated tools not to read are skipped. Turning this off does not bypass logins or CAPTCHAs; those are never touched.

## `maxConcurrency` (type: `integer`):

How many websites are checked in parallel. 10 is a good default for 256 MB of memory; use up to 20-40 with 512 MB-1 GB for very long lists.

## `maxSpendUsd` (type: `string`):

Optional hard limit for this run, for example 5 = never charge more than $5.00. The run stops before going over it. Leave empty for no extra limit (Apify's own "Maximum cost per run" setting also works).

## `proxyConfiguration` (type: `object`):

Not needed for most websites; requests go out directly by default. Turn on Apify Proxy only if many of your websites answer "blocked" from data-center addresses. Proxy traffic is billed by Apify separately.

## Actor input object example

```json
{
  "websites": [
    "apify.com",
    "https://www.sweetgreen.com"
  ],
  "maxPagesPerWebsite": 5,
  "includePersonalEmails": false,
  "checkEmailMx": true,
  "defaultCountry": "US",
  "requireEmail": false,
  "saveEmptyWebsites": true,
  "respectRobotsTxt": true,
  "maxConcurrency": 10,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

## `results` (type: `string`):

No description

## `contacts` (type: `string`):

No description

## `address` (type: `string`):

No description

## `social` (type: `string`):

No description

## `status` (type: `string`):

No description

## `summary` (type: `string`):

No description

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "websites": [
        "apify.com",
        "https://www.sweetgreen.com"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("hydrocore/website-contact-social-finder").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = { "websites": [
        "apify.com",
        "https://www.sweetgreen.com",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("hydrocore/website-contact-social-finder").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "websites": [
    "apify.com",
    "https://www.sweetgreen.com"
  ]
}' |
apify call hydrocore/website-contact-social-finder --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,hydrocore/website-contact-social-finder"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/QhPMolSDiolK1YVE0/builds/Z2PdYYQGb4oJP2LZI/openapi.json
