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

Extract contact details from any website. Crawls the homepage plus contact/about/team/imprint pages and returns emails, phone numbers, social media links, and postal address per domain. Deobfuscates (at)/(dot) emails. Pure HTTP, no API key needed.

- **URL**: https://apify.com/thirdwatch/website-contact-scraper.md
- **Developed by:** [Thirdwatch](https://apify.com/thirdwatch) (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.10 / 1,000 results

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/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are a software tools running on the Apify platform, for all kinds of web data extraction and automation use cases.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

In JavaScript/TypeScript projects, use official [JavaScript/TypeScript client](https://docs.apify.com/api/client/js/docs.md):

```bash
npm install apify-client
```

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python/docs.md):

```bash
pip install apify-client
```

In shell scripts, use [Apify CLI](https://docs.apify.com/cli/docs.md):

````bash
# MacOS / Linux
curl -fsSL https://apify.com/install-cli.sh | bash
# Windows
irm https://apify.com/install-cli.ps1 | iex
```bash

In AI frameworks, you might use the [Apify MCP server](https://docs.apify.com/integrations/mcp.md).

If your project is in a different language, use the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).


# README

## Website Contact Scraper

> Turn a list of company websites into clean contact records: emails, phone numbers, social profiles, and a postal address for each one.

### What you get

Give this scraper a list of company domains and it returns one tidy contact record per website. It checks the homepage and the pages where companies usually publish their contact details (contact, about, team, and legal pages), then pulls out the emails, phone numbers, social media profiles, and postal address each company has chosen to share publicly.

It only reads contact information a company publishes on its own public website. It does not access private accounts, gated member areas, or personal data hidden behind logins. Coverage depends on what each site chooses to show, so it will not find details a company keeps private. When a site uses anti-bot protection, the scraper handles it automatically so you still get a result where the details are publicly visible.

Use it to build outreach lists, enrich your CRM, and skip the manual click-through-every-page research.

### Output fields

| Field | Description |
|-------|-------------|
| `domain` | The company's website, cleaned up to a standard form (with `www.` removed) |
| `emails` | List of email addresses found on the site, with duplicates removed |
| `phones` | List of phone numbers found on the site, with duplicates removed |
| `socials` | Social media profile links by platform: `linkedin`, `twitter`, `facebook`, `instagram`, `youtube`, `tiktok`, `github` |
| `address` | The company's postal address, when it is published on the site |
| `pagesCrawled` | How many pages on the site were successfully checked for this domain |
| `sourceUrls` | For derived details such as the address, the exact page the detail came from |

### Example output

```json
{
  "domain": "basecamp.com",
  "emails": ["support@basecamp.com", "press@basecamp.com"],
  "phones": ["+1-312-261-9899"],
  "socials": {
    "twitter": "https://twitter.com/basecamp",
    "youtube": "https://youtube.com/basecamp",
    "github": "https://github.com/basecamp"
  },
  "address": "30 N Racine Ave, Chicago, IL, 60607, US",
  "pagesCrawled": 6,
  "sourceUrls": {
    "address": "https://basecamp.com/about"
  }
}
````

### Input parameters

| Parameter | Required | Default | Description |
|-----------|----------|---------|-------------|
| `domains` | Yes | — | The websites to extract contact details from. You can paste plain domains (`example.com`), full URLs (`https://example.com/about`), or addresses with or without `www.` Each entry produces one result record. |
| `maxPagesPerDomain` | No | 10 | How many pages to check on each website. The scraper looks at the homepage plus common contact, about, team, and legal pages. A higher number finds more details but takes longer. Range 1–30. |
| `useBrowser` | No | false | Reserved for future use. The scraper handles anti-bot protection automatically, so you can leave this off. |

#### Example: enrich a single company

```json
{
  "domains": ["basecamp.com"],
  "maxPagesPerDomain": 10
}
```

#### Example: build a prospecting list from many domains

```json
{
  "domains": ["zapier.com", "stripe.com", "notion.so", "intercom.com"],
  "maxPagesPerDomain": 8
}
```

#### Example: fast pass on just the key pages

```json
{
  "domains": ["example.com"],
  "maxPagesPerDomain": 3
}
```

### Use cases

- **Sales and SDR teams:** Turn a list of target accounts into a ready-to-use outreach list with emails, phones, and social profiles, instead of researching each website by hand.
- **Growth and demand gen:** Enrich inbound leads or event lists with the public contact details a company shares, so your sequences reach the right inbox.
- **CRM and revenue ops:** Backfill missing email, phone, and social fields on accounts you already track, and keep records current across thousands of domains.
- **Recruiters and agencies:** Source the public contact points for companies you want to reach about hiring, partnerships, or client work.
- **Researchers and analysts:** Build a repeatable company contact dataset across many domains for market mapping or list-building projects.

### Limitations

We aim to be honest about what this does and does not do:

- It returns contact details a company publishes on its own public website. It is not a source of private or personal data, and it does not access login walls, gated member areas, or anything a company keeps off its public pages.
- Coverage is not 100%. If a company simply doesn't publish a phone number or address, there's nothing on the page to return.
- Some emails are only built on the page by the visitor's browser or are hidden behind a contact form. Those may not appear in the results.
- Address detection works best when a site publishes its address in a standard, machine-readable way. For unusual page layouts, the address may be missed.
- Phone number detection is deliberately cautious to avoid returning junk, so very unusual formats may occasionally be skipped.
- A small number of sites with very aggressive bot protection may return no usable content even though the scraper handles protection automatically.
- Always follow each website's terms of use and the laws that apply to you, including anti-spam and data-protection rules, when you use the contact details you collect.

### Compared to alternatives

The most popular comparable tool on the Apify Store is **vdrmota/contact-info-scraper** (Contact Details Scraper). Here's how this scraper differs:

- **Built for clean per-domain records.** You get exactly one structured record per website you submit — domain, emails, phones, socials, and address — which drops straight into a CRM or spreadsheet without extra cleanup.
- **Reads disguised emails.** It recognizes addresses written as `name (at) company (dot) com` and turns them back into real, usable emails, so you don't lose contacts that were deliberately obfuscated.
- **Real social profiles, not noise.** Share buttons, tracking widgets, and intent links are filtered out, so the social links you get are actual company profiles.
- **Tells you where each detail came from.** The `sourceUrls` field shows the exact page an address was found on, so you can verify before you reach out.
- **Focused and low-cost.** It targets the pages where companies actually publish contact details rather than crawling an entire site, which keeps runs fast and inexpensive.

If you need full-site crawling, JavaScript-rendered email extraction, or email verification, see "Custom builds" below.

### FAQ

**What can I paste into the domains field?**
A list of websites in almost any common form. `example.com`, `https://example.com/about`, and `www.example.com` are all accepted and cleaned up to a standard form automatically.

**Does it find emails written as "name (at) company (dot) com"?**
Yes. It recognizes the common ways companies disguise their email (such as `(at)`, `(dot)`, `at`, and `dot`) and converts them back into real addresses.

**Which social platforms does it detect?**
LinkedIn, Twitter/X, Facebook, Instagram, YouTube, TikTok, and GitHub. Share buttons and tracking links are filtered out so you get genuine company profiles.

**How many pages does it check per website?**
Up to your `maxPagesPerDomain` setting (10 by default): the homepage, common contact and about pages, and contact-related links it finds on the homepage.

**Do I need a proxy or an API key?**
No. There's nothing to configure. It handles anti-bot protection automatically so you can simply paste your domains and run.

**Is the data it returns private or personal?**
No. It only reads contact details a company chooses to publish on its own public website.

### Custom builds

Need deeper crawling, JavaScript rendering, contact-form detection, email verification, or dashboard-ready exports? Reach out to Thirdwatch at [thirdwatch.dev](https://thirdwatch.dev) or through the Apify actor support channel.

Last verified: 2026-06

# Actor input Schema

## `domains` (type: `array`):

List of websites to extract contact details from. Accepts bare domains (example.com), full URLs (https://example.com/about), or with/without www. Each entry produces one result row.

## `maxPagesPerDomain` (type: `integer`):

How many pages to check on each website. The scraper looks at the homepage plus common contact, about, team, and legal pages. A higher number finds more details but takes longer. Default 10.

## `useBrowser` (type: `boolean`):

Reserved for future use. The scraper handles anti-bot protection automatically, so you can leave this off.

## Actor input object example

```json
{
  "domains": [
    "basecamp.com",
    "zapier.com"
  ],
  "maxPagesPerDomain": 10,
  "useBrowser": false
}
```

# 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 = {
    "domains": [
        "basecamp.com",
        "zapier.com"
    ],
    "maxPagesPerDomain": 10
};

// Run the Actor and wait for it to finish
const run = await client.actor("thirdwatch/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 = {
    "domains": [
        "basecamp.com",
        "zapier.com",
    ],
    "maxPagesPerDomain": 10,
}

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

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

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

```

## CLI example

```bash
echo '{
  "domains": [
    "basecamp.com",
    "zapier.com"
  ],
  "maxPagesPerDomain": 10
}' |
apify call thirdwatch/website-contact-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=thirdwatch/website-contact-scraper",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "Website Contact Scraper - Emails, Phones & Socials",
        "description": "Extract contact details from any website. Crawls the homepage plus contact/about/team/imprint pages and returns emails, phone numbers, social media links, and postal address per domain. Deobfuscates (at)/(dot) emails. Pure HTTP, no API key needed.",
        "version": "1.0",
        "x-build-id": "E5ayKliVWN8SEYJQ3"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/thirdwatch~website-contact-scraper/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-thirdwatch-website-contact-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        },
        "/acts/thirdwatch~website-contact-scraper/runs": {
            "post": {
                "operationId": "runs-sync-thirdwatch-website-contact-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor and returns information about the initiated run in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/runsResponseSchema"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/acts/thirdwatch~website-contact-scraper/run-sync": {
            "post": {
                "operationId": "run-sync-thirdwatch-website-contact-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "inputSchema": {
                "type": "object",
                "required": [
                    "domains"
                ],
                "properties": {
                    "domains": {
                        "title": "Domains / URLs",
                        "type": "array",
                        "description": "List of websites to extract contact details from. Accepts bare domains (example.com), full URLs (https://example.com/about), or with/without www. Each entry produces one result row.",
                        "default": [],
                        "items": {
                            "type": "string"
                        }
                    },
                    "maxPagesPerDomain": {
                        "title": "Max Pages Per Domain",
                        "minimum": 1,
                        "maximum": 30,
                        "type": "integer",
                        "description": "How many pages to check on each website. The scraper looks at the homepage plus common contact, about, team, and legal pages. A higher number finds more details but takes longer. Default 10.",
                        "default": 10
                    },
                    "useBrowser": {
                        "title": "Use Browser (reserved)",
                        "type": "boolean",
                        "description": "Reserved for future use. The scraper handles anti-bot protection automatically, so you can leave this off.",
                        "default": false
                    }
                }
            },
            "runsResponseSchema": {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "string"
                            },
                            "actId": {
                                "type": "string"
                            },
                            "userId": {
                                "type": "string"
                            },
                            "startedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "finishedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "status": {
                                "type": "string",
                                "example": "READY"
                            },
                            "meta": {
                                "type": "object",
                                "properties": {
                                    "origin": {
                                        "type": "string",
                                        "example": "API"
                                    },
                                    "userAgent": {
                                        "type": "string"
                                    }
                                }
                            },
                            "stats": {
                                "type": "object",
                                "properties": {
                                    "inputBodyLen": {
                                        "type": "integer",
                                        "example": 2000
                                    },
                                    "rebootCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "restartCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "resurrectCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "computeUnits": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "options": {
                                "type": "object",
                                "properties": {
                                    "build": {
                                        "type": "string",
                                        "example": "latest"
                                    },
                                    "timeoutSecs": {
                                        "type": "integer",
                                        "example": 300
                                    },
                                    "memoryMbytes": {
                                        "type": "integer",
                                        "example": 1024
                                    },
                                    "diskMbytes": {
                                        "type": "integer",
                                        "example": 2048
                                    }
                                }
                            },
                            "buildId": {
                                "type": "string"
                            },
                            "defaultKeyValueStoreId": {
                                "type": "string"
                            },
                            "defaultDatasetId": {
                                "type": "string"
                            },
                            "defaultRequestQueueId": {
                                "type": "string"
                            },
                            "buildNumber": {
                                "type": "string",
                                "example": "1.0.0"
                            },
                            "containerUrl": {
                                "type": "string"
                            },
                            "usage": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "integer",
                                        "example": 1
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "usageTotalUsd": {
                                "type": "number",
                                "example": 0.00005
                            },
                            "usageUsd": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "number",
                                        "example": 0.00005
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
