# Contact Details Scraper - Emails & Phones from Any Website (`akhil_rajesh/contact-details-scraper`) Actor

Contact details scraper and email extractor for any list of websites: emails, phone numbers, social profiles, contact pages and forms, and who runs each company. One clean row per website, best email first. $1 per 1,000 websites with contacts; sites with nothing found are free.

- **URL**: https://apify.com/akhil_rajesh/contact-details-scraper.md
- **Developed by:** [Akhil rajesh](https://apify.com/akhil_rajesh) (community)
- **Categories:** Lead generation, Automation, SEO tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.70 / 1,000 websites

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

## Contact Details Scraper: Emails & Phones from Any Website

Give it a list of websites. Get **one clean row per website**: the **best email first**, every email it found, **phone numbers in international format**, **social profiles**, the **contact page and form**, and **who runs the company**, read from the company's own pages.

**One flat price: $1.00 per 1,000 websites with an email or a phone number ($0.90 to $0.70 on Apify's paid plans), with platform usage included.** Reading 2 pages or 20 costs the same. A website where nothing is found costs nothing, and neither does a dead domain or a site that refuses the request.

### Why this scraper

- **You pay per website, not per page.** Page-priced scrapers charge for every page they open, found or not. Here, depth is free and an empty site is free.
- **One row per website, ready for a spreadsheet or a CRM.** No merging of page-by-page rows, no duplicates. `bestEmail` and `bestPhone` are columns you can use as they are.
- **The best address comes first.** The company's own domain before a Gmail address, a general or sales inbox before a named person, a person before support, legal or jobs.
- **Real phone numbers.** Every number is checked against its country's numbering plan and written as `+14155550123`. Coordinates, dates, order numbers, prices and sample numbers like (123) 456-7890 stay out. A number on a .com in Dublin is read as Irish, and a fax is marked as a fax.
- **It reads addresses simple scrapers miss.** Links, page text, `name [at] company [dot] com`, the site's structured data, and addresses behind Cloudflare's email protection.
- **Junk stays out.** No `logo@2x.png`, no tracking ids, no `you@example.com`. Made-up customers on a product page and the regulators named in a privacy policy are set aside in their own column, away from your list.
- **It finds who runs the company.** Owners, founders, directors and team members the site names, with their titles, from its team pages and legal notices (`Geschäftsführer`, `Inhaber`, `Managing Director`).
- **The contact page and form, in the same row.** Whether a site takes enquiries through a form, on which page, and through which service (HubSpot, Typeform, Google Forms, JotForm and others).
- **It says why a row is empty.** Dead domain, refused request, closed by robots.txt, parked domain: each gets a free row with the reason, so your list stays complete.

#### Tested head to head

We ran this Actor and three popular contact scrapers on the same 65 websites, on Apify, on the same day (October 31, 2026), at 6 pages per site. The sites were picked before anything ran: 30 Y Combinator startups and 35 local businesses from five cities.

| | Websites with an email | Phone numbers | Cost for this run |
|---|---|---|---|
| **This Actor** | **46** | International format, none invented | **about $0.05** |
| A per-contact scraper | 46 | International format, one wrong country | about $0.55 |
| A per-page scraper | 43 | Mixed with coordinates and ids | about $0.65 |
| A flat-price scraper | 33 | As written, with samples like (123) 456-7890 | about $0.10 |

#### What to expect on your own list

Measured on 1,100 websites nothing was tuned on, read from Apify's servers on October 31, 2026. Percentages are of the websites that could be read.

| Sample | Websites | Could be read | Email | Phone | Contact page | Contact form | Key person |
|---|---|---|---|---|---|---|---|
| Local businesses (Toronto, London, Berlin, Sydney, Dublin) | 800 | 84% | 80% | 82% | 79% | 44% | 14% |
| Startups (Y Combinator) | 300 | 95% | 82% | 27% | 54% | 33% | 31% |

The rest of the local list were mostly dead domains (old listings), sites that refused the request, and sites whose robots.txt closes them. A fresh list of live companies reads higher.

### Use cases

- **Lead lists:** add emails, phones and decision makers to company domains from Google Maps, directories, a CRM or a spreadsheet.
- **Agencies:** find local businesses with no contact form, no Instagram or no email on their site.
- **Recruiting:** reach the people who run small companies.
- **Sales research:** see who owns a business and how it takes enquiries before you call.
- **Automation:** enrich domains in n8n, Make, Zapier or your own pipeline through the API.

### How to use it in 4 steps

1. Open the **Input** tab and paste your websites, as domains or links, or add a text or CSV file or a Google Sheet shared with "anyone with the link".
2. Keep **Pages per website** at 6, or raise it for large sites.
3. Click **Start**.
4. Download the results as CSV, Excel, JSON or HTML from the **Output** tab.

### Input

| Field | What it does |
|---|---|
| Websites | Company websites as you have them: `acme.com`, `www.acme.com` or `https://acme.com/contact`. A website listed twice is read once. A deep link to one branch is read as its own website. |
| Or a file of websites | A longer list: upload a text or CSV file, or link one, or a Google Sheet. Every cell that is a website is read, whatever else the file holds. |
| Pages per website | How many pages to read on each site (default 6, up to 20): the homepage, then its contact, imprint, about, team and legal pages. It doesn't change the price. |
| Include people | Owners, founders, directors and team members the site names (on by default). |
| Default phone country | A two-letter country code for numbers written without one. Left empty, it is worked out for each site from its domain, address, language and the places it names. |
| Websites at a time | How many sites to read at once (default 30). |
| Proxy | Not needed for most sites. Apify's datacenter proxies or your own work; residential proxies aren't available. |

### What you get

eff.org, as read on October 31, 2026:

```json
{
  "website": "https://www.eff.org/",
  "domain": "eff.org",
  "status": "found",
  "companyName": "Electronic Frontier Foundation",
  "bestEmail": "info@eff.org",
  "emails": ["info@eff.org", "..."],
  "bestPhone": "+14154369333",
  "phones": ["+14154369333", "+15102438020"],
  "fax": "+14154369993",
  "keyPerson": "Allison Morris",
  "keyPersonTitle": "Chief Development Officer",
  "linkedin": "https://www.linkedin.com/company/EFF",
  "facebook": "https://www.facebook.com/eff",
  "instagram": "https://www.instagram.com/efforg",
  "tiktok": "https://www.tiktok.com/@efforg",
  "threads": "https://www.threads.com/@efforg",
  "contactPage": "https://www.eff.org/about/contact",
  "contactForm": false
}
```

| Field | Meaning |
|---|---|
| `status` | `found`: an email or a phone number (charged). Free: `nothingFound`, `refused`, `unreachable`, `robotsDisallowed`, `parked`, `notAWebsite`, `invalid`, `error`. |
| `statusReason` | Why, when the site wasn't read in full. |
| `bestEmail`, `emails` | The address to write to first, and every address, best first (at most 15). |
| `emailDetails` | Each address with its kind (general, sales, person, support, press, hr, legal, technical), scope (company, freeMail, otherDomain), the page it came from, how it was found, and whether its domain can receive mail. |
| `otherEmails` | Addresses set aside: at an unrelated domain on a page that isn't the home or contact page, or at a domain that can't receive mail. |
| `bestPhone`, `phones`, `fax` | Numbers in international format (at most 10). |
| `phoneDetails` | Each number with its national format, kind (phone, mobile, tollFree, fax) and the page it came from. |
| `keyPerson`, `keyPersonTitle`, `people` | Who runs the company, and everyone the site names (at most 15), with title, seniority and source. |
| `linkedin`, `facebook`, `instagram`, `x`, `youtube`, `tiktok`, `pinterest`, `threads`, `telegram`, `whatsapp` | The company's own profiles: not share buttons, posts or a website builder's page. |
| `contactPage`, `contactForm`, `contactFormKind`, `contactFormPage` | The contact page, and the form with its kind. A search box, a newsletter sign-up or a blog's comment form doesn't count as one. |
| `address` | The postal address, when the site publishes it in its structured data. |
| `needsJavaScript` | The homepage is almost empty without a browser, so the row may miss what the site draws with scripts. |

The **Output** tab has views for **Contacts**, **Every email and phone**, **People**, and **What wasn't read, and why**. Each run also saves a `RUN_SUMMARY` record for your pipelines.

### How much does it cost?

**$1.00 per 1,000 websites with an email or a phone number** on Apify's Free plan, $0.90 on Starter, $0.80 on Scale and $0.70 from Business up, with platform usage included. Rows with neither are free, however much was read.

| Websites you list | With contacts (about 75%) | You pay on the Free plan |
|---|---|---|
| 100 | 75 | $0.08 |
| 1,000 | 750 | $0.75 |
| 10,000 | 7,500 | $7.50 |

Set a **maximum cost per run** and the run stops there, says so, and lists how many websites went unread. Run it again on the same dataset by resurrecting the run, or use a new list.

### How it reads a website

Each site is read one page at a time, about a second apart, like a person clicking through it. It starts with robots.txt, then the homepage, then the pages most likely to hold contact details, in any language. A site whose `robots.txt` asks for a slower pace gets one.

It doesn't use a browser, which keeps runs fast and cheap: 1,000 websites take about 12 minutes. A site that turns the request away is reported as `refused`, and isn't asked again from another address.

### Good to know

- **Sites that draw everything with scripts** can come back thin. They are marked `needsJavaScript`.
- **The email check is on the domain.** It confirms a domain can receive mail; it doesn't prove a mailbox exists.
- **`people` lists what the site says.** A title can be out of date, and a small site may name no one.
- **Large chains** list many branches: `phones` holds the first 10 numbers, ranked by how clearly the site marks them.

### FAQ

**Is it legal to scrape contact details?** Reading what a company publishes on its own website is generally allowed, but what you do next is your responsibility. Emails and names of people are personal data under the GDPR and similar laws, and anti-spam laws such as CAN-SPAM and Canada's CASL cover what you send. Some countries restrict sending marketing email to addresses collected this way. Check the rules where you and your recipients are.

**Does it send emails or fill in forms?** No. It only reads.

**Why is there no email for a site that has one?** It may be drawn by a script (`needsJavaScript` marks those sites), be an image, or be on a page past your page limit.

**Can I use it from code or an AI agent?** Yes, through Apify's API, clients and MCP server, like any Actor. Send `{"websites": ["acme.com", "example.org"]}`. A `startUrls` list from another contact scraper works as it is.

**Something looks wrong?** Open an issue on the **Issues** tab with the website, and we'll look at it.

### Other Actors by this developer

- [Google Trends Scraper & API - Trending Now, Pinterest Trends](https://apify.com/akhil_rajesh/google-trends-scraper): Trending Now in 125 countries, interest over time, by region and rising searches without a login or API key, plus Pinterest Trends and Slack, Discord, Telegram or Teams alerts for new trends
- [YouTube Channel Scraper & Tracker](https://apify.com/akhil_rajesh/youtube-channel-scraper): exact subscribers, total views and video counts of YouTube channels without a login or API key, channels found by topic, plus new videos and growth with Slack, Discord or Teams alerts
- [Telegram Channel Scraper & Monitor](https://apify.com/akhil_rajesh/telegram-channel-scraper): posts, views, reactions, comments and exact subscriber counts of public Telegram channels without a login, plus new, edited and deleted posts with Slack, Discord or Teams alerts
- [Google Ads Transparency Scraper & Monitor](https://apify.com/akhil_rajesh/google-ads-transparency-scraper): every ad a brand runs on Google Search, YouTube, Shopping and Maps, with ad copy and targeting, political ad spend and ads Google removed, plus Slack, Discord or Teams alerts for new and stopped ads
- [Craigslist Scraper & Tracker](https://apify.com/akhil_rajesh/craigslist-scraper): Craigslist listings by keyword, city, state or link with prices, cars and rentals, plus new listings, price drops and Slack, Discord or Teams alerts
- [Kijiji Scraper & Tracker](https://apify.com/akhil_rajesh/kijiji-scraper): Kijiji listings by keyword, city and category with prices and price drops, cars and rentals, plus Slack, Discord or Teams alerts for new listings
- [Zillow Price Tracker & Scraper](https://apify.com/akhil_rajesh/zillow-price-tracker): Zillow homes for sale, sold and for rent, with price-drop tracking, Slack alerts and an MCP server
- [App Store Reviews Scraper & API](https://apify.com/akhil_rajesh/app-store-reviews-scraper): App Store reviews from 175 countries with developer replies, filters, ratings and keyword rankings, plus Slack, Discord or Teams alerts for new reviews
- [Google Play Reviews Scraper & API](https://apify.com/akhil_rajesh/google-play-reviews-scraper): Google Play reviews with app versions, developer replies and filters, plus installs, rankings and Slack, Discord or Teams alerts for new reviews
- [Yahoo Finance Scraper](https://apify.com/akhil_rajesh/yahoo-finance-scraper): quotes, history, financials, options and news, with an MCP server
- [AliExpress Price Tracker & Scraper](https://apify.com/akhil_rajesh/aliexpress-price-tracker): AliExpress search results with store prices, units sold and price history
- [Amazon.ca Product & Trending Tracker](https://apify.com/akhil_rajesh/amazon-ca-product-trending-tracker): Amazon Best Sellers, prices, search positions and reviews on 23 marketplaces, with change tracking
- [Sports API - Live Scores, Stats & Odds (Soccer, NBA, NHL, NFL)](https://apify.com/akhil_rajesh/sports-scraper): scores, statistics and odds for seven sports
- [Tennis API - Live Scores, Stats & Odds (ATP, WTA, ITF)](https://apify.com/akhil_rajesh/tennis-scraper): live scores, results, match statistics, point-by-point and bookmaker odds for ATP, WTA, Challenger and ITF
- [Google Hotels Scraper - Hotel Price Tracker & Comparison](https://apify.com/akhil_rajesh/google-hotels-scraper): hotel prices from Google Hotels, with price tracking
- [Price Tracker Canada - Best Buy, Walmart, Canada Computers](https://apify.com/akhil_rajesh/bot-wall-price-scraper): live price comparison across major Canadian retailers
- [AutoTrader Canada Scraper - Used Cars & Prices](https://apify.com/akhil_rajesh/autotrader-canada-scraper): Canadian vehicle listings with price, mileage, trim and dealer
- [Indeed Jobs Scraper - Canada, US, UK, Australia & More](https://apify.com/akhil_rajesh/indeed-jobs-scraper): job listings from Indeed in eight countries
- [SEEK, JobStreet & JobsDB Jobs Scraper](https://apify.com/akhil_rajesh/seek-jobstreet-jobsdb-scraper): jobs from SEEK, JobStreet and JobsDB in Australia, New Zealand and six Asian markets, with pay as numbers, applicant counts and change tracking
- [Wellfound (AngelList) Jobs Scraper - Salary & Equity](https://apify.com/akhil_rajesh/wellfound-jobs-scraper): startup jobs from Wellfound (formerly AngelList Talent) with salary and equity ranges and an exact Y Combinator flag
- [Job Bank Scraper - Canada Jobs, Salary & NOC Codes](https://apify.com/akhil_rajesh/canadian-jobs-scraper): Canadian job postings with salary, employer, location and NOC code

### Disclaimer

This Actor is a tool. You are responsible for how you use what it finds, including the GDPR and local privacy law, anti-spam law, and the terms of the sites you read. It follows each site's `robots.txt`.

# Actor input Schema

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

Company websites, one row each: domains or links, as you have them (acme.com, www.acme.com, https://acme.com/contact). A website listed twice is read once.

## `websiteFiles` (type: `array`):

A longer list: upload a text or CSV file, or link one, or a Google Sheet shared with 'anyone with the link'. Every cell that is a website is read, whatever else the file holds.

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

How many pages to read on each website, the homepage first, then its contact, imprint, about, team and legal pages. It doesn't change the price.

## `includePeople` (type: `boolean`):

Add the owners, founders, directors and team members the site names on its own pages, with their titles. It doesn't change the price.

## `defaultPhoneCountry` (type: `string`):

A two-letter country code (US, CA, GB, DE) for numbers written without a country code. Leave it empty to work it out for each site from its domain, address and language.

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

How many websites to read at once. Each site is read one page at a time, about a second apart.

## `proxy` (type: `object`):

Not needed for most websites. You can use Apify's datacenter proxies or your own; residential proxies aren't available in this Actor.

## Actor input object example

```json
{
  "websites": [
    "www.python.org",
    "www.mozilla.org",
    "www.eff.org"
  ],
  "maxPagesPerSite": 6,
  "includePeople": true,
  "maxConcurrency": 30
}
```

# Actor output Schema

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

No description

## `allContacts` (type: `string`):

No description

## `people` (type: `string`):

No description

## `problems` (type: `string`):

No description

## `allData` (type: `string`):

No description

## `runSummary` (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": [
        "www.python.org",
        "www.mozilla.org",
        "www.eff.org"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("akhil_rajesh/contact-details-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": [
        "www.python.org",
        "www.mozilla.org",
        "www.eff.org",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("akhil_rajesh/contact-details-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": [
    "www.python.org",
    "www.mozilla.org",
    "www.eff.org"
  ]
}' |
apify call akhil_rajesh/contact-details-scraper --silent --output-dataset

```

## MCP server setup

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