# Company Contact Details Scraper: Emails, Phones & Socials (`latamdatatools/company-website-enrichment`) Actor

Turn a list of company domains into clean company profiles: name, description, language, country, logo, official LinkedIn/X/Facebook/Instagram/YouTube pages, phones, generic emails (info@, sales@), address and tech stack. Public company data only, robots.txt respected.

- **URL**: https://apify.com/latamdatatools/company-website-enrichment.md
- **Developed by:** [Julian Genuario](https://apify.com/latamdatatools) (community)
- **Categories:** Lead generation, Developer tools, Business
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

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

## Company Contact Details Scraper: Emails, Phones & Socials

Give it a list of company domains and get back one clean, CRM-ready row per company, built from the company's own public website:

- **Company name** (and legal name when the site publishes it), **description**, **logo** and **favicon**
- **Language** of the site and **probable country** (from the published address, phone prefixes, ccTLD or language)
- **Official social profiles**: LinkedIn company page, X (Twitter), Facebook, Instagram, YouTube and TikTok
- **Company phone numbers**, normalised to E.164 (`+4971563030`) and international format
- **Generic company emails only**: `info@`, `contact@`, `sales@`, `ventas@`, `support@`, `hello@`, `press@`, `privacy@`... on the company's own domain
- **Postal address** when the site publishes it (structured data or `<address>` tags)
- **Technologies** detected from the home page: CMS (WordPress, Drupal, Webflow, Wix...), e-commerce platform (Shopify, WooCommerce, Magento, VTEX...), analytics and tag managers, ad pixels, chat widgets, consent tools, frameworks and CDN, plus an `hasEcommerce` flag

It visits the home page and at most a few relevant pages (contact, imprint / legal notice, about, privacy), never the whole site. Plain HTTP requests, no browser: fast and cheap.

### What does Company Enrichment by Domain do?

Company Enrichment by Domain turns a list of company websites into clean company profiles built from each company's own public site: name, description, logo, language, probable country, official LinkedIn / X / Facebook / Instagram / YouTube / TikTok pages, company phone numbers, generic contact emails (info@, sales@, support@), postal address and tech stack. It does not collect personal emails.

### How to use Company Enrichment by Domain

1. Click **Try for free** on this page (a free Apify account is enough to start).
2. Fill in the input (see the examples below) or keep the prefilled example.
3. Click **Start** and wait for the run to finish.
4. Download the results from the **Output** tab as JSON, CSV, Excel or HTML, or read them with the Apify API.
5. Optional: create a **Schedule** to run it daily or weekly, and connect a webhook or an integration (Make, Zapier, n8n, Slack).

### Use cases

- **Enrich a lead list or CRM** (HubSpot, Salesforce, Pipedrive): add website description, country, LinkedIn page and a generic contact channel to every account
- **Clean and qualify company lists** from trade-show exhibitor lists, directories or exports: which companies have e-commerce, which run WordPress or Shopify, which sell in which language
- **Account research for SDRs and agencies**: one row per account instead of opening 5 tabs per company
- **Data hygiene**: find the official social profiles and the general phone number of each company
- **Market mapping**: technology adoption (CMS, analytics, chat, payments) across a list of competitors or prospects

### Input

```json
{
  "domains": ["stripe.com", "https://www.hubspot.com/", "info@bosch.de"],
  "maxPagesPerDomain": 5,
  "detectTechnologies": true,
  "maxConcurrency": 5
}
```

Domains, full URLs or work emails are accepted (the email's domain is used). Duplicates and invalid lines are removed and listed in the run summary.

### Output (one row, shortened)

```json
{
  "input": "zapier.com",
  "domain": "zapier.com",
  "finalDomain": "zapier.com",
  "url": "https://zapier.com/",
  "status": "ok",
  "companyName": "Zapier",
  "legalName": null,
  "description": "Build and scale AI workflows and agents across 9,000+ apps with Zapier...",
  "language": "en",
  "languageTag": "en",
  "countryCode": "US",
  "countrySource": "address",
  "logoUrl": "https://res.cloudinary.com/zapier-media/image/upload/...",
  "faviconUrl": "https://zapier.com/favicon.ico",
  "socialProfiles": {
    "linkedin": "https://www.linkedin.com/company/zapier",
    "x": "https://x.com/zapier",
    "facebook": "https://www.facebook.com/ZapierApp",
    "instagram": "https://www.instagram.com/zapier",
    "youtube": "https://www.youtube.com/@ZapierApp",
    "tiktok": null
  },
  "emails": ["privacy@zapier.com"],
  "phones": [],
  "address": { "streetAddress": "548 Market St. #62411", "postalCode": "94104", "locality": "San Francisco", "region": "CA", "country": "US", "full": "548 Market St. #62411, 94104 San Francisco, CA, US", "source": "structured-data" },
  "technologies": [ { "name": "Next.js", "category": "framework" }, { "name": "Google Tag Manager", "category": "analytics" }, { "name": "Vercel", "category": "hosting" } ],
  "hasEcommerce": false,
  "pagesVisited": ["https://zapier.com/", "https://zapier.com/l/contact-sales", "https://zapier.com/legal", "https://zapier.com/privacy"],
  "pagesBlockedByRobots": 0,
  "personalEmailsDiscarded": 0,
  "error": null,
  "scrapedAt": "2026-10-26T22:10:00.000Z"
}
```

Phones look like `{ "number": "+49 7156 3030", "e164": "+4971563030", "country": "DE", "source": "structured-data" }` (`source` is `structured-data`, `tel-link` or `page-text`).

Every row has the same keys; missing data is `null` or an empty list. Websites that cannot be read (down, DNS error, blocked by a firewall, HTTP 4xx/5xx) come back with `status: "failed"` and the reason in `error`. Websites whose robots.txt disallows the home page come back with `status: "blocked_by_robots"`. **Failed and blocked rows are not charged.**

The dataset has three views: *Company profiles*, *Contacts (CRM-ready)* and *Technologies*. A `RUN_SUMMARY` record in the key-value store has the totals (enriched, failed, blocked by robots.txt, with email / phone / LinkedIn / address).

### Privacy and compliance

This Actor is built for **company (B2B) data**, not for collecting data about people:

- **Only public, corporate information** published by the company on its own website.
- **No personal emails.** Only role / generic mailboxes are returned (info@, sales@, support@, press@, privacy@, careers@, etc.). Emails that look like a person (`john.smith@`, `jsmith@`, `maria@`) are discarded and only counted (`personalEmailsDiscarded`), never stored. Emails on other domains (gmail.com, agencies, widgets) are ignored.
- **No employee names.** People listed in structured data, team pages or personal LinkedIn profiles (`linkedin.com/in/...`) are ignored; team and people pages are not visited.
- **Respects robots.txt** of every website, on every request and every redirect: paths disallowed for our user agent (or for `*`) are never requested. A `Crawl-delay` up to 10 seconds is honoured.
- **Identifiable and polite**: user agent `CompanyWebsiteEnrichmentBot/1.0` with a link to this page, pages of the same site fetched one at a time with a delay (1 s by default), at most 8 pages per domain, timeouts on every request. No proxies, no CAPTCHA solving, no login.

You are responsible for using the results lawfully (for example GDPR / ePrivacy rules on B2B outreach in your country).

### Pricing

Pay per event: **USD 4 per 1,000 enriched domains** (USD 0.004 per company). Failed websites, domains blocked by robots.txt, invalid inputs and duplicates are free. Apify platform usage is included. The run respects your *max charge per run*: it never processes more domains than you will pay for.

### Limits and tips

- Some websites block automated requests with a firewall (HTTP 403) or only render their content with JavaScript. These come back as `failed` or with fewer fields; they are not charged when they fail.
- Large corporations often hide emails behind contact forms: you will get more emails and phones from small and mid-size companies, which usually publish `info@` and a phone number in the footer or imprint.
- The country is a best guess and comes with its source (`address`, `phone`, `domain`, `language`).
- Technology detection looks at the home page HTML and headers only (no browser), so tools loaded later by JavaScript may be missed.
- Around 5 pages per domain and 5 domains in parallel: roughly 300-600 domains per 10 minutes, depending on the websites.

### Why use Company Contact Details Scraper

- **One clean row per company, not per page.** Name, description, language, likely country, logo, official social pages (LinkedIn company page, X, Facebook, Instagram, YouTube, TikTok), phones in E.164, generic contact emails (info@, sales@, support@), address and tech stack.
- **Predictable price:** a flat price per company, whatever number of pages it reads (up to 8).
- **Company data only.** It does not collect personal emails of employees, which keeps the output simpler to use under GDPR.
- **Failed sites, robots.txt blocks, invalid inputs and duplicates are not charged.**

### Cost examples

Prices at the current pay-per-event rates (see Pricing). You can set a maximum charge per run in the run options.

| Job | Approximate cost |
|---|---|
| 100 company domains | about $0.40 |
| 1,000 company domains | about $4.00 |
| 10,000 company domains | about $40 |

### Use it from your code, an integration or an AI agent

**Python** (`pip install apify-client`):

```python
from apify_client import ApifyClient

client = ApifyClient("<YOUR_APIFY_TOKEN>")
run = client.actor("latamdatatools/company-website-enrichment").call(run_input={
    "domains": [
        "stripe.com",
        "hubspot.com",
        "siemens.com"
    ]
})
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)
```

**JavaScript / Node.js** (`npm install apify-client`):

```javascript
import { ApifyClient } from 'apify-client';

const client = new ApifyClient({ token: '<YOUR_APIFY_TOKEN>' });
const run = await client.actor('latamdatatools/company-website-enrichment').call({
  "domains": [
    "stripe.com",
    "hubspot.com",
    "siemens.com"
  ]
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);
```

**No code:**

- **Schedules:** run it daily or weekly from Apify Console (Schedules), with the same input saved as a Task.
- **Integrations:** send results to Google Sheets, Slack, email, Make, Zapier, n8n or Airbyte from the Integrations tab, or call your own webhook when a run finishes.
- **AI agents:** add it as a tool in Claude, Cursor, VS Code and other MCP clients through the Apify MCP server (`https://mcp.apify.com`), so the agent can run Company Contact Details Scraper and read the results.

### FAQ

**Can I get the CEO's or employees' emails?** No, by design. Use this Actor for company-level data only.

**Why is a LinkedIn / Instagram profile missing?** Only links published on the company's own website are used. If the site does not link to its profiles, the field is `null`.

**Can I pass a list from another Actor or a spreadsheet?** Yes: paste domains or URLs, one per line, or call the Actor via API / integrations (Make, Zapier, n8n) with a `domains` array.

**How is it different from a crawler that collects every email on a site?** Those return one row per page or per email found, often including personal addresses. This Actor reads a handful of pages (home, contact, imprint, about, privacy) and returns one merged company profile with only company-level contacts.

**Which websites work best?** Small and mid-size company sites. Very large corporations often hide emails behind forms, and sites that block bots (HTTP 403) or render everything with JavaScript return fewer fields or fail (failures are free).

Questions or a missing field? Open an issue in the Issues tab.

# Actor input Schema

## `domains` (type: `array`):

One per line: a domain (stripe.com), a website URL (https://www.siemens.com/) or even a work email (info@acme.com - its domain is used). Duplicates are removed.

## `maxPagesPerDomain` (type: `integer`):

The home page plus the most useful pages it links to (contact, imprint/legal notice, about, privacy). 5 is usually enough; more pages = slower runs.

## `detectTechnologies` (type: `boolean`):

Detect CMS, e-commerce platform, analytics, tag managers, chat widgets, CDN and frameworks from the home page HTML and headers.

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

How many different websites are processed at the same time. Pages of the same website are always fetched one by one.

## `delayBetweenPagesMs` (type: `integer`):

Politeness delay between two requests to the same website. A longer Crawl-delay in the site's robots.txt is respected (up to 10 s).

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

Maximum time to wait for one page.

## Actor input object example

```json
{
  "domains": [
    "stripe.com",
    "hubspot.com",
    "siemens.com"
  ],
  "maxPagesPerDomain": 5,
  "detectTechnologies": true,
  "maxConcurrency": 5,
  "delayBetweenPagesMs": 1000,
  "requestTimeoutSecs": 20
}
```

# Actor output Schema

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

No description

## `runSummary` (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 = {
    "domains": [
        "stripe.com",
        "hubspot.com",
        "siemens.com"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("latamdatatools/company-website-enrichment").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 = { "domains": [
        "stripe.com",
        "hubspot.com",
        "siemens.com",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("latamdatatools/company-website-enrichment").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 '{
  "domains": [
    "stripe.com",
    "hubspot.com",
    "siemens.com"
  ]
}' |
apify call latamdatatools/company-website-enrichment --silent --output-dataset

```

## MCP server setup

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

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/hVuNbzcTLpsjFReyF/builds/D60zFHsQjYTXQtciS/openapi.json
