# Website Email & Phone Finder - Contact Scraper (`invincible_brookbed/website-contact-finder`) Actor

Extract emails, phone numbers and social profiles from any website list. Crawls homepage plus contact/about pages. Fast lead capture for sales, agencies and CRM enrichment. Pay only when contacts are found. MCP-ready.

- **URL**: https://apify.com/invincible_brookbed/website-contact-finder.md
- **Developed by:** [Виталий Белогуров](https://apify.com/invincible_brookbed) (community)
- **Categories:** Lead generation
- **Security:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $10.00 / 1,000 contact results

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

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 Email & Phone Finder — Contact Scraper

**Website email finder and phone scraper for sales lists.** Paste domains or URLs, get emails, phone numbers and social profiles — one tidy record per site. You only pay when contacts are actually found (~**$10 per 1,000 sites**).

### Why users pick this Actor

- Clear pay-per-event pricing — you only pay for successful results (~$0.01/site with contacts)
- Structured JSON ready for CRM, sheets, Zapier/Make/n8n
- Works with AI agents via [Apify MCP](https://mcp.apify.com/)
- Honest limitations documented — no fake data

Website Contact Finder crawls each homepage plus the pages most likely to hold contact details (contact, about, imprint, team, support) with a fast, browser-free Cheerio crawler. It extracts and de-duplicates emails, phone numbers and LinkedIn / X (Twitter) / Facebook / Instagram profiles, then returns structured JSON, CSV or Excel-ready rows.

### What does it do?

- Visits the **homepage** and up to *N* **contact-style pages** per site (default: 3 pages total).
- Finds emails from `mailto:` links, visible text, JSON-LD, obfuscated `[at]`/`[dot]` patterns, HTML-entity encoding and **Cloudflare-protected emails**.
- Finds phone numbers from `tel:` links, schema.org markup and international or US-style numbers in page text.
- Picks up **company social profiles** and ignores share buttons, tracking links and post URLs.
- Filters out junk like `logo@2x.png`, placeholder addresses and tracking IDs.

### Why use this Actor?

| | Copy-paste by hand | Generic "crawl everything" scraper | **Website Contact Finder** |
|---|---|---|---|
| Setup time | Hours per list | Selectors and regex to write | **Paste URLs, click Start** |
| Targets contact pages automatically | Manual | Usually no | **Yes — keyword-ranked links** |
| Output | Spreadsheet you build | Raw pages | **Structured, de-duplicated records** |
| Speed | Minutes per site | Slow if browser-based | **Seconds per site (HTTP only)** |
| Cost control | Your time | Compute-based, unpredictable | **Flat per-result price + `maxResults`** |
| Charged when nothing is found | n/a | Yes | **No** |

### Input

| Field | Type | Default | Description |
|---|---|---|---|
| `startUrls` | array | — (required) | Website homepages to scan. Plain domains like `example.com` are accepted via API. |
| `maxPagesPerSite` | integer | `3` | Pages fetched per site including the homepage (1–20). |
| `maxResults` | integer | unlimited | Stop after this many site records. A simple spending cap. |
| `proxyConfiguration` | object | off | Optional; off by default. Enable Apify Proxy only for large lists. No captcha needed. |

Example input:

```json
{
    "startUrls": [{ "url": "https://apify.com" }, { "url": "https://crawlee.dev" }],
    "maxPagesPerSite": 3,
    "maxResults": 100,
    "proxyConfiguration": { "useApifyProxy": false }
}
```

### Output

One record per website. Download as JSON, CSV, Excel, XML or HTML, or read it via API.

```json
{
    "url": "https://apify.com/",
    "domain": "apify.com",
    "emails": ["hello@apify.com", "support@apify.com"],
    "phones": [],
    "social": {
        "linkedin": "https://linkedin.com/company/apify",
        "twitter": "https://x.com/apify",
        "facebook": null,
        "instagram": null
    },
    "pageTitle": "Apify: Full-stack web scraping and data extraction platform",
    "pagesCrawled": 3,
    "error": null,
    "scrapedAt": "2026-10-11T09:30:12.481Z"
}
```

If a site could not be fetched, or no contact details were found, you still get a record with an explanatory `error` message — so you always know what happened to each URL. A run summary (sites scanned, contacts found, charged events) is saved to the key-value store under `STATS`.

### Pricing

This Actor uses **pay-per-event** pricing:

| Event | Price | When it is charged |
|---|---|---|
| `contact-page` | **$0.01** (about $10 per 1,000 sites) | One site record that contains at least one email, phone or social profile |

- Sites that fail to load or yield no contact data are **not charged**.
- Platform usage costs are covered by the event price.
- Set `maxResults` or a maximum run cost in the Apify Console to cap spending; the Actor stops cleanly when the limit is hit.

### Use cases

- **Lead generation:** enrich a list of prospect domains with a reachable email or LinkedIn page.
- **Sales ops & CRM enrichment:** fill missing contact fields on existing account lists.
- **Local business outreach:** collect phone numbers and social links for agencies, shops and clinics.
- **Recruiting & partnerships:** find company contact points and social profiles quickly.
- **Market research:** check which competitors publish public contact channels.

### FAQ

**Does it work on JavaScript-heavy sites?**
It reads server-delivered HTML only. Sites that render contact details exclusively with client-side JavaScript may return fewer results. Most business sites still expose a `mailto:` or `tel:` link in the HTML.

**Does it guess or verify emails?**
No. It returns addresses that are published on the pages it visits. It does not guess patterns or run SMTP verification.

**How accurate are phone numbers?**
`tel:` links and schema.org values are very reliable. Numbers found in free text are pattern-based, so spot-check them for important campaigns.

**Which pages are crawled?**
The homepage first, then same-site links whose URL or text suggests contact, imprint, about, team, support or locations. Pages in other languages (e.g. *Kontakt*, *Impressum*) are recognised.

**Do I need proxies?**
Not for small lists. For hundreds of sites, or sites that block datacenter IPs, enable Apify Proxy.

**Is scraping contact data legal?**
Only collect publicly available business contact information, and follow GDPR, CAN-SPAM, ePrivacy and each site's terms. Personal emails are personal data in many jurisdictions; you are responsible for lawful use.

### MCP — use it from AI agents

This Actor is ready for the Model Context Protocol, so Claude, Cursor and other MCP clients can run it as a tool. Add it through the Apify MCP server:

`https://mcp.apify.com/?tools=fetch-actor-details,invincible_brookbed/website-contact-finder`

Then ask your agent something like *"Find contact emails and LinkedIn pages for these 20 domains."*

### Limitations

- No JavaScript rendering, logins, or CAPTCHA solving.
- Some sites block automated traffic; use proxies and expect occasional failures (reported in `error`).
- Obfuscation beyond the common patterns (images of emails, custom scripts) cannot be decoded.
- Social links are the first company-level profile found, not a verified "official account".

Found a site that should work but doesn't? Open an issue from the Actor page with the URL and we will take a look.

# Actor input Schema

## `startUrls` (type: `array`):

Websites to scan. Use the homepage (e.g. https://example.com). Domains without a scheme are accepted via the API and treated as https.

## `maxPagesPerSite` (type: `integer`):

Maximum pages fetched per website, including the homepage. The crawler prioritises links that look like contact, about, team, imprint or support pages.

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

Stop after this many website records have been saved. Leave empty or 0 for no limit. Handy as a spending cap.

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

Optional. Off by default — most sites work without a proxy. Enable Apify Proxy only for large lists or rate-limited sites. Captcha solving is not required.

## Actor input object example

```json
{
  "startUrls": [
    "https://apify.com",
    "https://crawlee.dev"
  ],
  "maxPagesPerSite": 3,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

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

Dataset with the extracted contact details.

## `stats` (type: `string`):

End-of-run statistics (sites scanned, contacts found, charged events).

# 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 = {
    "startUrls": [
        "https://apify.com",
        "https://crawlee.dev"
    ],
    "proxyConfiguration": {
        "useApifyProxy": false
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("invincible_brookbed/website-contact-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 = {
    "startUrls": [
        "https://apify.com",
        "https://crawlee.dev",
    ],
    "proxyConfiguration": { "useApifyProxy": False },
}

# Run the Actor and wait for it to finish
run = client.actor("invincible_brookbed/website-contact-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 '{
  "startUrls": [
    "https://apify.com",
    "https://crawlee.dev"
  ],
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}' |
apify call invincible_brookbed/website-contact-finder --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,invincible_brookbed/website-contact-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/qWLTgKJT7644xqhK3/builds/nakyp1W9m6f0nwv5X/openapi.json
