# Website Contact Enricher (`gpos_lab/my-actor`) Actor

Turn public company websites into clean, evidence-backed contact records. Get public emails, phone numbers, official social profiles, contact pages, scanned pages, and source evidence—one structured row per site

- **URL**: https://apify.com/gpos\_lab/my-actor.md
- **Developed by:** [Ilya Komarov](https://apify.com/gpos_lab) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $5.00 / 1,000 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

Turn public company websites into **one clean, evidence-backed contact record per site**.

Website Contact Enricher scans a homepage plus a small number of high-value public pages such as Contact, About, Support, Team, Careers, or Imprint. Instead of returning a noisy pile of separate rows, it groups the useful contact data into one predictable company-level result.

### What you get

For each website, the Actor can return:

- public email addresses
- public phone numbers
- official social profile links
- organization name when exposed by the website
- the best contact page discovered
- the exact pages scanned
- source evidence for extracted contact values
- per-site errors without crashing the whole batch

This format is useful for **CRM enrichment, B2B research, spreadsheet cleanup, company datasets, and AI-agent workflows**.

### How to use it

Add one or more public company or homepage URLs. You can process up to 50 websites in a run.

Example input:

```json
{
  "urls": [
    "https://apify.com",
    "https://buffer.com/press"
  ],
  "maxPagesPerSite": 4,
  "requestTimeoutSecs": 12,
  "includeEvidence": true
}
```

#### Input options

- **Website URLs** — one public website per line.
- **Maximum pages per site** — controls how many public pages are checked. The default is 4 and the maximum is 8.
- **Request timeout** — maximum time to wait for each page request.
- **Include source evidence** — when enabled, the output keeps the source URL and discovery method for each contact value.

### Output

The default dataset contains one row per input website.

Example:

```json
{
  "inputUrl": "https://company.example/",
  "resolvedUrl": "https://company.example/",
  "domain": "company.example",
  "organizationName": "Example Company",
  "emails": ["hello@company.example"],
  "phones": ["+14165551234"],
  "socials": {
    "linkedin": ["https://www.linkedin.com/company/example-company"]
  },
  "contactPage": "https://company.example/contact",
  "pagesScanned": [
    "https://company.example/",
    "https://company.example/contact"
  ],
  "evidenceCount": 3,
  "errors": [],
  "scrapedAt": "2026-09-30T00:00:00.000Z"
}
```

The dataset can be exported from Apify in formats such as JSON, CSV, Excel, XML, and others supported by the platform.

### Evidence-first contact extraction

Website contact data can be surprisingly noisy. Pages often contain dates, company IDs, invoice numbers, example phone numbers, documentation snippets, social-media handles, and hidden email-protection markup.

This Actor is deliberately conservative. It prioritizes real contact pages, normalizes duplicate phone formats, handles common Cloudflare-protected email addresses, avoids treating arbitrary numeric strings as phones, and keeps evidence so you can see where a value came from.

### Pricing

The intended pricing model is **pay per successfully processed website**.

The current proposed custom event is:

- **Website enriched** — $0.005 per successfully processed website

Final Store pricing is controlled by the Actor's Monetization settings in Apify Console.

### Limits

This Actor focuses on **publicly accessible website data**.

It does not:

- bypass logins, CAPTCHAs, access controls, or anti-bot protections
- verify whether a mailbox actually exists or can receive email
- guess private contact information
- guarantee complete results from JavaScript-only websites
- use a full browser in the current lightweight version

A site can return an empty contact list and still be processed successfully if no public contact information is exposed in the pages checked.

### Reliability

The Actor has two automated test layers:

- deterministic regression tests for extraction, schemas, evidence, redirects, failures, and pricing guardrails
- live validation against varied public websites to catch real-world changes that controlled fixtures may miss

Live websites change over time. When a known site changes, the validation system flags it for review instead of silently weakening extraction rules.

### Common questions

#### Why did a site return no phone number?

The Actor intentionally rejects number-like text unless it has strong phone evidence. This reduces false positives from company IDs, dates, prices, counters, and serial numbers.

#### Why did it scan several pages?

Many websites keep useful contact information away from the homepage. The Actor follows a small number of high-value same-site links while respecting the page limit you set.

#### Can I use the output in an AI workflow?

Yes. The output is structured as one predictable record per website, which works well for downstream automation, data pipelines, and AI-agent tools.

#### Does it collect private data?

No. It works with information exposed on public web pages and does not attempt to bypass access controls.

# Actor input Schema

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

One public website or company homepage per line.

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

Homepage plus a few high-value public pages such as Contact, About, Support, Team, Careers, or Imprint.

## `requestTimeoutSecs` (type: `integer`):

Maximum seconds to wait for each page request.

## `includeEvidence` (type: `boolean`):

Keep the exact source page and discovery method for each contact value.

## Actor input object example

```json
{
  "urls": [
    "https://apify.com"
  ],
  "maxPagesPerSite": 4,
  "requestTimeoutSecs": 12,
  "includeEvidence": 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 = {
    "urls": [
        "https://apify.com"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("gpos_lab/my-actor").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://apify.com"] }

# Run the Actor and wait for it to finish
run = client.actor("gpos_lab/my-actor").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://apify.com"
  ]
}' |
apify call gpos_lab/my-actor --silent --output-dataset

```

## MCP server setup

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

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/cl9XESKCM7INygngf/builds/kDrfcUMK6buWqSfMy/openapi.json
