# Website Contact Scraper - Emails, Phones, Socials, Address (`victorrodi/website-contact-scraper-api`) Actor

Company contacts from any website list: role emails (info@, sales@), phones, social profiles, address, logo and technologies. One clean row per site, GDPR-friendly, no browser. Pay only when contacts are found.

- **URL**: https://apify.com/victorrodi/website-contact-scraper-api.md
- **Developed by:** [TrendPulse Data](https://apify.com/victorrodi) (community)
- **Categories:** Lead generation, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.50 / 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

### 📇 Website Contact Scraper — company emails, phones, socials & address from any website

**Turn a list of websites into a clean list of company contacts.** For each website this contact scraper reads the home page and the contact / about / legal pages, then returns the company's **contact emails, phone numbers, social media profiles, postal address, logo and the technologies the site uses** — as JSON, CSV or Excel. No browser, so it is fast and costs a fraction of a cent per website.

✅ **Company emails** (info@, contact@, sales@, reservas@…) — only the addresses a business publishes for customers
✅ **Phone numbers** from click-to-call links, structured data and the page text, normalized (`+351213218100`)
✅ **Social profiles**: Facebook, Instagram, LinkedIn company page, X/Twitter, YouTube, TikTok, Pinterest, GitHub
✅ **Postal address**, company name and logo from schema.org data
✅ **Technologies**: WordPress, Shopify, Wix, Squarespace, Webflow, PrestaShop, HubSpot, Google Analytics, Meta Pixel, Stripe…
✅ **Contact page URL** for each website
✅ Finds contact pages in **any language** (contact, contactos, kontakt, impressum, sobre-nós, à-propos…)
✅ **Pay only for websites where contacts are found** — dead or empty websites are free

***

### 🛡️ GDPR-friendly by design

This Actor collects **business contact details only**: role-based mailboxes (info@, sales@, support@…) of the website's own domain, company phone numbers and company social pages. It **does not collect personal email addresses** (firstname.lastname@), personal LinkedIn profiles or emails of other websites quoted on the page. That keeps your lead lists cleaner and much easier to use under GDPR and similar laws.

***

### 🚀 Why this contact scraper is different

| | This Actor | Typical contact scrapers |
|---|---|---|
| Price | **$0.003 per website** (up to 5 pages included) | $0.002 **per page** (≈ $0.01 per website) |
| Charged when nothing is found | **Never** | Usually |
| One clean row per website | **Yes**, deduplicated across pages | One row per page to merge yourself |
| Address, logo and technologies | **Yes** | Rarely |
| Personal emails | **Not collected** (GDPR-friendly) | Collected |
| Fake / example numbers filtered | **Yes** | No |

***

### 💡 Use cases

- **Lead generation**: enrich a list of company websites (from Google Maps, directories, trade fairs, CRM exports) with emails, phones and social profiles.
- **Agencies**: find businesses on WordPress, Wix or Shopify, or without analytics, and pitch them the right service.
- **Sales & CRM enrichment**: fill in missing phone numbers, addresses and LinkedIn company pages.
- **Market research**: map the technologies and social presence of an industry.
- **Partnerships & PR**: get the right contact mailbox (press@, partnerships@) of each company.

***

### 🛠️ How to use it (3 steps)

1. **Paste websites or domains**, one per line (from a spreadsheet, Google Maps results, a directory…).
2. Keep **5 pages per website** (home + contact + about + legal pages) or raise it.
3. **Click Start** and download your contacts as **CSV, Excel or JSON**, or fetch them through the API.

***

### 📥 Input example

```json
{
  "startUrls": ["hotelavenidapalace.pt", "https://www.apify.com", "example-bakery.de"],
  "maxPagesPerSite": 5,
  "concurrency": 10
}
```

### 📤 Output example (real run)

```json
{
  "url": "https://hotelavenidapalace.pt/",
  "domain": "hotelavenidapalace.pt",
  "companyName": "Hotel Avenida Palace",
  "emails": ["reservas@hotelavenidapalace.pt"],
  "phones": ["+351213218100"],
  "socials": {
    "facebook": "https://www.facebook.com/HotelAvenidaPalaceLisboa",
    "instagram": "https://www.instagram.com/hotelavenidapalace"
  },
  "address": { "streetAddress": "Rua 1º Dezembro, 123", "addressLocality": "Lisboa", "postalCode": "1200-359", "addressCountry": "Portugal" },
  "logo": "https://www.hotelavenidapalace.pt/media/hotel-avenida-palace-hotelhotel-avenida-palace-exterior_3.webp",
  "technologies": ["Google Analytics", "Google Tag Manager", "Guestcentric website builder"],
  "contactPage": null,
  "pagesVisited": ["https://www.hotelavenidapalace.pt/", "https://www.hotelavenidapalace.pt/about"]
}
```

Websites without any contact detail, and unreachable websites, are listed in the run's `RUN_SUMMARY` record — and not charged.

***

### ⚙️ Input parameters

| Field | Type | Default | Description |
|---|---|---|---|
| `startUrls` | array | `["https://www.apify.com"]` | Company websites or domains, one per line (example.com, https://www.example.pt). One result per website, up to 5,000 per run. |
| `maxPagesPerSite` | integer | `5` | Home page plus contact, about and legal pages found on it. 5 finds almost everything. |
| `concurrency` | integer | `10` | How many websites are processed at the same time. |
| `proxyConfiguration`, `maxRetries` | object, integer | Apify Proxy, auto | Proxy and retries; the defaults work for most runs. |

### 📋 Output fields

| Field | Type | Description |
|---|---|---|
| `url` | string | Website as given in the input |
| `domain` | string | Domain without www |
| `finalUrl` | string | Home page after redirects |
| `companyName` | string | Company / site name |
| `title` | string | Home page title |
| `description` | string | Meta description |
| `language` | string | Page language |
| `emails` | array | Role emails of the company (info@, contact@, sales@...) |
| `phones` | array | Phone numbers, normalized |
| `socials` | object | Company social profiles by network |
| `address` | object | Postal address from structured data |
| `logo` | string | Logo or share image URL |
| `technologies` | array | CMS, e-commerce, analytics and tools detected |
| `contactPage` | string | Contact page URL |
| `pagesVisited` | array | Pages read on the website |

Export as JSON, CSV, Excel, XML or HTML, or read it through the API.

***

### 💰 Pricing — pay only for websites with contacts

| What you run | Cost (free plan) |
|---|---|
| 100 websites | $0.30 |
| 1,000 websites | $3.00 |
| 5,000 websites | $15.00 |

Higher Apify plans pay less: $0.0025 (Bronze), $0.002 (Silver), $0.0015 (Gold and above). Platform usage and proxies are **included**. Set a **maximum cost per run** and the Actor stops cleanly when it is reached.

***

### 🔌 API & integrations

**Python**

```python
from apify_client import ApifyClient  # pip install "apify-client>=3"

client = ApifyClient("<YOUR_APIFY_TOKEN>")
run = client.actor("victorrodi/website-contact-scraper-api").call(
    run_input={"startUrls": ["hotelavenidapalace.pt", "apify.com"]}
)
for company in client.dataset(run.default_dataset_id).iterate_items():
    print(company["domain"], company["emails"], company["phones"])
```

**JavaScript / Node.js**

```javascript
import { ApifyClient } from 'apify-client';

const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('victorrodi/website-contact-scraper-api').call({ startUrls: ['apify.com'] });
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);
```

**cURL**

```bash
curl -X POST "https://api.apify.com/v2/acts/victorrodi~website-contact-scraper-api/run-sync-get-dataset-items" \
  -H "Authorization: Bearer $APIFY_TOKEN" -H "Content-Type: application/json" \
  -d '{"startUrls": ["apify.com"]}'
```

Works with **Google Sheets, HubSpot, Make, Zapier, n8n, Clay** and **MCP / AI agents** (Claude, ChatGPT, Cursor) through Apify integrations — e.g. *"Find the contact email and phone of these 20 hotels' websites."*

***

#### 🤖 Use it from AI agents (Claude, ChatGPT, Cursor…)

This Actor is available to AI assistants through the **[Apify MCP server](https://mcp.apify.com)**. Add the server to Claude Desktop, Claude Code, Cursor or any MCP client, then simply ask:

> *"Find the contact email and phone of these 20 company websites and put them in a table."*

> *"Use victorrodi/website-contact-scraper-api to get the LinkedIn and Instagram pages of these shops."*

The clean, flat output is designed to be read directly by LLMs.

***

### 🛡️ Reliability

- Requests are paced and retried with a **new IP** and exponential backoff.
- If the site keeps blocking, the Actor **switches to residential IPs automatically**.
- One failing item never stops the run, and you are never charged for it.
- Every run writes a `RUN_SUMMARY` record (results, failures, retries, blocks).
- Measured on 20 real websites in 24 seconds: 13 with contacts, 2 without any, 5 behind anti-bot walls (not charged).

More examples and docs for all our Actors: **[Vicshock/trendpulse-scrapers](https://github.com/Vicshock/trendpulse-scrapers)**.

***

### 📌 Tips

- Chain it after a **Google Maps scraper**: export the `website` column and paste it here.
- Big brands often hide contacts behind forms; small and medium businesses publish them — that is where this Actor shines.
- Some websites block all bots (Cloudflare "Under attack" mode); they are listed as unreachable and not charged. We tested a real-browser fallback: big marketplaces and job sites (Glassdoor, Indeed, Etsy, G2…) block it too from cloud servers, so this Actor stays fast and cheap and focuses on what it does best: **company and small-business websites**.

### ❓ FAQ

**Does it collect personal data?** It is built not to: only role-based company mailboxes of the website's own domain, company phones and company social pages. You remain responsible for how you use the data (GDPR, CAN-SPAM, ePrivacy).

**Why is an email I can see on the site missing?** It is either a personal address (firstname@…), an address of another domain, or it is only shown inside an image or a contact form.

**How many websites per run?** Up to 5,000. Split bigger lists into several runs.

### 💬 Support

Missing a field or found an issue? Open an issue in the **Issues** tab — it is answered fast.

# Actor input Schema

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

Company websites or domains, one per line (example.com, https://www.example.pt). One result per website, up to 5,000 per run.

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

Home page plus contact, about and legal pages found on it. 5 finds almost everything.

## `concurrency` (type: `integer`):

How many websites are processed at the same time.

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

Apify Proxy is used by default; the Actor switches to residential IPs automatically when websites start blocking.

## `maxRetries` (type: `integer`):

Retries per page with a new IP and backoff.

## `debugLog` (type: `boolean`):

Log every request (for troubleshooting).

## Actor input object example

```json
{
  "startUrls": [
    "https://www.apify.com",
    "https://www.hotelavenidapalace.pt"
  ],
  "maxPagesPerSite": 5,
  "concurrency": 10,
  "proxyConfiguration": {
    "useApifyProxy": true
  },
  "maxRetries": 3,
  "debugLog": false
}
```

# Actor output Schema

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

No description

## `summary` (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 = {
    "startUrls": [
        "https://www.apify.com",
        "https://www.hotelavenidapalace.pt"
    ],
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("victorrodi/website-contact-scraper-api").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://www.apify.com",
        "https://www.hotelavenidapalace.pt",
    ],
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("victorrodi/website-contact-scraper-api").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://www.apify.com",
    "https://www.hotelavenidapalace.pt"
  ],
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call victorrodi/website-contact-scraper-api --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,victorrodi/website-contact-scraper-api"
        }
    }
}
```

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/Mr50bhktYqg8Ss7TT/builds/MtpOPDk1lF40Dqrl3/openapi.json
