# B2B Lead & Multi-Channel Contact Enricher (`wonx_2983/b2b-lead-multi-channel-contact-enricher`) Actor

Scrape, discover, and enrich B2B leads from search queries or website URLs. Deep extraction of direct & obfuscated emails, international phone numbers, LinkedIn & social profiles, Schema.org/JSON-LD company intelligence, physical addresses, and key decision-maker contact pages.

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

## Pricing

Pay per usage

This Actor is paid per platform usage. The Actor is free to use, and you only pay for the Apify platform usage, which gets cheaper the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-usage

## 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 & Multi-Channel Contact Enricher

[![Apify Actor](https://img.shields.io/badge/Apify-Actor-orange?logo=apify)](https://apify.com)
[![Python 3.11](https://img.shields.io/badge/Python-3.11-blue?logo=python)](https://python.org)
[![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)](https://opensource.org/licenses/MIT)

> **Autonomous B2B Lead Generation & Multi-Channel Contact Enrichment Engine.** Discover verified business emails (including Cloudflare-obfuscated & `[at]` protections), international phone numbers, LinkedIn & social networks, Schema.org company intelligence, physical addresses, and tech stacks from queries or direct URLs.

***

### ⚡ Key Capabilities

- 🎯 **Dual Input Architecture:**
  - **Discovery Mode:** Feed natural search queries (e.g., *"Roofing contractors in Miami, FL"*, *"SaaS startups Berlin"*, *"Commercial cleaning Dallas TX"*) to dynamically uncover live company domains.
  - **Direct URL Mode:** Enrich a list of pre-existing website domains or URLs in bulk.
- ✉️ **Military-Grade Email Extraction:**
  - Unmasks standard `mailto:` links and RFC 5322 regex addresses.
  - Decodes **Cloudflare `data-cfemail` hex obfuscation** and `/cdn-cgi/l/email-protection` scripts.
  - Decodes obfuscated patterns (e.g. `info [at] company [dot] com`, `contact(at)domain.com`).
  - Intelligent scoring to identify the **Primary Corporate Email** (`contact@`, `info@`, `sales@`, etc.).
- 📞 **Global Phone Number Normalization:**
  - Extracts raw phone numbers, `tel:` links, and formatted text.
  - Normalizes numbers into international **E.164** and standard regional formats via Google's `libphonenumber` engine.
- 🌐 **Multi-Channel Social Intelligence:**
  - Extracts verified direct links for **LinkedIn** (company & personal), **Twitter / X**, **Facebook**, **Instagram**, **YouTube**, **TikTok**, **GitHub**, **Pinterest**, and **Telegram**.
  - Intelligent filtering discards share buttons (`/sharer.php`, `/intent/tweet`) and system pages.
- 🏢 **Deep Schema.org & Address Intelligence:**
  - Parses `LocalBusiness`, `Organization`, `Corporation`, and `PostalAddress` JSON-LD scripts.
  - Extracts physical street address, city, state, postal code, country, and precise latitude/longitude geo-coordinates.
- 🕷️ **Multi-Page Internal Link Traversal:**
  - Automatically identifies and crawls high-value internal subpages: `/contact`, `/about`, `/team`, `/reach-us`, `/support`, `/impressum`, `/kontakt`.
- 🛡️ **Anti-Bot Resilience & Proxy Support:**
  - Rotating desktop browser User-Agents and modern HTTP/2 client headers.
  - Fully compatible with **Apify Residential / Datacenter Proxies** and custom HTTP/HTTPS proxy pools.

***

### 📥 Input Configuration

Configure your actor using the Apify Console UI or via raw JSON:

#### Example Input JSON

```json
{
  "searchQueries": [
    "Commercial solar contractors Austin TX",
    "B2B SaaS companies Berlin"
  ],
  "startUrls": [
    { "url": "https://stripe.com" },
    { "url": "https://vercel.com" }
  ],
  "maxLeadsPerQuery": 20,
  "deepCrawlContactPages": true,
  "maxInternalPagesPerDomain": 5,
  "extractEmails": true,
  "extractPhones": true,
  "extractSocials": true,
  "extractAddresses": true,
  "extractMetadata": true,
  "defaultCountry": "US",
  "concurrency": 8,
  "requestTimeoutSec": 15,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

#### Input Field Specifications

| Field | Type | Default | Description |
|---|---|---|---|
| `searchQueries` | Array of Strings | `[]` | List of search queries/niches + locations for automated website discovery. |
| `startUrls` | Array of Objects | `[]` | List of target websites to crawl directly (`{"url": "https://example.com"}`). |
| `maxLeadsPerQuery` | Integer | `25` | Max distinct business domains to discover per search query. |
| `deepCrawlContactPages` | Boolean | `true` | Automatically traverse `/contact`, `/about`, `/team` pages. |
| `maxInternalPagesPerDomain` | Integer | `5` | Maximum internal contact pages to crawl per domain. |
| `extractEmails` | Boolean | `true` | Extract plain, mailto, obfuscated, and Cloudflare emails. |
| `extractPhones` | Boolean | `true` | Extract and normalize phone numbers into international format. |
| `extractSocials` | Boolean | `true` | Discover LinkedIn, Twitter/X, Facebook, Instagram, YouTube, etc. |
| `extractAddresses` | Boolean | `true` | Parse Schema.org JSON-LD for address & geo-coordinates. |
| `defaultCountry` | String | `"US"` | 2-letter ISO country code used for local phone parsing. |
| `concurrency` | Integer | `8` | Number of parallel worker threads. |
| `requestTimeoutSec` | Integer | `15` | Timeout per HTTP page request. |
| `proxyConfiguration` | Object | `{"useApifyProxy": true}` | Apify Proxy or custom proxy configuration. |

***

### 📤 Output Dataset Format

Each enriched lead is saved into the default Apify Dataset as clean, structured JSON:

```json
{
  "domain": "acmeroofingfl.com",
  "websiteUrl": "https://acmeroofingfl.com",
  "sourceQuery": "Roofing contractors in Miami, FL",
  "companyName": "Acme Commercial Roofing",
  "title": "Acme Commercial Roofing | Miami FL Premier Roofing Specialists",
  "description": "Leading industrial and commercial roofing contractors serving Miami-Dade and South Florida.",
  "emails": [
    "contact@acmeroofingfl.com",
    "service@acmeroofingfl.com",
    "estimates@acmeroofingfl.com"
  ],
  "primaryEmail": "contact@acmeroofingfl.com",
  "phones": [
    "+1 305-555-0199",
    "+1 305-555-0188"
  ],
  "primaryPhone": "+1 305-555-0199",
  "socialProfiles": {
    "linkedin": "https://www.linkedin.com/company/acme-commercial-roofing",
    "twitter": "https://x.com/acmeroofingfl",
    "facebook": "https://www.facebook.com/acmecommercialroofing",
    "instagram": "https://www.instagram.com/acmeroofingfl",
    "youtube": "https://www.youtube.com/@AcmeRoofingFL",
    "tiktok": null,
    "github": null,
    "pinterest": null,
    "telegram": null
  },
  "address": {
    "streetAddress": "742 NW 1st Ave",
    "addressLocality": "Miami",
    "addressRegion": "FL",
    "postalCode": "33136",
    "addressCountry": "US",
    "formattedAddress": "742 NW 1st Ave, Miami, FL, 33136, US",
    "latitude": 25.7812,
    "longitude": -80.1983
  },
  "schemaType": "LocalBusiness, RoofingContractor",
  "crawledPages": [
    "https://acmeroofingfl.com",
    "https://acmeroofingfl.com/contact",
    "https://acmeroofingfl.com/about-us"
  ],
  "contactPageUrls": [
    "https://acmeroofingfl.com/contact",
    "https://acmeroofingfl.com/about-us"
  ],
  "technologies": [
    "Cloudflare",
    "Google Analytics / GTM",
    "WordPress"
  ],
  "status": "SUCCESS",
  "errorMessage": null,
  "enrichedAt": "2026-10-05T18:30:00.000000Z"
}
```

***

### 🔗 CRM & Automation Integrations

Export your dataset effortlessly into any sales and marketing workflow:

#### 1. Make.com (Integromat)

1. Add an **Apify** module -> *Watch Dataset Items*.
2. Select this Actor's dataset.
3. Map `primaryEmail`, `companyName`, `primaryPhone`, and `socialProfiles.linkedin` to **HubSpot**, **Salesforce**, or **Pipedrive** (*Create/Update Contact*).

#### 2. Zapier

1. Set Trigger: **Apify - New Item in Dataset**.
2. Action: **Google Sheets - Create Spreadsheet Row** or **Instantly.ai / Smartlead - Add Lead to Campaign**.

#### 3. Webhooks & API

Listen to Apify run completion webhooks and retrieve the JSON dataset with:

```bash
curl "https://api.apify.com/v2/datasets/{DATASET_ID}/items?format=json" \
  -H "Authorization: Bearer YOUR_APIFY_TOKEN"
```

***

### 🛠️ Local Development & Deployment

#### 1. Local Setup

```bash
## Clone or navigate to the project directory
cd b2b-lead-contact-enricher

## Create and activate virtual environment
python -m venv venv
## Windows:
venv\Scripts\activate
## Linux/macOS:
source venv/bin/activate

## Install dependencies
pip install -r requirements.txt
```

#### 2. Run Locally with Apify CLI

```bash
## Run actor locally using local storage
apify run
```

#### 3. Deploy to Apify Cloud

```bash
## Login to Apify
apify login

## Push and build Actor on Apify platform
apify push
```

***

### 💡 Best Practices

1. **Enable Residential Proxies for Discovery:** When running large batches of search queries, set `proxyConfiguration: { "useApifyProxy": true, "apifyProxyGroups": ["RESIDENTIAL"] }` for highest success rates.
2. **Adjust Concurrency:** For large enterprise domains, set `concurrency` between `10` and `25` to achieve high throughput without encountering edge rate limits.
3. **Target Country Phone Normalization:** Set `defaultCountry` matching your target market (e.g. `GB` for United Kingdom, `DE` for Germany, `US` for United States) to optimize phone number parsing.

***

### 📄 License

MIT License. Created for high-performance lead generation and enterprise sales intelligence workflows.

# Actor input Schema

## `searchQueries` (type: `array`):

List of search terms or business niches + locations to discover relevant company websites (e.g., 'Roofing contractors in Miami, FL', 'Fintech startups London', 'Commercial cleaning services Dallas').

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

List of direct website or company domain URLs to enrich. Accepts plain URLs or Apify request format.

## `maxLeadsPerQuery` (type: `integer`):

Maximum number of distinct business domains to extract and enrich per search query in Discovery Mode.

## `deepCrawlContactPages` (type: `boolean`):

When enabled, the actor automatically traverses internal pages (/contact, /about, /team, /impressum, /support, /reach-us) to discover hidden contact details.

## `maxInternalPagesPerDomain` (type: `integer`):

Maximum number of secondary internal pages to crawl per website for contact discovery.

## `extractEmails` (type: `boolean`):

Extract plain emails, mailto links, obfuscated \[at] / \[dot] representations, and Cloudflare-protected email addresses.

## `extractPhones` (type: `boolean`):

Extract phone numbers, tel: links, and normalize into E.164 and international standards.

## `extractSocials` (type: `boolean`):

Discover company profiles across LinkedIn, Twitter/X, Facebook, Instagram, YouTube, TikTok, GitHub, Pinterest, and Telegram.

## `extractAddresses` (type: `boolean`):

Parse Schema.org / JSON-LD / Microdata for LocalBusiness, Organization, street address, postal code, and geo-coordinates.

## `extractMetadata` (type: `boolean`):

Extract meta titles, descriptions, OpenGraph tags, language, and page titles.

## `defaultCountry` (type: `string`):

Two-letter ISO 3166-1 alpha-2 country code (e.g., 'US', 'GB', 'DE', 'FR', 'CA', 'AU') used as fallback for local phone parsing.

## `concurrency` (type: `integer`):

Number of concurrent domain enrichment tasks running in parallel.

## `requestTimeoutSec` (type: `integer`):

Timeout in seconds for fetching each webpage.

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

Proxy settings. Recommended to enable Apify Proxy with RESIDENTIAL or DATACENTER groups to avoid rate limiting.

## Actor input object example

```json
{
  "searchQueries": [
    "SaaS startups Austin TX",
    "HVAC contractors Denver CO"
  ],
  "startUrls": [
    {
      "url": "https://stripe.com"
    },
    {
      "url": "https://vercel.com"
    }
  ],
  "maxLeadsPerQuery": 25,
  "deepCrawlContactPages": true,
  "maxInternalPagesPerDomain": 5,
  "extractEmails": true,
  "extractPhones": true,
  "extractSocials": true,
  "extractAddresses": true,
  "extractMetadata": true,
  "defaultCountry": "US",
  "concurrency": 8,
  "requestTimeoutSec": 15,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

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

Structured dataset of discovered and enriched B2B leads with emails, phone numbers, social media links, and company intelligence.

# 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 = {
    "searchQueries": [
        "SaaS startups Austin TX",
        "HVAC contractors Denver CO"
    ],
    "startUrls": [
        {
            "url": "https://stripe.com"
        },
        {
            "url": "https://vercel.com"
        }
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("wonx_2983/b2b-lead-multi-channel-contact-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 = {
    "searchQueries": [
        "SaaS startups Austin TX",
        "HVAC contractors Denver CO",
    ],
    "startUrls": [
        { "url": "https://stripe.com" },
        { "url": "https://vercel.com" },
    ],
}

# Run the Actor and wait for it to finish
run = client.actor("wonx_2983/b2b-lead-multi-channel-contact-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 '{
  "searchQueries": [
    "SaaS startups Austin TX",
    "HVAC contractors Denver CO"
  ],
  "startUrls": [
    {
      "url": "https://stripe.com"
    },
    {
      "url": "https://vercel.com"
    }
  ]
}' |
apify call wonx_2983/b2b-lead-multi-channel-contact-enricher --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,wonx_2983/b2b-lead-multi-channel-contact-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/ttzuPAPQ99q2mnFpU/builds/1SEq405C7UaYw3hUg/openapi.json
