# Business Website Contact Enricher (`huggable_chipmunk/business-contact-enricher`) Actor

Extract published business emails, phones, social links and source evidence from websites. Multilingual contact discovery, role labels and optional MX checks.

- **URL**: https://apify.com/huggable_chipmunk/business-contact-enricher.md
- **Developed by:** [Marco Schwartz](https://apify.com/huggable_chipmunk) (community)
- **Categories:** Lead generation, Business
- **Security:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $8.00 / 1,000 website results

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

## Business Website Contact Enricher

Turn public business websites into company contact records with published emails, phone numbers, social profile links, and the source page for each email and phone. No login, proxy subscription, AI service, or additional API key is required.

Useful for enriching a company list, researching potential suppliers, or preparing CRM imports from contacts a business publishes on its own website.

### Quick start

1. Enter business website URLs in the input form.
2. Choose a page limit: the homepage plus up to four relevant contact, about, or legal pages.
3. Run the Actor and open Website contacts in the Output tab.
4. Export JSON, CSV, or Excel. Nested evidence arrays are most convenient in JSON.

```json
{
  "websiteUrls": ["https://www.scrapingbee.com/"],
  "maxPagesPerWebsite": 5,
  "checkMx": false
}
```

URLs are normalized to their homepages and deduplicated by domain, including www aliases. Up to 100 website URLs can be supplied per run. Relevant contact links are discovered in several languages, including English, French, German, Spanish, Italian and Portuguese. By default, email results are limited to the website's domain and common public mail providers such as Gmail. Enable Include external-domain emails to also return other published email domains.

### Output and evidence

One successful or partial website check produces one record:

| Field | Meaning |
| --- | --- |
| websiteUrl, domain | Requested website and domain |
| companyName | Published site name or page title; not a verified legal entity |
| emails, phones | Deduplicated contacts published in visible HTML or mailto/tel links |
| socialUrls | Links to public social profiles; sharing links are excluded |
| emailDetails | Email, heuristic role label, domainRelation, sourceUrls and optional MX status |
| phoneDetails | Phone number and sourceUrls |
| contactPageUrl | First successfully scanned contact page, if found |
| sourceUrls, pagesScanned | Evidence pages and successful page count |
| status | ok or partial; partial means one or more attempted pages failed or were blocked |
| errors | Per-page errors or robots exclusions |
| checkedAt | UTC observation time |

Role labels include sales, support, careers, press, billing, general and other. They describe the email prefix, not the recipient's confirmed job. domainRelation is same_website, public_mail_provider or external; it is a domain comparison, not proof of ownership. Phone values retain published formatting rather than guessing a country code. No contacts found is a valid result for an accessible website.

Optional MX checking reports mx_present, no_mx, unknown or not_checked. It checks email-domain mail-exchange records only. It does not verify mailbox existence, deliverability, ownership, or permission to contact someone. A no_mx result does not prove an email is undeliverable; SMTP can also fall back to address records.

RUN_SUMMARY in the run's key-value store lists coverage, failed websites, partial results and spending-limit status. Completely inaccessible sites are reported there and do not produce paid contact records. If every website fails, the run fails with diagnostic information.

### Pricing

**$8 per 1,000 emitted website records** ($0.008 each). The same Actor event price applies across Apify plans. A record can contain several emails, phones and evidence pages. Partial accessible results and accessible websites with no contacts are billable; completely failed websites are not.

Use Maximum total charge to bound the number of paid results. The Actor checks the limit before beginning each website and stops emitting when it is reached. Ordinary Apify platform usage charges may apply according to your plan. The Store pricing panel is authoritative.

### Coverage and limitations

- Reads public HTML and published mailto/tel links. It does not run a browser or execute JavaScript, solve challenges, log in, or bypass access restrictions.
- robots.txt is checked before scanning each origin. If robots rules cannot be checked, or access is explicitly denied, that origin is skipped.
- Page limits bound scan depth; this is not a whole-site crawler. Homepage plus discovered relevant pages are attempted; PDFs and binary documents are excluded.
- Obfuscated emails, JavaScript-only contacts and image-based phone numbers may not be detected. International phone text extraction is conservative; explicit tel links are preferred.
- Source URLs show where a contact was found. Published data can be stale or belong to a third party mentioned on the page.
- Public network targets only, with redirect and DNS checks. Local networks, URL credentials and nonstandard ports are rejected.
- Response size, request timeout and retry limits prevent oversized or indefinitely hanging pages.

### Privacy and support

Results remain in the running user's Apify storage. No data is sent to an external AI or analytics provider. The Actor does not send emails or submit forms. Use the Actor's Issues tab for support and include a public website URL and run ID; do not include credentials.

### Local development

Use Node.js 22 or newer: npm ci, npm test, then npm start with Apify local INPUT.json. Dependencies are pinned in package-lock.json. Actor input, output and dataset schemas are in .actor. Release scripts read APIFY_TOKEN from the environment; no token is embedded in the source.

# Actor input Schema

## `websiteUrls` (type: `array`):

Public business websites. One result per unique domain. Up to 100 websites per run.

## `maxPagesPerWebsite` (type: `integer`):

Homepage plus relevant contact/about/legal pages. Robots rules and page limits are respected.

## `checkMx` (type: `boolean`):

Optional domain-level DNS check. This does not verify an individual mailbox.

## `includeExternalEmails` (type: `boolean`):

Also include unrelated published email domains. Off keeps the website domain and common public mail providers such as Gmail.

## Actor input object example

```json
{
  "websiteUrls": [
    "https://www.scrapingbee.com/"
  ],
  "maxPagesPerWebsite": 5,
  "checkMx": false,
  "includeExternalEmails": false
}
```

# Actor output Schema

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

Normalized public records. The dataset schema describes each field.

## `summary` (type: `string`):

Scan coverage, output counts, errors and spending-limit status.

# 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 = {};

// Run the Actor and wait for it to finish
const run = await client.actor("huggable_chipmunk/business-contact-enricher").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 = {}

# Run the Actor and wait for it to finish
run = client.actor("huggable_chipmunk/business-contact-enricher").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 '{}' |
apify call huggable_chipmunk/business-contact-enricher --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,huggable_chipmunk/business-contact-enricher"
        }
    }
}
```

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/it6keIalUMdZdYQbv/builds/inPIZ8LwAiO4h0zCQ/openapi.json
