# Business Website Enricher — Company Contacts (`afkdigital/business-website-enricher`) Actor

Extract company-owned, publicly published business emails, general phones, addresses and social links from your URL list. Confidence and source pages included. No employee profiles, Google Maps, reviews, or login scraping.

- **URL**: https://apify.com/afkdigital/business-website-enricher.md
- **Developed by:** [AFK Digital](https://apify.com/afkdigital) (community)
- **Categories:** Business, Lead generation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$6.00 / 1,000 useful company website enricheds

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

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 Enricher — Source-Backed Company Contacts

**Turn your own list of business websites into structured, auditable company metadata.** This Actor only visits a company's publicly accessible own website. It is **not** a Google Maps, employee, personal-email, or reputation scraper.

### Input

- `websiteUrls` (required): 1–100 domains or HTTP(S) URLs. Domain-only inputs use HTTPS.
- `maxPagesPerSite`: 1–10 successful HTML pages per business, default 3.
- `crawlContactPages`: include permitted Contact links and conventional Contact paths, default true.

### Dataset output

One record per unique submitted website, including `status`, `companyName`, `businessEmail`, `businessPhone`, `businessAddress`, `socialUrls`, `sourcePages`, `pagesCrawled`, `fieldEvidence`, `robotsStatus`, and `processedAt`. Every populated field has a **source page URL**, method, and high/medium/low confidence. Social links also include their source page and confidence.

Business email means **role mailbox on the website's domain** (examples: info@, sales@, contact@, support@). Personal addresses such as jane@company.example and named employee profiles are excluded. Corporate social links are discovered from the company's own pages, not by visiting the linked social networks.

### Charging: pay per useful website

Target price: **$0.006 per successful website with at least one company contact detail or corporate social link** ($6 per 1,000 useful sites). No per-page or startup event. Invalid, blocked, duplicate, or empty results are not charged. Apify's run spending cap applies. **See the Store Pricing tab for the actual effective event price**; the account's publishing configuration is authoritative.

### Boundaries

- Robots.txt respected before fetching business HTML. Fail closed if robot rules are unavailable or deny access.
- Same-domain only; redirects cannot be used to escape the allowed site. No search engines, Maps, directory bypass, third-party API, login pages, browser automation, or proxies.
- 1 request per second per site; per-request timeouts; HTML size cap 2 MB; per-site page cap, 100 website cap, no unbounded crawl.
- HTML links and organization JSON-LD are parsed; JavaScript-render-only contact data may not be visible. Uncertain organization names are omitted rather than guessed.
- Some websites prohibit automated reuse in terms independent of robots.txt. Users must ensure their URL inputs and data use are permitted. Do not use results for unlawful unsolicited outreach.

### Example input

```
{
  "websiteUrls": ["https://www.hetzner.com", "https://www.digitalocean.com"],
  "maxPagesPerSite": 3,
  "crawlContactPages": true
}
```

### Example output (illustrative, not a real company)

```
{
  "inputUrl": "https://example.org",
  "status": "ok",
  "companyName": "Example LLC",
  "businessEmail": "info@example.org",
  "businessPhone": null,
  "businessAddress": null,
  "socialUrls": [{"platform":"linkedin","url":"https://www.linkedin.com/company/example","sourceUrl":"https://example.org","confidence":"medium"}],
  "fieldEvidence": {
    "companyName": {"value":"Example LLC","sourceUrl":"https://example.org","confidence":"high","method":"json-ld"},
    "businessEmail": {"value":"info@example.org","sourceUrl":"https://example.org/contact","confidence":"high","method":"mailto-link"},
    "businessPhone": null,
    "businessAddress": null
  },
  "sourcePages": ["https://example.org", "https://example.org/contact"],
  "pagesCrawled": 2
}
```

### Tests, known limits and support

Five labeled site-structure fixtures include JSON-LD, footer contacts, personal-email false positives, company-only contact points, and JavaScript-only content. See `reports/fixture_validation.json`. They are synthetic tests, not proof of general internet extraction accuracy. Real-world evaluation is kept separately under `reports/live_business_sites.json`. Requests may be blocked, pages may exceed 2MB, or sites may load contact information only through JavaScript. This Actor leaves unverified data blank.

Source code and maintenance scope: Netcup `/opt/APIFY/API09` only. No dependency on API06, no Google Places integration. If Places is added in a later version, its license, retention, and display requirements must be separately reviewed first.

# Actor input Schema

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

User-supplied company domains or public URLs, up to 100.

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

Maximum one to ten pages including homepage.

## `crawlContactPages` (type: `boolean`):

Whether to scan public, allowed contact pages.

## Actor input object example

```json
{
  "websiteUrls": [
    "https://www.hetzner.com"
  ],
  "maxPagesPerSite": 3,
  "crawlContactPages": true
}
```

# Actor output Schema

## `results` (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 = {
    "websiteUrls": [
        "https://www.hetzner.com"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("afkdigital/business-website-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 = { "websiteUrls": ["https://www.hetzner.com"] }

# Run the Actor and wait for it to finish
run = client.actor("afkdigital/business-website-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 '{
  "websiteUrls": [
    "https://www.hetzner.com"
  ]
}' |
apify call afkdigital/business-website-enricher --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,afkdigital/business-website-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/WchNeezF5CjeAZ91h/builds/8UQR0PGyLn5YMb2aT/openapi.json
