# Website Contact Scraper - Company Emails, Phones & Socials (`teddythebuilder/website-contact-scraper`) Actor

Extract company contact details from business websites: role-based emails (info@, sales@, support@), phone numbers, LinkedIn/Facebook/Instagram/X/YouTube profiles, address and contact page. GDPR-friendly: no personal emails. Fast, no browser. Export JSON/CSV or call via API/MCP.

- **URL**: https://apify.com/teddythebuilder/website-contact-scraper.md
- **Developed by:** [Teddy Wasserman](https://apify.com/teddythebuilder) (community)
- **Categories:** Lead generation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.65 / 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

### What does Website Contact Scraper do?

Website Contact Scraper is a **company contact details extractor** for lead generation and CRM enrichment. Give it a list of company websites or domains and it returns, for each one, the **company emails** (info@, sales@, support@, press@ …), **phone numbers**, **social media profiles** (LinkedIn company page, Facebook, Instagram, X/Twitter, YouTube, TikTok, GitHub, Pinterest and more), the **postal address**, and the **contact page and contact form URLs**.

It scans the homepage and the most relevant contact, about, imprint and support pages of each site with fast HTTP requests, no browser. It is **GDPR-friendly by design**: it returns company-level contact points only and never outputs personal email addresses such as jane.doe@company.com.

### Why use Website Contact Scraper?

- **One row per company.** All contacts of a website merged and de-duplicated, ready to import into a CRM or a spreadsheet.
- **Company contacts, not personal data.** Role-based emails, switchboard numbers and official company profiles are what B2B outreach and data enrichment need, and they carry far less privacy risk than scraped personal addresses. Personal-looking addresses are counted (`personalEmailsSkipped`) but never returned.
- **Social profiles done right.** LinkedIn *company* pages only (never personal `/in/` profiles), real account URLs instead of share buttons, and the full list of profiles found per network.
- **Structured data aware.** Reads schema.org Organization / LocalBusiness JSON-LD for the company name, legal name, address, phone and `sameAs` profiles, and decodes Cloudflare-protected emails.
- **Pay only for results.** You are charged per website where contacts were found. Unreachable websites and websites without any contact details are free.
- **Fast and cheap.** No browser: 10 websites take about 7 seconds. robots.txt is respected.

### What data can you extract?

| Field | Example | Description |
|---|---|---|
| `website` | `https://apify.com/` | The website you gave |
| `domain` | `apify.com` | Domain without www |
| `companyName` | `Apify` | From schema.org or og:site_name |
| `legalName` | `Apify Technologies s.r.o.` | schema.org legalName when published |
| `emails` | `["hello@apify.com", "support@apify.com"]` | Role-based company emails |
| `emailSources` | `[{"email": "hello@apify.com", "foundOn": "https://docs.apify.com/legal"}]` | Page where each email was found |
| `phones` | `["+14152559096"]` | Phone numbers from tel: links and schema.org data |
| `linkedin` | `https://www.linkedin.com/company/apify` | LinkedIn company page |
| `facebook` | `https://www.facebook.com/joesbarbershopsf` | Facebook page |
| `instagram` | `https://www.instagram.com/ikea` | Instagram account |
| `x` | `https://x.com/apify` | X / Twitter account |
| `youtube` | `https://www.youtube.com/c/Apify` | YouTube channel |
| `tiktok` | `https://www.tiktok.com/@apifytech` | TikTok account |
| `socialProfiles` | `{"github": ["https://github.com/apify"], "bluesky": […]}` | Up to 5 profiles per network (also Pinterest, GitHub, Xing, Threads, Bluesky, Mastodon) |
| `address` | `{"streetAddress": "Olof Palmestraat 1", "postalCode": "2616 LN", "addressLocality": "Delft", "addressCountry": "NL"}` | Postal address from schema.org |
| `country` | `NL` | Address country |
| `contactPageUrl` | `https://www.mozilla.org/en-US/contact/` | Contact or imprint page |
| `contactFormUrl` | `https://basecamp.com/support` | Page with a contact form |
| `personalEmailsSkipped` | `2` | Personal-looking emails found but not returned |
| `pagesScanned` | `5` | Pages read on this website |
| `error` / `_info` | `http_403`, `No company contact details found` | Free rows: why nothing was returned |

### How to use Website Contact Scraper (step by step)

1. Click **Try for free**.
2. Paste company websites or domains into **Websites**, one per line (`apify.com`, `https://www.patagonia.com`, …). Thousands per run are fine.
3. Optional: change **Max pages per website** (default 5) or switch on **Only emails on the website's own domain**.
4. Click **Start**.
5. Open the **Contacts** view, or export the dataset to CSV, Excel or JSON. Join it back to your list on the `website` or `domain` column.

### Input example

```json
{
  "websites": [
    "apify.com",
    "https://www.patagonia.com",
    "https://www.joesbarbershop.com"
  ],
  "maxPagesPerWebsite": 5,
  "ownDomainEmailsOnly": true
}
```

### Output example

```json
[
  {
    "website": "https://apify.com/",
    "domain": "apify.com",
    "loadedUrl": "https://apify.com/",
    "companyName": "Apify",
    "legalName": "Apify Technologies s.r.o.",
    "emails": ["hello@apify.com", "legal@apify.com", "privacy@apify.com", "support@apify.com"],
    "phones": [],
    "linkedin": "https://www.linkedin.com/company/apify",
    "x": "https://x.com/apify",
    "youtube": "https://www.youtube.com/c/Apify",
    "tiktok": "https://www.tiktok.com/@apifytech",
    "socialProfiles": {"github": ["https://github.com/apify"], "tiktok": ["https://www.tiktok.com/@apifytech", "https://www.tiktok.com/@apifyoffice"]},
    "address": {"streetAddress": "Na Příkopě 959/27", "postalCode": "11000", "addressLocality": "Prague", "addressCountry": "CZ"},
    "country": "CZ",
    "contactPageUrl": "https://apify.com/contact",
    "contactFormUrl": "https://apify.com/contact-sales",
    "personalEmailsSkipped": 0,
    "pagesScanned": 5,
    "scrapedAt": "2026-10-21T19:58:00Z"
  },
  {
    "website": "https://www.joesbarbershop.com/",
    "domain": "joesbarbershop.com",
    "companyName": "Joe's Barbershop",
    "emails": [],
    "phones": ["+14152559096"],
    "facebook": "https://www.facebook.com/joesbarbershopsf",
    "x": "https://x.com/joesbarbershop",
    "pagesScanned": 2,
    "scrapedAt": "2026-10-21T19:58:01Z"
  }
]
```

Real output from October 2026; each website returns what it publishes.

### How much does it cost?

Website Contact Scraper uses pay-per-event pricing, charged **per website with results**, not per page.

| Event | Price (Free plan) | When it is charged |
|---|---|---|
| Actor start | $0.0005 | Once per run |
| Website with contacts | $0.003 ($3 per 1,000 websites) | A website where at least one email, phone, social profile or address was found |

Unreachable websites (DNS errors, timeouts, 403 bot protection), websites blocked by robots.txt and websites without any contact details are **free**. Paid Apify plans get Store discounts (Bronze −15%, Silver −30%, Gold and up −45%).

Worked examples (Free plan prices):

- **Enrich 1,000 leads from a spreadsheet**, 800 with contacts: 800 × $0.003 ≈ **$2.40**.
- **10,000 domains from a trade-fair exhibitor list**, 7,000 with contacts: ≈ **$21**.
- **Weekly refresh of 200 key accounts**: ≈ $0.60 per run, **about $2.40 per month**.

The Apify Free plan includes monthly platform credit, which covers runs like these.

### Use cases

- **B2B lead generation.** Turn a list of company domains (from a directory, a trade fair, Google Maps exports or a tech-stack search) into contact points for outreach.
- **CRM enrichment.** Fill missing phone numbers, generic emails and LinkedIn company URLs in HubSpot, Salesforce or Pipedrive.
- **Social media research.** Find every official social account of a list of brands, e.g. to monitor competitors or build influencer and partner lists.
- **Market mapping.** Collect addresses and countries of companies in a niche to see where they are based.
- **Data cleaning.** Check which websites in your database are dead (free error rows) and which still publish contact details.
- **AI agents.** Give an agent a tool that answers "how do I contact this company?" with structured, company-level data.

### Use with AI agents, MCP and the API

```bash
curl -X POST "https://api.apify.com/v2/acts/teddythebuilder~website-contact-scraper/run-sync-get-dataset-items?token=<TOKEN>" \
  -H "Content-Type: application/json" \
  -d '{"websites":["apify.com","patagonia.com"]}'
```

Python with `apify-client`:

```python
from apify_client import ApifyClient

client = ApifyClient("<TOKEN>")
run = client.actor("teddythebuilder/website-contact-scraper").call(run_input={
    "websites": ["apify.com", "python.org", "patagonia.com"],
})
for row in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(row["website"], row.get("emails"), row.get("phones"), row.get("linkedin"))
```

**MCP:** the actor is available as a tool in the Apify MCP server (`https://mcp.apify.com`) for Claude, ChatGPT, Cursor and other MCP clients.

### Integrations

Send results to Google Sheets, HubSpot, Salesforce, Pipedrive, Airtable, Make, Zapier, n8n, Slack or a webhook when a run finishes. Combine with a scheduled run to keep account data fresh.

### Data source and legality

The actor reads public pages of the websites you provide over HTTP, after checking each site's **robots.txt**. It does not log in, does not bypass bot protection or CAPTCHAs, and does not use proxies to hide.

It is built to return **company-level contact points only**: role-based mailboxes (info@, sales@, support@, …), phone numbers published on the website or in its structured data, official company social accounts and the business address. Emails that look personal (first or last names) are skipped and only counted. LinkedIn personal profiles are never returned. That keeps the output suited to B2B use under GDPR's legitimate-interest rules, but you remain responsible for how you contact people: follow your local direct-marketing laws (e.g. opt-in rules for email marketing) and honour opt-outs.

### FAQ

**Why are some emails missing?**
Personal addresses (e.g. anna.svensson@company.se) are intentionally not returned. Many companies also use only contact forms; then you get `contactFormUrl` instead. Emails that are only shown by JavaScript or as images can't be read without a browser.

**Which emails count as "role-based"?**
Addresses whose name part is a function: info, contact, hello, sales, support, service, office, press, media, marketing, hr, jobs, careers, billing, invoice, booking, orders, privacy, legal and about 150 more, in several languages (kontakt, kundservice, vertrieb, …), also with region suffixes like info.se@ or salesuk@.

**Why did a website return an error?**
`http_403` usually means bot protection; `dns_error` means the domain doesn't resolve; `blocked_by_robots_txt` means the site disallows crawlers. All of these rows are free.

**Does it find phone numbers written in the page text?**
It returns numbers published as clickable `tel:` links or in schema.org data, which are the numbers companies intend to be called on. Free-text number guessing is avoided because it produces many false positives (order numbers, VAT IDs).

**How many pages are scanned?**
The homepage plus up to 4 pages whose URL or link text looks like contact, about, imprint, support, press or locations. Change it with `maxPagesPerWebsite`.

**Can I run it on Google Maps results?**
Yes. Export the website column of any business list and paste it in.

**Something looks wrong for a website.**
Open an issue with the URL. We reply within 24 hours. If the actor helps you, a rating on the Store page helps others find it.

### Related actors

- [Tech Stack Detector](https://apify.com/teddythebuilder/tech-stack-detector): find companies that use Shopify, HubSpot, WordPress and 3,000 other technologies, then get their contacts here.
- [Domain WHOIS & DNS Lookup API](https://apify.com/teddythebuilder/domain-whois-dns-api): registration, MX/SPF/DMARC and SSL data for the same domains.
- [Nordic Company Registry API](https://apify.com/teddythebuilder/nordic-company-registry): official company records for Sweden, Norway and Finland.
- [Website to Markdown](https://apify.com/teddythebuilder/website-to-markdown): the readable content of any web page for AI and research.
- [Career Site Jobs API](https://apify.com/teddythebuilder/career-site-jobs-api): which companies are hiring, from their own job boards.

### Changelog and support

- **1.0 (October 2026):** first release. Role-based emails, phones, social profiles, schema.org name/address, contact page and form, Cloudflare email decoding, free rows for unreachable or empty websites.

Questions or feature requests? Open an issue on the actor page. We reply within 24 hours.

# Actor input Schema

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

Company websites or domains, one per line, e.g. apify.com or https://www.patagonia.com. The homepage and up to a few contact/about/imprint pages are scanned per website.

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

Homepage plus up to this many minus one contact, about, imprint or support pages, e.g. 5. The price is per website, not per page.

## `ownDomainEmailsOnly` (type: `boolean`):

Drop emails on other domains (e.g. an agency's or a parent company's address found on the page).

## `maxResults` (type: `integer`):

Stop after this many websites with contacts (websites without contacts are free and don't count).

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

How many websites are scanned at the same time.

## Actor input object example

```json
{
  "websites": [
    "https://apify.com",
    "https://www.python.org",
    "https://www.patagonia.com",
    "https://www.joesbarbershop.com",
    "https://www.ikea.com"
  ],
  "maxPagesPerWebsite": 5,
  "ownDomainEmailsOnly": false,
  "maxResults": 10000,
  "maxConcurrency": 10
}
```

# Actor output Schema

## `results` (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": [
        "https://apify.com",
        "https://www.python.org",
        "https://www.patagonia.com",
        "https://www.joesbarbershop.com",
        "https://www.ikea.com"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("teddythebuilder/website-contact-scraper").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": [
        "https://apify.com",
        "https://www.python.org",
        "https://www.patagonia.com",
        "https://www.joesbarbershop.com",
        "https://www.ikea.com",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("teddythebuilder/website-contact-scraper").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": [
    "https://apify.com",
    "https://www.python.org",
    "https://www.patagonia.com",
    "https://www.joesbarbershop.com",
    "https://www.ikea.com"
  ]
}' |
apify call teddythebuilder/website-contact-scraper --silent --output-dataset

```

## MCP server setup

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

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/sgIJwJOQZURF1eVhO/builds/ZDMyRJ4FNjwx24Agw/openapi.json
