# Company Lead Enrichment: Emails, Phones, Team & Tech Stack (`datagleaner/company-lead-enrichment`) Actor

B2B lead enrichment from a list of company domains: enrich each company with emails, phones, socials, address, decision makers with titles and LinkedIn, company description and tech stack (CMS, shop, CRM, analytics, email provider). $0.001 per profile plus each module's listed price.

- **URL**: https://apify.com/datagleaner/company-lead-enrichment.md
- **Developed by:** [Data Gleaner](https://apify.com/datagleaner) (community)
- **Categories:** Lead generation, Integrations, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$1.00 / 1,000 company profiles

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 Lead Enrichment: emails, phones, decision makers and tech stack from a domain list

**Company enrichment and lead enrichment in one run.** Give it a list of company domains (or the results of Google Maps Scraper or any other scraper) and get back **one row per company** with:

- **Emails and phones** published on the company's own website, plus the best general address (`bestEmail`)
- **Social profiles**: LinkedIn company page, X, Facebook, Instagram, YouTube, TikTok, GitHub, Pinterest
- **Postal address, country, company name, legal name, description, logo and founding date**
- **Decision makers**: the named people the company lists on its team, about, leadership and Impressum pages, with job title, seniority, LinkedIn link and published email, most senior first
- **Tech stack**: CMS, shop platform, CRM and marketing tools, analytics, hosting and email provider

It is the lookup people describe as *find emails and decision makers from a domain list*, *domain enrichment*, *email and phone enrichment*, *company data enrichment* or *Clay-style enrichment on Apify*: a waterfall of four specialised lookups merged into a single company profile you can export to CSV, Google Sheets or your CRM.

**Pricing is per result and stated in full below.** In our own test runs a company cost **$0.007 to $0.013**, everything included. Domains that return nothing are free, and you can switch off any module you don't need.

### How it works

The Actor runs four Data Gleaner Actors for your whole list at once, each as its own run in your Apify account, and merges their results by domain:

| Module | Actor it runs | What it adds |
|---|---|---|
| Contacts (`includeContacts`) | [Website Email Finder & Contact Details Scraper](https://apify.com/datagleaner/website-contact-details-scraper) | Emails, phones, social profiles, contact form, postal address, read from up to 8 pages per site |
| People (`includePeople`) | [Company Leadership & Team Page Scraper](https://apify.com/datagleaner/team-page-contacts) | Named people with job title, seniority, LinkedIn and published email |
| Company (`includeCompany`) | [Company Enrichment by Domain](https://apify.com/datagleaner/company-enrichment-by-domain) | Name, description, logo, founding date, address, official social profiles |
| Tech stack (`includeTechStack`) | [Tech Stack Lookup by Domain](https://apify.com/datagleaner/tech-stack-by-domain) | CMS, shop platform, CRM, analytics, hosting, email provider, each with evidence |

The four lookups run in parallel, so a run takes about as long as the slowest module: 11 to 34 seconds for 3 companies and 52 to 117 seconds for 10 in our tests. Domains are deduplicated first: `acme.com`, `www.acme.com`, `https://acme.com/about` and `ACME.com/` are one company. Every row carries `sources`, the run ID of each module's run, so any value can be traced back to the page it came from.

If one module fails or returns nothing for a company, the row is still returned with what the other modules found, and `warnings` and `moduleStatus` say which module came back empty and why.

### Pricing

Pay per event, no subscription. Two kinds of charges appear on your bill:

| Event | Charged by | Price | When |
|---|---|---|---|
| `company-profile` | this Actor | **$0.001** | per company row with at least one email, person, company fact (name, description, phone, address or social profile) or technology. Empty and unreachable domains are free. |
| `website-with-email` | contacts module | $0.002 | per website where at least one email was found |
| `person-found` | people module | $0.002 | per person returned (capped by `maxPeoplePerCompany`, default 5) |
| `company-enriched` | company module | $0.0008 | per company with a name plus a social profile or contact |
| `tech-stack-found` | tech stack module | $0.0025 | per domain where at least one technology was detected |

The module charges are each Actor's own listed price, the same as running it alone, and they show on your bill under that Actor's name.

**Worked example.** A typical company with an email on its site, 3 people on its team page, a company profile and a tech stack costs $0.001 + $0.002 + 3 x $0.002 + $0.0008 + $0.0025 = **$0.0123**. 1,000 such companies cost about $12.30.

**Measured on our own runs (Apify platform, October 2026):** 3 software companies with team pages cost $0.039 in total ($0.013 each, 10 people found); 10 mixed small businesses (dentists, a pizzeria, a brewery, small software firms) cost $0.073 in total ($0.0073 each), because fewer of them publish a team page.

**Turning modules off lowers the cost.** Leave out people and tech stack and the most a company can cost is $0.001 + $0.002 + $0.0008 = $0.0038. Lower `maxPeoplePerCompany` to pay for fewer people.

**Your max cost per run is respected across all modules.** When you set a maximum total charge for the run, the Actor splits it between itself and the four module runs in proportion to each one's worst case per company (every module billing, `maxPeoplePerCompany` people each), and passes each module its share as that run's own limit. It enriches only as many companies as fit, says how many it skipped in the status message, and stops if the platform reports the limit reached. Because the split assumes the worst case, a tight limit can enrich fewer companies than it would have paid for.

### How to enrich a list of company domains

1. Paste the company domains into **Company domains**, one per line (bare domains or full URLs).
2. Switch off any module you don't need, and set **Max people per company**.
3. Click **Start**. The four modules start at once; the merged rows appear when they finish.
4. Open the **Company profiles** view in the Output tab and export as CSV, Excel or JSON, or read the dataset through the API.

### Run it after Google Maps Scraper or any scraper

To enrich every business a Google Maps scrape (or any other scraper that outputs websites) returns:

1. Open the source Actor's **Integrations** tab and add this Actor (`datagleaner/company-lead-enrichment`).
2. Set its input to:

```json
{"datasetId": "{{resource.defaultDatasetId}}"}
```

Every time the source run succeeds, this Actor reads the website of each result (`website`, `url`, `domain`, `site`, `homepage`, `link`, `companyWebsite` or `web`, the first one present, or the field you name in `datasetUrlField`), skips items without a website, map and social-network links and duplicates, and enriches each company up to `maxCompanies`. Each row keeps the source item's `title` or `name` as `sourceName`, for example the Google Maps place name.

From code, for a run that has already finished:

```python
run = client.actor("datagleaner/company-lead-enrichment").call(run_input={"datasetId": "SOURCE_DATASET_ID"})
```

When no `domains`, `startUrls` or `datasetId` is given, the Actor also looks for the triggering run's dataset in the integration payload (`payload.resource.defaultDatasetId`). If the platform does not let the run read that dataset, the status message says so: set `datasetId` as above.

### Input

```json
{
  "domains": ["baremetrics.com", "plausible.io", "savvycal.com"],
  "includeContacts": true,
  "includePeople": true,
  "includeCompany": true,
  "includeTechStack": true,
  "maxPeoplePerCompany": 5,
  "maxCompanies": 100
}
```

| Field | Meaning |
|---|---|
| `domains` | Company domains or URLs, one per line. Scheme, `www.`, path and case are ignored. |
| `startUrls` | The same in the common Apify format, `[{"url": "https://acme.com"}]`. Merged with `domains`. |
| `datasetId`, `datasetUrlField` | Read websites from another Actor's dataset (see above). |
| `includeContacts`, `includePeople`, `includeCompany`, `includeTechStack` | Modules to run (all on by default). A module that is off is not run and not billed. |
| `maxPeoplePerCompany` | People per company, most senior first (default 5, max 50). |
| `maxCompanies` | Companies per run across every source (default 100). |

With every source empty, the Actor runs a 3-company example (baremetrics.com, plausible.io, savvycal.com) and says so in the status message.

### Output

One row per company. Fields a module did not find are empty or `null`, never guessed. A real row (shortened):

```json
{
  "domain": "baremetrics.com",
  "input": "baremetrics.com",
  "website": "https://baremetrics.com/",
  "status": "ok",
  "billed": true,
  "companyName": "Baremetrics",
  "description": "Baremetrics is the subscription analytics platform that transforms recurring revenue data into actionable insights ...",
  "logoUrl": "https://baremetrics.com/hubfs/.../baremetrics-logo.svg",
  "foundingDate": null,
  "country": null,
  "address": null,
  "bestEmail": "hello@baremetrics.com",
  "emails": ["hello@baremetrics.com", "marketing@baremetrics.com", "luke@baremetrics.com"],
  "phones": ["+18559486210"],
  "socials": {
    "linkedin": null,
    "x": "https://x.com/Baremetrics",
    "facebook": "https://www.facebook.com/baremetrics",
    "instagram": "https://www.instagram.com/baremetricsapp",
    "youtube": "https://www.youtube.com/channel/UC4yqLVYBeheZX7Z8z9cfy8A",
    "tiktok": null,
    "github": "https://github.com/baremetrics",
    "pinterest": null
  },
  "people": [
    {"name": "Luke Marshall", "jobTitle": "CEO", "seniority": "c-level", "email": "luke@baremetrics.com", "linkedinUrl": null, "sourceUrl": "https://baremetrics.com/about"},
    {"name": "Allison Barkley", "jobTitle": "Director of Operations", "seniority": "director", "email": "allison@baremetrics.com", "linkedinUrl": null, "sourceUrl": "https://baremetrics.com/about"}
  ],
  "peopleCount": 5,
  "techStack": ["HubSpot CMS", "HubSpot", "Mailchimp", "Help Scout", "Intercom", "Google Analytics", "Google Workspace"],
  "platform": "HubSpot CMS",
  "cms": ["HubSpot CMS"],
  "ecommerce": [],
  "crmMarketing": ["HubSpot", "Mailchimp"],
  "analytics": ["Google Analytics", "Google Analytics 4"],
  "emailProvider": ["Google Workspace"],
  "techByCategory": {"CMS": ["HubSpot CMS"], "CRM and marketing automation": ["HubSpot", "Mailchimp"]},
  "sourceName": null,
  "moduleStatus": {"contacts": "ok", "people": "ok", "company": "ok", "techStack": "ok"},
  "warnings": [],
  "sources": {"contactsRunId": "nrCfRIVxl5FcilVP4", "peopleRunId": "6dLwgv820qbz1Llv5", "companyRunId": "7D3FufInCoeXR5gqc", "techStackRunId": "Zt8JXAxvVUgKfHKm1"},
  "scrapedAt": "2026-10-20T16:20:11+00:00"
}
```

`status` is `ok` when the row holds at least one email, person, company fact or technology (and is billed), `noData` when the site was read but held nothing, or the site's own status such as `unreachable` or `parked` (free). The final status message summarises the run: companies, how many had an email, people found and tech stacks found. The key-value store record `RUN_SUMMARY` lists each module's run ID and its share of your max cost.

### Measured results

Run on the Apify platform (datacenter IPs) in October 2026 on 10 mixed companies: two Austin dentists, a New York pizzeria, a Copenhagen brewery and six small software companies.

- **Email** found for 7 of 10, **phone** for 3, **at least one social profile** for 9 (LinkedIn company page for 5), **postal address** for 4.
- **Company name** for 10 of 10, **description** for 9.
- **People** for 4 of 10 (8 people, all founders or leaders, 3 with a LinkedIn link). The local businesses publish no team page; most small software companies do.
- **Tech stack** for 10 of 10, **email provider** for 8 (Google Workspace, Fastmail and others).
- Run time 52 seconds. On 3 software companies (the prefill), all 3 had an email, people (10 in all), a company profile and a tech stack, in 11 to 34 seconds over four runs.

A different list gives different rates. Local businesses rarely list their staff online, and some sites block automated visitors.

### Limits

- **Only what the company publishes on its own website**, plus its DNS records for the email provider. No LinkedIn search, no third-party databases, no guessed emails.
- No JavaScript rendering: details a site draws only with scripts after the page loads can be missed, and sites that block non-browser clients may come back `unreachable` (the contacts and company modules retry blocked sites once through Apify Proxy).
- People need a first and last name and a role on the page; first-name-only cards are skipped.
- The merged row appears when all four modules have finished, not company by company.
- Each module's run counts toward your account's concurrent runs and memory: 1 GB for contacts, 512 MB each for people and company, 2 GB for tech stack, about 4 GB in all while the modules run.

### Use it from n8n, Make, Zapier, the API or an AI agent

Actor ID: `datagleaner/company-lead-enrichment`

Minimal input:

```
{"domains": ["baremetrics.com", "plausible.io"]}
```

- **n8n:** add the **Apify** node (`@apify/n8n-nodes-apify`), choose **Run an Actor and get dataset**, set Actor to `datagleaner/company-lead-enrichment` and paste the input above.
- **Make:** use the Apify app's **Run an Actor** module, then **Get Dataset Items**.
- **Zapier:** use the Apify action **Run Actor**, then the search **Fetch dataset items**.
- **AI agents (MCP):** connect to `https://mcp.apify.com/?tools=datagleaner/company-lead-enrichment` and ask in plain words, for example: *Enrich baremetrics.com and plausible.io: best email, founders with LinkedIn, and which CRM they use.*

Python:

```python
## pip install apify-client
from apify_client import ApifyClient

client = ApifyClient("YOUR_APIFY_TOKEN")
run = client.actor("datagleaner/company-lead-enrichment").call(
    run_input={"domains": ["baremetrics.com", "plausible.io"], "maxPeoplePerCompany": 3}
)
for row in client.dataset(run.default_dataset_id).iterate_items():
    print(row["domain"], row["bestEmail"], [p["name"] for p in row["people"]], row["crmMarketing"])
```

One API call that returns the rows:

```bash
curl -X POST "https://api.apify.com/v2/acts/datagleaner~company-lead-enrichment/run-sync-get-dataset-items?token=<APIFY_TOKEN>" \
  -H "Content-Type: application/json" \
  -d '{"domains": ["baremetrics.com", "plausible.io"]}'
```

### FAQ

**Is this the same as running the four Actors myself?** The data is the same and so are their prices. This Actor saves the work of starting four runs and joining their rows by domain, and adds $0.001 for each merged company profile.

**Why do I see five Actors on my bill?** Each module runs as its own run in your account and bills its own listed events. The table above lists every event and price.

**Can I get only emails and decision makers?** Yes. Switch off `includeCompany` and `includeTechStack`. The most a company then costs is $0.001 + $0.002 + `maxPeoplePerCompany` x $0.002.

**Does it find personal emails of people?** Only when the company publishes them on its own pages. It never guesses or generates addresses.

**Does it work with a CSV of domains?** Paste the column into `domains`, or upload the file as a dataset and pass its ID in `datasetId`.

**What happens with duplicates and messy URLs?** `https://www.Acme.com/about`, `acme.com/` and `ACME.com` are treated as one company and enriched once.

**What if a module fails?** The row is still returned with what the other modules found. `moduleStatus` shows `failed` for that module and `warnings` gives the reason. A company with nothing found is free.

### Related Data Gleaner Actors

- [Website Email Finder & Contact Details Scraper](https://apify.com/datagleaner/website-contact-details-scraper): every email, phone, social profile and contact form on a website.
- [Company Leadership & Team Page Scraper](https://apify.com/datagleaner/team-page-contacts): founders, executives and team members from a company's own website, one row per person.
- [Company Enrichment by Domain](https://apify.com/datagleaner/company-enrichment-by-domain): company name, logo, description and official social profiles.
- [Tech Stack Lookup by Domain](https://apify.com/datagleaner/tech-stack-by-domain): CMS, shop platform, CRM, analytics and email provider of any website.

### Responsible use

This Actor reads publicly available web pages and DNS records only. Names, work emails and phone numbers of people can still be personal data. You are responsible for complying with the law that applies to you, including data protection rules (GDPR, CCPA and similar) and anti-spam law, when you store or contact the companies and people in the results.

# Actor input Schema

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

Company websites, one per line. `acme.com`, `www.acme.com` and `https://acme.com/about` all count as the same company: scheme, `www.`, path and case are ignored and duplicates are removed. Leave every source empty to run a 3-domain example.

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

Optional. A list of `{"url": "https://example.com"}` objects, the common Apify format. Merged with Company domains and the dataset, duplicates removed.

## `datasetId` (type: `string`):

Optional. Read company websites from this dataset, for example Google Maps Scraper results, and add them to the domains above. Each item's `website` (or `url`, `domain`, `site`, `homepage`, `link`, `companyWebsite`, `web`) is used; map and social-network links are skipped, and items without a website are skipped. Each row keeps the item's `title` or `name` as `sourceName`. In an integration use `{{resource.defaultDatasetId}}`, or leave it empty: with no other source the triggering run's dataset is read automatically.

## `datasetUrlField` (type: `string`):

Optional. Name of the field that holds the website when it is not one of the usual ones. Tried first.

## `includeContacts` (type: `boolean`):

Crawls up to 8 pages of each site (contact, about, legal, team) for emails, phones, social profiles, contact forms and postal address. Billed by the contacts module at $0.002 per site with an email.

## `includePeople` (type: `boolean`):

Named people the company publishes on its own team, about, leadership and Impressum pages, with job title, seniority, LinkedIn and published email. Billed by the people module at $0.002 per person returned.

## `includeCompany` (type: `boolean`):

Company name, legal name, description, logo, founding date, address, country and official social profiles. Billed by the company module at $0.0008 per enriched company.

## `includeTechStack` (type: `boolean`):

CMS, shop platform, CRM and marketing tools, analytics, hosting and email provider, each with evidence. Billed by the tech module at $0.0025 per domain with a technology detected.

## `maxPeoplePerCompany` (type: `integer`):

Most senior first (founders, C-level, VPs, directors, then others). People over this cap are not returned and not billed.

## `maxCompanies` (type: `integer`):

Upper bound on companies enriched in one run, across domains, start URLs and the dataset.

## Actor input object example

```json
{
  "domains": [
    "baremetrics.com",
    "plausible.io",
    "savvycal.com"
  ],
  "includeContacts": true,
  "includePeople": true,
  "includeCompany": true,
  "includeTechStack": true,
  "maxPeoplePerCompany": 5,
  "maxCompanies": 10
}
```

# 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 = {
    "domains": [
        "baremetrics.com",
        "plausible.io",
        "savvycal.com"
    ],
    "maxCompanies": 10
};

// Run the Actor and wait for it to finish
const run = await client.actor("datagleaner/company-lead-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": [
        "baremetrics.com",
        "plausible.io",
        "savvycal.com",
    ],
    "maxCompanies": 10,
}

# Run the Actor and wait for it to finish
run = client.actor("datagleaner/company-lead-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": [
    "baremetrics.com",
    "plausible.io",
    "savvycal.com"
  ],
  "maxCompanies": 10
}' |
apify call datagleaner/company-lead-enrichment --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,datagleaner/company-lead-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/BgEQJcKDHHrszMjNY/builds/zwBGfe4FSui7OfjBU/openapi.json
