# Contact Info Scraper — Emails, Phones & Social Links (`junipr/contact-info-scraper`) Actor

Extract public emails, phone numbers, addresses, contact pages, and social links from websites with lead-quality scoring and deduped exports.

- **URL**: https://apify.com/junipr/contact-info-scraper.md
- **Developed by:** [junipr](https://apify.com/junipr) (community)
- **Categories:** Lead generation, Developer tools
- **Features:** Limited permissions
- **Stats:** 36 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $12.00 / 1,000 site scrapeds

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.

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 Info Scraper — Emails, Phones & Social Links

### What does Contact Info Scraper — Emails, Phones & Social Links do?

Contact Info Scraper visits public website pages and extracts contact information present in the returned HTML. It finds email addresses, phone numbers, physical addresses, and social media profile links (LinkedIn, Twitter/X, Facebook, Instagram, YouTube, GitHub). Optional link following prioritizes contact-heavy pages such as `/contact`, `/about`, `/team`, `/impressum`, and `/support` within the configured page cap.

Give it a list of website URLs and it returns one structured result per successfully crawled domain with deduplicated contact details, crawl counts, and a deterministic lead-quality score.

### Features

- **Multi-signal extraction** — Emails, phone numbers, physical addresses, and social media profiles in one run
- **Smart crawling** — Automatically prioritizes contact, about, team, and support pages before general internal links
- **Six social platforms** — Detects LinkedIn, Twitter/X, Facebook, Instagram, YouTube, and GitHub profiles
- **Bounded batch processing** — Process up to 100 input websites with explicit site and page caps
- **Per-domain deduplication** — All results are deduplicated per domain so you get clean, unique data
- **Configurable extraction** — Toggle each extraction type on or off (emails, phones, socials, addresses)
- **Adjustable crawl depth** — Control how many pages per domain to crawl (1-10)
- **Contact page detection** — Reports the URL of the contact or about page if one was found
- **Polite crawling** — Configurable request delay and concurrency to respect target servers
- **Lead-quality score** — Rank each result from 0-100 using the public contact signals found
- **Optional proxy support** — Use an Apify proxy configuration when a target requires it

### Input Configuration

```json
{
  "urls": ["https://example.com"],
  "maxSites": 1,
  "maxPages": 1,
  "followLinks": false,
  "priorityPages": ["/contact", "/about", "/team", "/impressum", "/support"],
  "extractEmails": true,
  "extractPhones": true,
  "extractSocials": true,
  "extractAddresses": true,
  "maxConcurrency": 1,
  "requestDelay": 1000,
  "proxyConfiguration": { "useApifyProxy": false }
}
```

| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `urls` | string\[] | `["https://crawlee.dev"]` | Website URLs to scrape for contact information |
| `maxSites` | integer | `1` | Maximum input websites to process (1-100) |
| `maxPages` | integer | `1` | Maximum pages to crawl per domain (1-10) |
| `followLinks` | boolean | `false` | Follow internal links to discover more pages |
| `priorityPages` | string\[] | `["/contact", "/about", ...]` | URL paths to crawl first |
| `extractEmails` | boolean | `true` | Extract email addresses |
| `extractPhones` | boolean | `true` | Extract phone numbers |
| `extractSocials` | boolean | `true` | Extract social media profile links |
| `extractAddresses` | boolean | `true` | Extract physical addresses |
| `maxConcurrency` | integer | `1` | Maximum concurrent requests (1-5) |
| `requestDelay` | integer | `1000` | Delay between requests in milliseconds |
| `proxyConfiguration` | object | Direct requests | Optional Apify proxy settings for web requests |

### Output Format

Each domain produces one result object:

```json
{
  "url": "https://example.com",
  "emails": ["info@example.com", "sales@example.com"],
  "phones": ["+1-555-123-4567"],
  "socialProfiles": {
    "linkedin": "https://linkedin.com/company/example",
    "twitter": "https://twitter.com/example",
    "facebook": "https://facebook.com/example",
    "instagram": null,
    "youtube": null,
    "github": "https://github.com/example"
  },
  "addresses": ["123 Main St, San Francisco, CA 94102"],
  "contactPageUrl": "https://example.com/contact",
  "pagesCrawled": 1,
  "contactPointCount": 8,
  "leadQualityScore": 90,
  "scrapedAt": "2026-03-11T12:00:00.000Z"
}
```

### Usage Examples / Use Cases

- **Lead generation** — Build prospect lists by scraping contact info from company websites in your target market
- **Sales prospecting** — Enrich a list of company domains with emails, phone numbers, and LinkedIn pages for outreach
- **Competitor research** — Discover competitors' social media presence and contact channels across platforms
- **Business directory building** — Aggregate contact details from hundreds of local business websites
- **Due diligence** — Verify a company's public contact information and online presence before partnerships
- **Recruitment** — Find team pages and contact emails for companies you want to recruit from or sell to

### Ready-to-run public tasks

- **Extract Crawlee public contact signals** — one page with email, phone, social, and address fields.
- **Find Apify public social links** — one page focused on public company contact channels.
- **Inventory contact channels** — one page with address extraction intentionally disabled.

Every task caps the run at one site and one page, disables link following, and uses concurrency one.

### Pricing

This actor uses Pay-Per-Event pricing with the `site-scraped` event at **$12.00 per 1,000 websites scraped** ($0.012 per site) in the live Store pricing entry.

Apify platform usage is passed through according to the live Store pricing entry because a single website can require multiple page fetches. The safe default is one site, one page, direct requests, and `followLinks=false`; increase those settings only when the additional crawl cost is intentional.

### Proxy Requirements

The actor uses direct requests by default. A target can still reject datacenter traffic, require authentication, or depend on JavaScript rendering. Configure an appropriate proxy when you are authorized to access a target and direct requests fail. If proxy creation is unavailable, the actor records a key-value-store diagnostic and attempts the bounded request directly.

### FAQ

#### How many websites can I scrape in one run?

The actor processes at most 100 websites per run. Use `maxSites` to set a lower cap; excess input URLs are ignored. Each accepted site is also bounded by `maxPages`.

#### What if a website has no contact information?

After a page is crawled successfully, the actor can return a result with empty contact arrays and a score of zero. Failed sites are not emitted as paid dataset rows; their request errors are stored as diagnostics in the key-value store.

#### Does it extract emails from JavaScript-rendered pages?

The actor uses Cheerio (server-side HTML parsing), which does not execute JavaScript. Emails embedded directly in HTML and `mailto:` links can be extracted. Contact details rendered only by client-side scripts may be missed.

#### How does priority page crawling work?

Before following general internal links, the actor automatically queues requests for common contact page paths (`/contact`, `/about`, `/team`, `/impressum`, `/support`) on each domain. These pages are crawled first because they are most likely to contain contact information, reducing the number of pages needed to find results.

#### Can I scrape only emails without phone numbers?

Yes. Set `extractPhones`, `extractSocials`, and `extractAddresses` to `false` and only `extractEmails` to `true`. The actor will still crawl the same pages but only extract and return email addresses.

### Related Actors

- [Email Validator](https://apify.com/junipr/email-validator) — Validate extracted emails with MX, SMTP, and disposable domain checks
- [Disposable Email Checker](https://apify.com/junipr/disposable-email-checker) — Check if emails are from disposable/temporary providers
- [Domain WHOIS Lookup](https://apify.com/junipr/domain-whois-lookup) — Get WHOIS and DNS data for any domain
- [Yellow Pages Scraper](https://apify.com/junipr/yellow-pages-scraper) — Scrape business listings with contact details from Yellow Pages
- [Bluesky Scraper](https://apify.com/junipr/bluesky-scraper) — Scrape social media posts and profiles from Bluesky

# Actor input Schema

## `urls` (type: `array`):

List of website URLs to scrape for contact information. Each URL will be crawled for emails, phone numbers, social profiles, and addresses.

## `maxSites` (type: `integer`):

Maximum number of input websites to process in this run.

## `maxPages` (type: `integer`):

Maximum number of pages to crawl per domain. Higher values find more contact info but take longer.

## `followLinks` (type: `boolean`):

Follow internal links to discover more pages with contact information within the maxPages cap.

## `priorityPages` (type: `array`):

URL paths to prioritize crawling. These pages typically contain contact information.

## `extractEmails` (type: `boolean`):

Extract email addresses from page content.

## `extractPhones` (type: `boolean`):

Extract phone numbers from page content.

## `extractSocials` (type: `boolean`):

Extract social media profile links (LinkedIn, Twitter/X, Facebook, Instagram, YouTube, GitHub).

## `extractAddresses` (type: `boolean`):

Extract physical addresses from page content.

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

Maximum concurrent requests. Lower values are more polite to target servers.

## `requestDelay` (type: `integer`):

Delay between requests in milliseconds. Higher values are more polite to target servers.

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

Optional proxy settings. Direct requests are used by default for a reliable first run.

## Actor input object example

```json
{
  "urls": [
    "https://crawlee.dev"
  ],
  "maxSites": 1,
  "maxPages": 1,
  "followLinks": false,
  "priorityPages": [
    "/contact",
    "/about",
    "/team",
    "/impressum",
    "/support"
  ],
  "extractEmails": true,
  "extractPhones": true,
  "extractSocials": true,
  "extractAddresses": true,
  "maxConcurrency": 1,
  "requestDelay": 1000,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

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

Extracted contact details per website: emails, phones, social profiles, addresses, and contact page URL.

# 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 = {
    "urls": [
        "https://crawlee.dev"
    ],
    "maxPages": 1,
    "priorityPages": [
        "/contact",
        "/about",
        "/team",
        "/impressum",
        "/support"
    ],
    "maxConcurrency": 1,
    "requestDelay": 1000,
    "proxyConfiguration": {
        "useApifyProxy": false
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("junipr/contact-info-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 = {
    "urls": ["https://crawlee.dev"],
    "maxPages": 1,
    "priorityPages": [
        "/contact",
        "/about",
        "/team",
        "/impressum",
        "/support",
    ],
    "maxConcurrency": 1,
    "requestDelay": 1000,
    "proxyConfiguration": { "useApifyProxy": False },
}

# Run the Actor and wait for it to finish
run = client.actor("junipr/contact-info-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 '{
  "urls": [
    "https://crawlee.dev"
  ],
  "maxPages": 1,
  "priorityPages": [
    "/contact",
    "/about",
    "/team",
    "/impressum",
    "/support"
  ],
  "maxConcurrency": 1,
  "requestDelay": 1000,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}' |
apify call junipr/contact-info-scraper --silent --output-dataset

```

## MCP server setup

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