# Website Contacts Crawler

> Extract emails, phone numbers, team names and LinkedIn links from company websites. Finds contact, team and about pages for you. One row per company; the contact fee applies only when found.

Actor id `quaking_pail/contact-crawler`. Index of all Epsimo actors: https://epsimo.org/llms.txt

## What it does

### Website Contacts Crawler

Website Contacts Crawler is a website contact extraction Actor that visits company websites, auto-discovers contact/team/about/leadership pages via site links and common path heuristics (including English and French page names), performs fast HTTP crawling without a browser, parses HTML to extract contact information, and returns one consolidated record per company. It extracts email addresses, phone numbers (international and local formats with placeholder numbers filtered), names associated with job titles, and LinkedIn profile links found on the site; it deduplicates results and includes counts of pages processed and pages with HTTP errors. Keywords: website crawler, contact scraper, email extraction, phone number extraction, team/leadership discovery, LinkedIn profile links, HTML parsing, link discovery, de-duplication, lead generation, CRM enrichment, sales prospecting.

### Use cases

- Build prospect lists for sales and SDR outreach from a list of company websites.  
- Enrich CRM exports (missing contact emails and phone numbers) for platforms like HubSpot, Pipedrive, or Salesforce.  
- Map leadership and team members for partner or competitor analysis.  
- Provide a contact-lookup step for developers and AI agents in enrichment or automation pipelines.  
- Convert a list of company domains into a consolidated contact sheet for outreach campaigns.  
- Feed extracted company contact data into LLMs or data enrichment workflows.

## Use cases and Limits

From the actor README on the Apify Store.

### Use cases for website contact extraction

- Turn a list of company domains into a contact sheet for outreach.
- Fill missing emails and phone numbers in HubSpot, Pipedrive or Salesforce exports.
- Find the leadership team of partner or competitor companies.
- Feed company contact data into an LLM or enrichment workflow.

### How much will it cost to find website contacts?

You **pay only per result, no subscription** and no rental. A result here is a **website where at least one email or phone number was found**. Websites with no email and no phone are still returned in the dataset, so you can see they were checked, but they are not charged the contact event. Standard platform events, such as the Actor start, are listed too.

Prices are shown on the **Pricing** tab and may differ by Apify plan. If you set a **maximum cost per run**, the crawler stops before the next website once that limit is reached, so a run never costs more than you allowed.

### Tips for better contact results

- Use the company's main domain (for example `example.com`, not a landing-page URL).
- Raise **Max pages per site** for large companies with separate team or leadership pages.
- Sites that load their content with JavaScript can return few or no contacts, because the crawler reads HTML only.
- People are detected only when a name appears next to a job title. Names without a role may be missed.

### FAQ, disclaimers and support

#### Is it legal to scrape contact details from websites?

You should be aware that your results could contain personal data. Personal data is protected by the GDPR in the European Union and by other regulations around the world. You should not scrape personal data unless you have a legitimate reason to do so. If you're unsure whether your reason is legitimate, consult your lawyers.

This Actor returns names, emails and phone numbers that websites publish, which is personal data in many cases. **You are responsible for making sure that your scraping and your use of the results are legal** in your country, including GDPR and anti-spam rules for outreach.

#### Does it find personal email addresses or scrape LinkedIn?

No. It only returns what is published on the website you give it. LinkedIn URLs are returned only when the website links to them.

#### Why did a website return no contacts?

The site may publish contacts only in images or forms, load content with JavaScript, or block automated requests. Check `pages_crawled` and `pages_failed` in the result and the run log.

#### How do I report a problem?

Open an issue in the **Issues** tab with the run ID so we can reproduce it. If the Actor saved you time, a rating on the **Reviews** tab helps other users find it.

## Input

| Name | Type | Required | Default | Allowed values / range | Description |
|---|---|---|---|---|---|
| `urls` | array of string | yes | - | - | List of company website URLs to crawl for contacts. |
| `maxPagesPerSite` | integer | no | `10` | min 1; max 50 | Maximum number of pages to crawl per website (homepage + discovered contact/team/about/leadership pages). |
| `delayBetweenRequests` | integer | no | `2` | min 0; max 30 | Delay in seconds between HTTP requests to be respectful to servers. |

## Example input

Built from the input schema prefill/default values (the actor publishes no example input).

```json
{
  "urls": [
    "https://apify.com"
  ],
  "maxPagesPerSite": 10,
  "delayBetweenRequests": 2
}
```

## Output

| Field | Type | Description |
|---|---|---|
| `company_name` | string or null | Company name derived from the website domain |
| `url` | string or null | Website URL that was crawled |
| `emails` | array or null | Unique email addresses found (max 20) |
| `phones` | array or null | Unique phone numbers found (max 10) |
| `people` | array or null | Names found next to a job title (max 30) |
| `linkedin` | array or null | LinkedIn profile URLs linked from the site (max 30) |
| `pages_crawled` | integer or null | Number of pages successfully crawled |
| `pages_failed` | integer or null | Number of pages that returned an HTTP error |

Dataset views: `overview` (Overview).

## Example output item

Built from the `example` values of the dataset schema.

```json
{
  "company_name": "Example Company",
  "url": "https://www.example-company.com",
  "emails": [
    "contact@example-company.com"
  ],
  "phones": [
    "+33 1 23 45 67 89"
  ],
  "people": [
    "Jane Doe"
  ],
  "linkedin": [
    "https://www.linkedin.com/in/janedoe"
  ],
  "pages_crawled": 5,
  "pages_failed": 2
}
```

## Pricing

Pay per event, in effect since 2026-10-16 (as of 2026-10-18). Each event below is charged.

| Event | Title | Description | Price USD (FREE tier) |
|---|---|---|---|
| `apify-actor-start` | Actor Start (once per run) | Charged when the Actor starts running. Number of events charged depends on Actor memory (one event per GB, minimum one event). | $0.00005 |
| `find-contact` | Website with contacts (primary) | Charged once per website where at least one email address or phone number is found. | $0.0055 |

Plan-tier prices for `find-contact`: FREE $0.0055, BRONZE $0.005, SILVER $0.0045, GOLD $0.004, PLATINUM $0.004, DIAMOND $0.004.

Prices are in USD at the Apify FREE plan tier; tiered events can cost less on paid Apify plans (plan-tier prices above). The [Apify Store page](https://apify.com/quaking_pail/contact-crawler) is authoritative: read the current price there instead of hardcoding these values.

## How to run

Run the actor and get its dataset items in one HTTP call (needs an Apify API token in `$APIFY_TOKEN`, sent in the `Authorization` header as Apify recommends ([Apify API authentication](https://docs.apify.com/api/v2))):

```bash
curl -X POST "https://api.apify.com/v2/acts/quaking_pail~contact-crawler/run-sync-get-dataset-items" \
  -H "Authorization: Bearer $APIFY_TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{
  "urls": [
    "https://apify.com"
  ],
  "maxPagesPerSite": 10,
  "delayBetweenRequests": 2
}'
```

Apify also accepts `?token=$APIFY_TOKEN` in the URL, but avoid it: URLs end up in logs and shell history.

If the run takes longer than 300 seconds, this endpoint returns HTTP 408 (Request Timeout). For longer runs start the actor with the asynchronous [Run Actor endpoint](https://docs.apify.com/api/v2/act-runs-post) and read the dataset when the run finishes. The `maxTotalChargeUsd` query parameter caps the total cost of a run ([run-sync-get-dataset-items reference](https://docs.apify.com/api/v2/act-run-sync-get-dataset-items-post)).

## Apify MCP

Apify hosts an MCP server at https://mcp.apify.com. The actor id is `quaking_pail/contact-crawler`; the `tools` query parameter loads only that actor as a tool ([Apify MCP server](https://docs.apify.com/platform/integrations/mcp)).

```json
{
  "mcpServers": {
    "apify": {
      "url": "https://mcp.apify.com?tools=quaking_pail/contact-crawler",
      "headers": {
        "Authorization": "Bearer $APIFY_TOKEN"
      }
    }
  }
}
```

Replace `$APIFY_TOKEN` with your Apify API token. Without the `headers` entry the client signs in to Apify with OAuth in the browser instead.

## Links

- Apify Store: [quaking_pail/contact-crawler](https://apify.com/quaking_pail/contact-crawler)
- Sources: [actor API](https://api.apify.com/v2/acts/quaking_pail~contact-crawler), [build API](https://api.apify.com/v2/acts/quaking_pail~contact-crawler/builds/default)
- Data fetched from the Apify API on 2026-10-18
- Build: 0.4.1

## Do not

- Do not hardcode prices: read them on the Apify Store page before a large run.
- Do not put the Apify token in shared URLs, prompts or logs; prefer the `Authorization` header.
- Do not treat the output as verified: it is scraped from public pages and can be incomplete, outdated or wrong.
