# 🌟B2b Lead Enricher (`databuddy/b2b-lead-enricher`) Actor

- **URL**: https://apify.com/databuddy/b2b-lead-enricher.md
- **Developed by:** [Sarthak](https://apify.com/databuddy) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.00005 / actor start

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

## 🏢 B2B Lead Enricher — Email Finder, LinkedIn, Tech Stack & Company Data

Paste a list of company websites and get back enriched B2B leads. For each one you get:

- business emails with a **confidence score**;
- phone numbers;
- the LinkedIn company page and other social profiles;
- the **technologies the site runs on**;
- domain data: WHOIS, SSL, and the email provider (Google Workspace, Microsoft 365, …);
- a **0–100 lead score with an A–D grade**.

Every value comes with the evidence of where it was found.

No API keys, no logins, no browser — fast HTTP crawling that works on the free Apify plan.

**Keywords:** email finder · company email finder · B2B lead enrichment · LinkedIn company URL finder · tech stack detector · WHOIS lookup · MX record check · email provider lookup · lead scoring · CRM enrichment · Hunter.io alternative · Apollo alternative · Clearbit alternative · website contact scraper

***

### ✨ What makes it different

| | This actor | Typical email finders |
|---|---|---|
| Emails from homepage + contact, team, about, impressum, support and press pages | ✅ | ✅ |
| **Cloudflare-protected emails decoded**, written-out emails (`sales [at] acme [dot] com`) and JSON-LD structured data | ✅ | ❌ |
| Confidence score **with reasons** for every email | ✅ | partial |
| Personal vs role mailboxes (info@, sales@, press@ …) | ✅ | ✅ |
| Company's real email format detected from published emails (first.last, f.last …) | ✅ | ❌ |
| **100+ technologies**, each with the exact code signal that proves it — no false hits from logos or blog mentions | ✅ | ❌ |
| Email provider (Google Workspace / Microsoft 365 / Zoho …) plus SPF and DMARC | ✅ | ❌ |
| Social profiles ranked so the company's own accounts come first, not authors or partners | ✅ | ❌ |
| Filters: required technology, lead grade, domain age, keywords, email only | ✅ | ❌ |
| Websites that fail show the reason and how to fix it — and are never charged | ✅ | ❌ |

### 🎯 Use cases

- **Sales prospecting:** turn a list of target accounts into contacts plus a priority grade.
- **Tech-based targeting:** find every prospect running Shopify, HubSpot, WordPress or Stripe.
- **Microsoft vs Google targeting:** see which companies run Microsoft 365 or Google Workspace.
- **Inbound lead qualification:** check domain age, SSL and mail server to tell real businesses from throwaways.
- **CRM enrichment:** feed the results into HubSpot, Salesforce or Pipedrive through Make, n8n or Zapier.
- **Recruiting and partnerships:** pull HR, careers and partnerships mailboxes.

### 🔧 Input

```json
{
  "urls": [
    "https://stripe.com",
    "figma.com",
    "jane@shopify.com",
    "acme-robotics.com | John | Doe"
  ],
  "firstName": "John",
  "lastName": "Doe",
  "maxPagesPerSite": 6,
  "requiredTech": ["Shopify", "HubSpot"],
  "minLeadGrade": "B"
}
```

| Option | What it does |
|---|---|
| `urls` | Domains, URLs or emails, one per line. Optionally add names to a line: `site.com \| First \| Last`. Duplicate domains are removed. |
| `firstName`, `lastName` | Contact name used to guess their email at every company. Names on a line override these. |
| `maxPagesPerSite` | Homepage plus the most useful internal pages, between 1 and 20 (default 6). |
| `includeExecutiveEmails` | Role guesses such as `ceo@`, `cto@`, `hr@` and `sales@`. Always marked unverified. |
| `checkWhois`, `checkSsl`, `checkDns` | Domain data. Turn any of them off for speed. |
| `includeFailedSites` | Adds a row with the reason for every site that couldn't be crawled. These rows are free. |
| `onlyWithEmail`, `onlyWithContact`, `requireMx` | Contact-quality filters. |
| `minLeadGrade`, `requiredTech`, `minDomainAgeYears`, `companyKeywords` | Targeting filters. Profiles they remove are never charged. |
| `skipPreviouslyScraped` | Remembers domains across runs, so scheduled runs only charge for new companies. |
| `proxyConfiguration` | Off by default, which is cheapest. Turn it on if many sites come back `blocked`. |

### 📤 Output (60+ fields per company)

```json
{
  "status": "ok",
  "domain": "stripe.com",
  "company_name": "Stripe",
  "lead_grade": "A - Hot Lead",
  "lead_score": 75,
  "primary_email": "media@stripe.com",
  "scored_emails": [
    { "email": "media@stripe.com", "confidence": 85, "type": "generic",
      "evidence": ["mailto link on stripe.com/newsroom"] }
  ],
  "phones": ["+1 888 926 2289"],
  "linkedin": ["https://www.linkedin.com/company/stripe"],
  "twitter": ["https://x.com/stripe"],
  "tech_stack": ["Next.js", "Nginx"],
  "email_provider": "Google Workspace",
  "has_spf": true,
  "dmarc_policy": "reject",
  "registrar": "SafeNames Ltd.",
  "domain_created": "1995-09-12",
  "ssl_valid": true,
  "person_email_guesses": { "best_guess": "john.doe@stripe.com", "verified": false },
  "executive_emails": { "verified": false, "patterns": { "CEO": "ceo@stripe.com" } }
}
```

**Fields**

- **Company:** domain, website, company name (and its source), description, page title, language, address, founding date, employee count.
- **Emails:** primary email, all emails, personal emails, generic emails, and scored emails with confidence, type, pages and evidence.
- **Phones:** primary phone, phones, and phone evidence.
- **Social:** LinkedIn company, LinkedIn people, X/Twitter, Facebook, Instagram, YouTube, TikTok, GitHub.
- **Tech:** tech stack, count, categories, and the evidence for each one.
- **Email setup:** MX records, email provider, SPF, DMARC policy.
- **Domain:** registrar, created and expiry dates, domain age, plus the full WHOIS object.
- **SSL:** valid or not, issuer, days left, plus the full SSL object.
- **Patterns:** detected email format with evidence, person email guesses, executive email patterns.
- **Scoring:** lead score, grade, and the reason for every point; keyword match evidence.
- **Crawl details:** pages crawled, status, error, how to fix, input, scraped at.

The dataset has three views: **Overview**, **Contacts only** and **Tech & domain**.

#### Lead score (12 signals)

| Points | Signal |
|---|---|
| +15 | Any email found |
| +15 | A named person's email found |
| +5 | An email on the company's own domain |
| +10 | Phone found |
| +10 | LinkedIn company page |
| +5 | Two or more other social profiles |
| +10 | Domain receives email (MX records) |
| +5 | Rich tech stack (5+ tools) |
| +5 | Pays for marketing or sales tools (CRM, chat, email marketing, ads) |
| +5 / +10 | Domain older than 2 / 5 years |
| +5 | Valid SSL certificate |
| +5 | Company name and description published |

**A - Hot Lead** 75–100 · **B - Warm Lead** 50–74 · **C - Cool Lead** 25–49 · **D - Cold Lead** 0–24

#### Email confidence

Each email starts at 40 points, and the reasons are listed on the email itself:

| Points | Signal |
|---|---|
| +30 | On the company's own domain |
| +20 | On a sister domain (for example acme.io for acme.com) |
| −25 | On an unrelated domain (vendor or agency) |
| +15 | Published as a mailto link or in structured data |
| +10 | Found on a contact or team page |
| +5 | Found on several pages |
| +5 | A named person |

### 📊 Run summary

Each run writes a `RUN_SUMMARY` record with:

- companies saved, how many have contacts, and charged events;
- a count for every status and every skip reason, with examples;
- the grade distribution and the email providers found;
- the most common technologies;
- request and block counts, and field fill rates.

### 💰 Pricing

You only pay for companies that are saved:

| Event | When |
|---|---|
| `company-lead` | Company enriched, no public email or phone found |
| `company-lead-with-contact` | Company enriched with at least one email or phone |

Websites that are unreachable, blocked or invalid, duplicates, domains already saved in earlier runs, and companies removed by your filters are **never charged**.

### ❓ FAQ

**Are the emails verified?** Emails published on the site are real addresses the company put there. They're ranked by confidence, and each one says where it was found. Person and role guesses are always marked `verified: false`; check them with an email verifier before sending.

**Does it work on JavaScript-only sites?** It reads the HTML the server sends, plus structured data. Most marketing sites work fine. Pure single-page apps may give fewer results.

**Some sites come back `blocked`.** That site has bot protection. Turn on the proxy (Apify Proxy, RESIDENTIAL gets through most) and run again. WHOIS, DNS and SSL data are still included in the failed row.

**Why is the domain age empty for .de and some other domains?** Some registries don't publish registration dates. The field stays empty and is never estimated.

**Does it find people's LinkedIn profiles?** It returns company pages, plus any personal profiles linked from the site (for example on team pages) in `linkedin_people`.

### ⚖️ Notes

This actor reads public company websites and public DNS/WHOIS data only. You are responsible for using contact data in line with privacy and anti-spam laws in your market (GDPR, CAN-SPAM, etc.).

# Actor input Schema

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

One per line: a domain (stripe.com), a URL (https://stripe.com) or an email (jane@stripe.com — its domain is used). Optional per-line names for email pattern guesses: "stripe.com | John | Doe". Duplicate domains are removed.

## `firstName` (type: `string`):

Contact first name used to predict their email at every company (for example John → john.doe@company.com). Per-line names override this.

## `lastName` (type: `string`):

Contact last name for email pattern prediction.

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

Homepage plus the most useful internal pages (contact, team, about, impressum, support, press). More pages find more emails but take longer.

## `maxResults` (type: `integer`):

Stop after this many enriched companies are saved (and charged). 0 = no limit.

## `includeExecutiveEmails` (type: `boolean`):

Adds guessed role addresses such as ceo@company.com. Always marked unverified; roles actually published on the site are listed as confirmed. Never mixed into the found emails.

## `checkWhois` (type: `boolean`):

Looks up registration and expiry dates and the registrar through RDAP, the official successor of WHOIS.

## `checkSsl` (type: `boolean`):

Checks certificate validity, issuer and days until expiry.

## `checkDns` (type: `boolean`):

Checks whether the domain can receive email, which provider hosts it (Google Workspace, Microsoft 365…) and its SPF/DMARC setup.

## `includeFailedSites` (type: `boolean`):

Adds a row (status = blocked / unreachable / invalid_input …) with the reason and how to fix it for every website that could not be crawled. These rows are never charged.

## `onlyWithEmail` (type: `boolean`):

Skip companies where no public email was found.

## `onlyWithContact` (type: `boolean`):

Skip companies with neither a public email nor a phone number.

## `minLeadGrade` (type: `string`):

Skip companies below this grade. A = 75–100, B = 50–74, C = 25–49, D = 0–24.

## `requiredTech` (type: `array`):

Keep only sites using at least one of these, e.g. Shopify, WordPress, HubSpot, Stripe, Webflow. Names as shown in the tech_stack column (not case-sensitive). Leave empty to keep all.

## `minDomainAgeYears` (type: `integer`):

Skip domains registered more recently than this. 0 = no minimum.

## `includeUnknownDomainAge` (type: `boolean`):

Some registries (e.g. .de) publish no registration date. When a min domain age is set, keep these if on, skip them if off. The age stays empty — never guessed.

## `requireMx` (type: `boolean`):

Skip domains without a mail server — their emails would bounce.

## `companyKeywords` (type: `array`):

Keep only companies whose name, description or page title matches one of these (e.g. "payments", "real estate", "SaaS"). Capitals, accents, hyphens and plurals are treated as equal.

## `keywordMatchMode` (type: `string`):

Exact phrase: words together in order. All words: every word anywhere. Any word: one is enough. Off: ignore keywords.

## `skipPreviouslyScraped` (type: `boolean`):

Remembers saved domains in a named key-value store and skips them in later runs, so scheduled runs only charge for new companies.

## `dedupeStoreName` (type: `string`):

Name of the key-value store that remembers saved domains. Lowercase letters, numbers and hyphens.

## `proxyConfiguration` (type: `object`):

Most company websites work without a proxy (cheapest). If sites come back as "blocked", turn on Apify Proxy — RESIDENTIAL gets through the most bot protection.

## Actor input object example

```json
{
  "urls": [
    "https://stripe.com",
    "figma.com",
    "shopify.com"
  ],
  "firstName": "",
  "lastName": "",
  "maxPagesPerSite": 6,
  "maxResults": 0,
  "includeExecutiveEmails": true,
  "checkWhois": true,
  "checkSsl": true,
  "checkDns": true,
  "includeFailedSites": true,
  "onlyWithEmail": false,
  "onlyWithContact": false,
  "minLeadGrade": "D",
  "requiredTech": [],
  "minDomainAgeYears": 0,
  "includeUnknownDomainAge": true,
  "requireMx": false,
  "companyKeywords": [],
  "keywordMatchMode": "exact",
  "skipPreviouslyScraped": false,
  "dedupeStoreName": "b2b-lead-enricher-seen",
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

## `companies` (type: `string`):

No description

## `contacts` (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 = {
    "urls": [
        "https://stripe.com",
        "figma.com",
        "shopify.com"
    ],
    "proxyConfiguration": {
        "useApifyProxy": false
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("databuddy/b2b-lead-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 = {
    "urls": [
        "https://stripe.com",
        "figma.com",
        "shopify.com",
    ],
    "proxyConfiguration": { "useApifyProxy": False },
}

# Run the Actor and wait for it to finish
run = client.actor("databuddy/b2b-lead-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 '{
  "urls": [
    "https://stripe.com",
    "figma.com",
    "shopify.com"
  ],
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}' |
apify call databuddy/b2b-lead-enricher --silent --output-dataset

```

## MCP server setup

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