# Email Pattern Finder — Name + Domain to Business Email (`haketa/email-pattern-finder`) Actor

Find business emails from a person's name and company domain, in bulk. Generates and ranks every email format (first.last@, flast@, first@…), learns a company's exact pattern from one known address, and validates domains via MX. Keyless email finder for lead gen, sales and outreach.

- **URL**: https://apify.com/haketa/email-pattern-finder.md
- **Developed by:** [Haketa](https://apify.com/haketa) (community)
- **Categories:** Lead generation, Business
- **Features:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.00 / 1,000 results

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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

## Email Pattern Finder — Name + Domain to Business Email

[![Apify Actor](https://img.shields.io/badge/Apify-Actor-orange?style=flat-square\&logo=apify)](https://apify.com/haketa/email-pattern-finder)
[![Maintenance](https://img.shields.io/badge/Maintained%3F-yes-green.svg?style=flat-square)](https://apify.com/haketa/email-pattern-finder)
[![Data Format](https://img.shields.io/badge/Data-JSON%20%7C%20CSV%20%7C%20Excel-blue?style=flat-square)](https://apify.com/haketa/email-pattern-finder)
[![Bulk Processing](https://img.shields.io/badge/Scale-1%2C000%2B%20Contacts-brightgreen?style=flat-square)](https://apify.com/haketa/email-pattern-finder)
[![Lead Generation](https://img.shields.io/badge/Lead%20Gen-B2B%20Intelligence-purple?style=flat-square)](https://apify.com/haketa/email-pattern-finder)
[![Speed](https://img.shields.io/badge/Speed-100%20Lookups%2Fsec-darkblue?style=flat-square)](https://apify.com/haketa/email-pattern-finder)

**Turn a person's name and company domain into the most likely business email address — in bulk.** Give this **email pattern finder** a list like `Jane Doe, acme.com` and for every contact it returns the **most probable business email, the email syntax pattern used, a 0–100 confidence score, real-time MX mail server validation, and a complete set of ranked alternatives**. No third-party credits, no expensive per-lookup API bills, and no rate limits.

Equipped with **smart pattern reverse-engineering**: feed it **one known confirmed email per company** (e.g., `John Smith, jsmith@acme.com`) and the actor automatically uncovers that company's exact naming convention (`pattern-learned`, ~92% confidence) and applies it to every employee at that domain.

***

### ⚡ At a glance

| Feature | Details |
|---|---|
| **Input Format** | `Full Name, company.com` or structured JSON objects |
| **Output Data** | Best-guess email, pattern name, confidence score, MX status, ranked alternatives |
| **Pattern Learning** | Reverse-engineers company format from a single sample address |
| **Supported Patterns** | 12 standard business formats (`first.last`, `flast`, `first`, `f.last`, etc.) |
| **Domain Validation** | Live asynchronous DNS MX record checks with domain-level caching |
| **International Names** | Full Unicode accent normalization (`José` → `jose`, `Müller` → `muller`) |
| **Processing Speed** | 50–200 simultaneous parallel DNS lookups; hundreds of contacts per second |
| **Export Formats** | Dataset (JSON, CSV, Excel, XML), Key-Value store, REST API |
| **Platform Integration** | Direct webhooks, Python SDK, Node.js SDK, Make, Zapier, n8n |

***

### 🔎 Why use an email pattern finder?

In modern sales prospecting and lead generation, sales and recruiting teams rarely possess direct verified email addresses right away. Instead, you start with **names and company affiliations** gathered from conference attendee lists, webinar registrations, company org charts, alumni directories, or speaking rosters.

Manually guessing formats or paying $0.10 to $0.50 per record to proprietary enrichment providers is neither scalable nor cost-effective.

**Primary applications for bulk email pattern finding:**

- **B2B outbound list building**: Convert target accounts and decision-maker rosters into deliverable email outreach campaigns.
- **CRM and pipeline enrichment**: Backfill missing business email fields in HubSpot, Salesforce, Pipedrive, or Airtable.
- **Conference and event lead capture**: Turn participant names and sponsor company domains into contactable leads within minutes.
- **Talent sourcing and recruiting**: Generate direct work email addresses for prospective executive and technical candidates.
- **Cost optimization**: Replace recurring SaaS subscription costs from services like Hunter, Apollo, or Clearbit with direct DNS generation.
- **Fallback candidate generation**: If the primary predicted format bounces, retrieve ranked backup candidate formats instantly.

***

### ⚖️ Comparative overview: Why generate emails in bulk?

| Feature / Metric | Proprietary Enrichment (Apollo / Hunter) | Manual Guessing | Email Pattern Finder |
|---|---|---|---|
| **Cost per 1,000 Contacts** | $50 – $200+ | Dozens of wasted hours | Fractions of a cent (compute only) |
| **Speed** | 1–5 lookups / sec (rate limited) | 1 contact every 2 minutes | 100+ lookups / sec |
| **Pattern Learning** | Proprietary black box | Intuition / trial & error | Reverse-engineers exact format from sample |
| **Data Privacy** | Contact lists shared with vendor | High manual exposure | Zero third-party data transmission |
| **API & Webhooks** | Rigid enterprise tier paywalls | None | Native Apify API, webhooks & SDKs |
| **Alternative Formats** | Usually 1 email returned | 1 at a time | All 12 ranked formats provided |

***

### 📐 Supported Email Patterns Reference

The actor evaluates 12 distinct naming conventions, weighted according to comprehensive real-world enterprise adoption datasets:

| Pattern Name | Syntax Template | Real-World Weight | Example (`Jane Doe`, `acme.com`) |
|---|---|---|---|
| `first.last` | `{first}.{last}@{domain}` | 65 | `jane.doe@acme.com` |
| `flast` | `{first_initial}{last}@{domain}` | 58 | `jdoe@acme.com` |
| `firstlast` | `{first}{last}@{domain}` | 50 | `janedoe@acme.com` |
| `f.last` | `{first_initial}.{last}@{domain}` | 48 | `j.doe@acme.com` |
| `first` | `{first}@{domain}` | 45 | `jane@acme.com` |
| `first_last` | `{first}_{last}@{domain}` | 38 | `jane_doe@acme.com` |
| `firstl` | `{first}{last_initial}@{domain}` | 33 | `janed@acme.com` |
| `last.first` | `{last}.{first}@{domain}` | 29 | `doe.jane@acme.com` |
| `first-last` | `{first}-{last}@{domain}` | 27 | `jane-doe@acme.com` |
| `last` | `{last}@{domain}` | 23 | `doe@acme.com` |
| `lastfirst` | `{last}{first}@{domain}` | 20 | `doejane@acme.com` |
| `fl` | `{first_initial}{last_initial}@{domain}` | 16 | `jd@acme.com` |

***

### ✨ Key features

- 🧠 **Pattern-Learning Engine**: Detects the exact email formula when given just one verified address from a company domain.
- 🌐 **Instant MX Validation**: Runs asynchronous DNS queries to verify mail exchange records exist before scoring confidence.
- 🔤 **Deep Unicode & Accent Handling**: Strips diacritics and converts non-decomposing Latin characters (`ø`, `æ`, `ß`, `ł`, `đ`, `ı`, `œ`) safely to standard email characters.
- ⚡ **High-Throughput Parallelism**: Concurrency pool processes up to 200 checks concurrently with per-domain DNS caching to avoid redundant queries.
- 🚫 **Role & Free Provider Detection**: Flags generic addresses (`info@`, `sales@`, `support@`) and freemail providers (`gmail.com`, `yahoo.com`, `outlook.com`).
- 📊 **Ranked Alternative Fallbacks**: Provides `allCandidates` as a semicolon-separated list of secondary formats for immediate outreach retry.
- 🛡️ **Zero API Keys Required**: Uses native system DNS resolution without external API subscription dependencies.
- 📁 **Flexible Input Schemas**: Accepts plain comma-delimited strings, pipe-delimited lines, or full JSON structured objects.

***

### 📥 Input parameters

The scraper accepts contact strings, company domains, and configuration flags:

| Field | Type | Default | Description |
|---|---|---|---|
| `people` | Array of strings | `["Tim Cook, apple.com", ...]` | List of people formatted as `Full Name, domain.com`. Pipe or semicolon delimiters also accepted. |
| `domain` | String | `""` | Global fallback company domain applied to any person record without an explicit domain. |
| `knownEmails` | Array of strings | `[]` | Confirmed sample emails formatted as `Full Name, user@domain.com` used to learn the company's pattern. |
| `verifyMx` | Boolean | `true` | Validates that the company domain has active mail exchanger (MX) DNS records. |
| `includeAllCandidates` | Boolean | `true` | Generates all 12 ranked email variations in the `allCandidates` field. |
| `maxConcurrency` | Integer | `50` | Maximum parallel workers executing DNS checks (1 to 200). |
| `maxItems` | Integer | `0` | Optional maximum records to process. Set to `0` for all provided inputs. |
| `proxyConfiguration` | Object | `{ "useApifyProxy": false }` | Optional proxy settings. Defaults to off since DNS is utilized. |

***

### 📋 Extracted data fields

Each output item represents a normalized contact record with predicted email coordinates:

#### 👤 Contact & company coordinates

| Field | Description | Coverage |
|---|---|---|
| `fullName` | Provided full name of the prospect | 🟢 High (100%) |
| `firstName` | Parsed first name token | 🟢 High (98%) |
| `lastName` | Parsed surname token | 🟢 High (95%) |
| `domain` | Normalized target corporate domain | 🟢 High (100%) |
| `company` | Organization name slug inferred from root domain | 🟢 High (100%) |

#### ✉️ Email prediction & confidence metrics

| Field | Description | Coverage |
|---|---|---|
| `email` | Primary predicted business email address | 🟢 High (98%) |
| `pattern` | Identifier of format utilized (e.g., `first.last`, `flast`) | 🟢 High (100%) |
| `confidence` | Numerical certainty score between 0 and 100 | 🟢 High (100%) |
| `confidenceLabel` | Qualitative rating bracket (`high` ≥75, `medium` ≥45, `low` <45) | 🟢 High (100%) |
| `method` | Prediction engine (`pattern-learned` vs `statistical`) | 🟢 High (100%) |

#### 🔍 Mail exchange & candidate alternatives

| Field | Description | Coverage |
|---|---|---|
| `hasMx` | String boolean indicating active mail exchange DNS records | 🟢 High (100%) |
| `mxHost` | Primary responding mail server hostname | 🟢 High (95%) |
| `isFreeProvider` | String boolean indicating personal consumer mail host | 🟢 High (100%) |
| `isRoleBased` | String boolean indicating generic role mailbox | 🟢 High (100%) |
| `allCandidates` | Semicolon-separated string of all 12 ranked alternative formats | 🟢 High (98%) |
| `candidateCount` | Total candidate addresses evaluated | 🟢 High (100%) |
| `scrapedAt` | ISO 8601 generation timestamp | 🟢 High (100%) |

***

### 💡 Example output record

```json
{
  "fullName": "Marc Benioff",
  "firstName": "Marc",
  "lastName": "Benioff",
  "domain": "salesforce.com",
  "company": "salesforce",
  "email": "mbenioff@salesforce.com",
  "pattern": "flast",
  "confidence": "92",
  "confidenceLabel": "high",
  "method": "pattern-learned",
  "hasMx": "true",
  "mxHost": "mx1.salesforce.com",
  "isFreeProvider": "false",
  "isRoleBased": "false",
  "allCandidates": "mbenioff@salesforce.com; marc.benioff@salesforce.com; marcbenioff@salesforce.com; m.benioff@salesforce.com; marc@salesforce.com",
  "candidateCount": "12",
  "scrapedAt": "2026-11-10T16:30:00.000Z"
}
```

***

### 🛠️ Step-by-step usage guide

1. **Format Input Contacts**: Create a list of names and domains in the format `First Last, domain.com` (e.g., `Satya Nadella, microsoft.com`).
2. **Add Known Samples (Recommended)**: If you know one valid address for key companies, add them to `knownEmails` (e.g., `Amy Hood, ahood@microsoft.com`) to unlock 92% confidence for all contacts at that company.
3. **Verify Settings**: Keep `verifyMx` enabled to verify domain deliverability.
4. **Execute Run**: Start the actor. Results populate within seconds.
5. **Download Output**: Export records as CSV, Excel, or JSON for immediate import into your cold email automation tool or CRM.

***

### 💼 End-to-End Prospecting Workflow Example

```
1. Sourcing Names & Companies
   ├── Scrape LinkedIn / Conference Attendees / Crunchbase
   └── Result: "Satya Nadella, microsoft.com", "Sundar Pichai, google.com"
        │
2. Email Pattern Finder (This Actor)
   ├── Input names + domains + optional known emails
   ├── Fast parallel MX lookup + pattern prediction
   └── Output: Structured JSON / CSV with predicted emails & ranked alternatives
        │
3. Optional Mailbox Verification
   ├── Run highest-priority leads through dedicated mailbox tester
   └── In case of bounce, immediately failover to second candidate in allCandidates
        │
4. Outbound Automation
   └── Push directly into Lemlist / Instantly / HubSpot / Outreach
```

***

### 💻 Integration Examples

#### Python with Apify Client

```python
from apify_client import ApifyClient

client = ApifyClient("YOUR_APIFY_TOKEN")

run_input = {
    "people": [
        "Jensen Huang, nvidia.com",
        "Colette Kress, nvidia.com",
        "Michael Dell, dell.com"
    ],
    "knownEmails": [
        "Ian Buck, ibuck@nvidia.com"
    ],
    "verifyMx": True
}

run = client.actor("haketa/email-pattern-finder").call(run_input=run_input)

for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(f"{item['fullName']} -> {item['email']} ({item['confidence']}% [{item['confidenceLabel']}])")
```

#### Node.js with Apify Client

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

const client = new ApifyClient({
    token: 'YOUR_APIFY_TOKEN',
});

const input = {
    people: [
        'Jane Doe, stripe.com',
        'John Smith, stripe.com'
    ],
    domain: 'stripe.com',
    knownEmails: ['Patrick Collison, patrick@stripe.com'],
};

const run = await client.actor('haketa/email-pattern-finder').call(input);
const { items } = await client.dataset(run.defaultDatasetId).listItems();

items.forEach((r) => {
    console.log(`${r.fullName} | Email: ${r.email} | Pattern: ${r.pattern} | Conf: ${r.confidence}%`);
});
```

#### cURL / REST API

```bash
curl "https://api.apify.com/v2/acts/haketa~email-pattern-finder/runs" \
  -X POST \
  -H "Authorization: Bearer YOUR_APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "people": ["Sundar Pichai, google.com", "Ruth Porat, google.com"],
    "verifyMx": true
  }'
```

***

### ⚡ Automated CRM Sync & Webhook Architecture

Integrate generated business emails directly into outbound marketing automation platforms:

1. **Trigger via Webhook**: Configure your form handler, Apollo list export, or Google Sheet script to send contact names to the actor via the Apify Run API.
2. **Real-time Processing**: DNS MX lookups and pattern learning execute within milliseconds.
3. **Downstream Delivery**: Set an Apify run-succeeded webhook to forward completed records to:
   - **Zapier / Make**: Stream parsed contacts directly into HubSpot, Salesforce, or Airtable.
   - **Lemlist / Instantly / Smartlead**: Automatically launch personalized outbound sequences for contacts with `confidenceLabel: "high"`.
   - **Internal Data Warehouses**: Ingest JSON records straight into PostgreSQL, Snowflake, or BigQuery.

***

### 🛡️ Error Handling, Resiliency & Graceful Degradation

Enterprise contact rosters frequently include noisy or incomplete records. The actor handles edge cases cleanly without aborting execution:

- **Unparseable Single Names**: If an input only contains a single word (e.g., `"Madonna, artist.com"`), the actor tags the record with `pattern: "unparseable-name"` and `confidence: "0"` rather than throwing an exception.
- **Missing Domains**: If a contact is submitted without a company domain and no global fallback domain is set, `pattern: "missing-domain"` is returned.
- **Free & Consumer Domains**: Contacts at consumer email providers (Gmail, Outlook, Yahoo) are tagged with `isFreeProvider: "true"`, preventing incorrect business pattern assumptions.
- **Dead or Suspended Domains**: Domains lacking DNS MX records have `hasMx: "false"`, with confidence scores lowered to reflect non-deliverability.

***

### 🎯 Best Practices for High Deliverability

1. **Leverage Pattern Learning**: Providing even a single confirmed sample address elevates precision from statistical heuristic to confirmed architectural truth.
2. **Segment by Confidence Bracket**:
   - `high` (≥75%): Ready for targeted account executive outbound.
   - `medium` (45–74%): Suitable for automated marketing newsletter sequences with fallback alternatives.
   - `low` (<45%): Typically indicates domains lacking valid MX mail servers or unparseable names.
3. **Utilize `allCandidates` on Bounce**: If an email provider uses non-standard patterns, retain the `allCandidates` string to automatically retry the secondary format (`firstlast` or `f.last`).
4. **Domain MX Caching**: The actor automatically memoizes DNS MX lookups across multiple contacts at the same company, ensuring high execution speeds even across 10,000+ person datasets.

***

### ❓ Frequently Asked Questions (FAQ)

#### Does this actor send ping emails or connect to mailboxes?

No. The actor resolves DNS mail exchanger (MX) records and computes mathematical pattern distributions. It does not initiate SMTP handshakes or send test messages, preventing server blacklisting and ensuring 100% compliance.

#### How accurate are the predicted emails?

When provided with a known sample in `knownEmails`, accuracy reaches ~92% across corporate domains. In statistical mode without samples, the top ranked candidates reflect the majority of enterprise naming conventions (`first.last` and `flast` account for over 70% of modern B2B email architecture).

#### How fast does the actor run on large lists?

Because DNS lookups are highly parallelized and memoized, lists of 1,000 contacts typically process in 5 to 15 seconds.

#### Can it handle names with special characters and accents?

Yes. International characters are automatically transliterated into valid email ASCII equivalents (e.g., `Björn` → `bjorn`, `François` → `francois`).

#### What happens if a domain does not have mail servers?

If a company domain has no active MX records (meaning it cannot receive email), the `hasMx` field is set to `false` and the confidence score is automatically downgraded to near zero.

#### What export formats are supported?

You can export results in JSON, CSV, Microsoft Excel (XLSX), XML, or access them programmatically via the Apify API.

#### What if I have contacts working at the same company?

You can specify the company domain once in the `domain` input field, and list only names in `people`. Any contact without a domain will automatically inherit the global domain.

#### Can I run 10,000+ contacts in a single run?

Yes. The actor processes items concurrently in memory with low CPU and memory footprints. Running 10,000 lookups typically requires less than 256 MB RAM and completes in under two minutes.

***

### 🔗 Related B2B Lead Generation Scrapers

Combine this actor with complementary data extraction tools to build an end-to-end prospecting engine:

- [**Bulk Email Verifier**](https://apify.com/haketa/bulk-email-verifier): Validate mailbox deliverability, catch-all configurations, and syntax health.
- [**Email & Contact Extractor**](https://apify.com/haketa/email-extractor): Scrape emails, telephone numbers, and social links directly from company websites.
- [**Bulk Company Name to Domain Finder**](https://apify.com/haketa/bulk-company-domain): Resolve raw company brand names to official corporate domain URLs.
- [**RemoteOK Jobs Scraper**](https://apify.com/haketa/remoteok-scraper): Extract remote job openings and target company hiring trends.

***

***

### 📋 Changelog

#### Version 1.2 (2026-11)

- **High-Volume list scaling**: Unlocked seamless processing for 1,000+ contact lists with automated batch concurrency.
- **Deep Unicode transliteration**: Expanded support for non-decomposing European characters and compound surnames.
- **Refined MX caching**: Domain-level memoization reduces DNS network overhead by 80% on large enterprise company lists.
- **Enhanced pattern ranking**: Updated pattern weights based on latest enterprise mail server conventions.

#### Version 1.1

- Added `knownEmails` pattern reverse-engineering engine.
- Added role-based and freemail provider classification.

#### Version 1.0

- Initial release with 12-pattern statistical engine and asynchronous DNS MX verification.

# Changelog

This Actor's version history is a separate document: https://apify.com/haketa/email-pattern-finder/changelog.md

# Actor input Schema

## `people` (type: `array`):

One person per line. Use the form `Full Name, company.com` (e.g. `Jane Doe, acme.com`). If every person is at the same company, you can drop the domain here and set it once in **Company domain** below. Leave this empty to run a quick demo and see exactly what the output looks like.

## `domain` (type: `string`):

A single company domain applied to every person who has no domain on their own line. Handy when your whole list works at one company — e.g. `acme.com`.

## `knownEmails` (type: `array`):

The most powerful option. Give one real, confirmed address per company as `Full Name, their.email@company.com` (e.g. `John Smith, jsmith@acme.com`). The Actor reverse-engineers that company's exact format and applies it to everyone else at the same domain with high confidence.

## `verifyMx` (type: `boolean`):

Check that each company domain actually has mail servers (MX records). Addresses on domains that cannot receive mail are flagged and scored near zero.

## `includeAllCandidates` (type: `boolean`):

Also output every alternative email format (ranked), not just the single most likely one. Useful when you want to try a few variations.

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

How many people to process at the same time. Higher is faster. The default works well for most lists.

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

Apify Proxy. Off by default — this Actor runs over DNS and does not need a proxy.

## Actor input object example

```json
{
  "people": [
    "Tim Cook, apple.com",
    "Satya Nadella, microsoft.com",
    "Sundar Pichai, google.com",
    "Marc Benioff, salesforce.com"
  ],
  "knownEmails": [],
  "verifyMx": true,
  "includeAllCandidates": true,
  "maxConcurrency": 50,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

## `fullName` (type: `string`):

Person's name as provided

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

Parsed first name

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

Parsed last name

## `domain` (type: `string`):

Company domain

## `company` (type: `string`):

Company slug from domain

## `email` (type: `string`):

Most likely email address

## `pattern` (type: `string`):

Format used (first.last, flast…)

## `confidence` (type: `string`):

Confidence score 0-100

## `confidenceLabel` (type: `string`):

high / medium / low

## `method` (type: `string`):

pattern-learned / statistical

## `hasMx` (type: `string`):

Domain can receive mail

## `mxHost` (type: `string`):

Primary mail server

## `isFreeProvider` (type: `string`):

gmail/yahoo/outlook…

## `isRoleBased` (type: `string`):

Role address (info@…)

## `allCandidates` (type: `string`):

Ranked alternative emails

## `candidateCount` (type: `string`):

Number of candidates

## `scrapedAt` (type: `string`):

Timestamp

# 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 = {
    "people": [
        "Tim Cook, apple.com",
        "Satya Nadella, microsoft.com",
        "Sundar Pichai, google.com",
        "Marc Benioff, salesforce.com"
    ],
    "knownEmails": [],
    "maxConcurrency": 50
};

// Run the Actor and wait for it to finish
const run = await client.actor("haketa/email-pattern-finder").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 = {
    "people": [
        "Tim Cook, apple.com",
        "Satya Nadella, microsoft.com",
        "Sundar Pichai, google.com",
        "Marc Benioff, salesforce.com",
    ],
    "knownEmails": [],
    "maxConcurrency": 50,
}

# Run the Actor and wait for it to finish
run = client.actor("haketa/email-pattern-finder").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 '{
  "people": [
    "Tim Cook, apple.com",
    "Satya Nadella, microsoft.com",
    "Sundar Pichai, google.com",
    "Marc Benioff, salesforce.com"
  ],
  "knownEmails": [],
  "maxConcurrency": 50
}' |
apify call haketa/email-pattern-finder --silent --output-dataset

```

## MCP server setup

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

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/ldoCfBuQqNLFrjrbr/builds/8Fip3qrPiuC5SyGXp/openapi.json
