# Email Format Finder: Company Email Pattern Lookup (`rod_analytics/email-format-finder`) Actor

Find the email format of a company (first.last, flast, first...) from the addresses it publishes on its own website. Per domain: pattern, 0-100 confidence, example emails with source URL, MX and mail provider. Domains with no clear pattern are free. $0.01 per pattern found.

- **URL**: https://apify.com/rod_analytics/email-format-finder.md
- **Developed by:** [Rod Services](https://apify.com/rod_analytics) (community)
- **Categories:** Lead generation, Marketing
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per event

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 format finder and company email pattern lookup**: find how a company writes its work emails (first.last, flast, first...) from the addresses it publishes on its own website.
Per domain you get the format, a 0-100 confidence, example emails with the page they came from, MX and mail provider. **$0.01 per domain with a pattern. No pattern, no charge. No API key.**

### What you get

- **The email pattern** such as `{first}.{last}`, `{f}{last}` or `{first}`, in the same notation Hunter uses, plus a plain example like `jane.doe@acme.com`.
- **A confidence from 0 to 100** and the number of published addresses that support the pattern. A pattern is only reported at 50 or more.
- **Evidence you can check.** Up to 10 example addresses per domain, each with the exact page of the company website where it is shown.
- **Mail setup of the domain.** MX hosts and the provider (Google Workspace, Microsoft 365, Proofpoint, Zoho and others), plus a hint when a secure email gateway makes mailbox checks unreliable.
- **Other formats on the site**, so a company with two conventions is visible.
- **One row per domain**, also for domains without a result. Those rows are free and say why.
- **Dataset input.** Feed the output of a Google Maps, Apollo or directory scraper with a website or domain field.

### How it works

1. The Actor opens the homepage, reads `robots.txt` and the sitemap, and picks the pages where companies show contacts: team, people, press, contact, impressum, about and privacy pages. Menus in many languages are understood (Kontakt, Équipe, Komanda and more).
2. It reads every email address on those pages together with the person name printed next to it. Role addresses such as info@ and sales@ are ignored.
3. A pattern counts as strong evidence when the name on the page produces the address, for example "Anna Meier" next to `anna.meier@acme.com`. An address with no name next to it counts less, based on its shape only.
4. Confidence rises with more supporting addresses and falls when the site shows conflicting formats.
5. DNS gives the MX hosts and the mail provider. No mail server is contacted.

Sources are limited to **emails the company itself publishes on its own website**. The Actor does not mine GitHub commits, does not visit LinkedIn or any social network, does not log in, and does not bypass bot protection. `robots.txt` is always respected.

### Quick start

1. Open the **Input** tab.
2. Paste company domains into **Company domains or websites**, one per line. `acme.com` is fine.
3. Or pick a dataset in **Dataset with websites or domains**, for example from a Google Maps Scraper run.
4. Press **Start**. The prefilled example with 3 domains finishes in about a minute.
5. Open the **Output** tab. The **Overview** view shows one pattern per domain. The **Example emails** view shows each supporting address with its source page.

### Input example

```json
{
    "domains": ["acme.com", "https://www.example.org"],
    "maxExamples": 3,
    "maxPagesPerDomain": 8
}
```

| Field | Default | Description |
| --- | --- | --- |
| `domains` | | Company domains or websites. Duplicates and www variants are merged. Free mail domains such as gmail.com are rejected. |
| `datasetId` | | Dataset of another run with a website or domain field. Dataset ID or the dataset picker. |
| `domainField` | auto | Field with the website or domain in that dataset. Dot paths work. |
| `maxExamples` | `3` | Example addresses with source page per domain, 1 to 10. |
| `maxPagesPerDomain` | `8` | Homepage plus best matching pages, 1 to 30. The crawl stops early when the evidence is clear. Same price for any number. |
| `hunterApiKey` | | Optional. Your own Hunter.io key adds Hunter's format as one more vote and reports its accept-all flag. Uses at most one credit of your plan per domain. |
| `suppressionList` | | Emails, domains or their SHA-256 hashes. Matching addresses never appear in the output. |
| `maxConcurrency` | `10` | Domains read in parallel. |
| `timeoutSecs` | `15` | Timeout per page. |

### Output sample

```json
{
    "domain": "acme.com",
    "inputUrl": "acme.com",
    "status": "pattern-found",
    "pattern": "{first}.{last}",
    "patternId": "first.last",
    "formatExample": "jane.doe@acme.com",
    "confidence": 87,
    "supportingExamples": 7,
    "evidenceSources": ["website"],
    "alternatives": [{ "pattern": "{f}.{last}", "patternId": "f.last", "confidence": 9, "supportingExamples": 1 }],
    "examples": [
        { "email": "anna.meier@acme.com", "sourceUrl": "https://acme.com/team", "evidence": "name-on-page" },
        { "email": "peter.mueller@acme.com", "sourceUrl": "https://acme.com/team", "evidence": "name-on-page" },
        { "email": "greta.lindqvist@acme.com", "sourceUrl": "https://acme.com/about", "evidence": "name-on-page" }
    ],
    "emailDomain": "acme.com",
    "mx": { "found": true, "hosts": ["aspmx.l.google.com"], "provider": "Google Workspace", "note": null },
    "catchAll": null,
    "catchAllSource": null,
    "hunterPattern": null,
    "emailsSeen": { "personal": 8, "role": 2, "otherDomain": 3, "suppressed": 0 },
    "pagesCrawled": 5,
    "error": false,
    "scrapedAt": "2026-10-07T09:30:00.000Z"
}
```

A domain with no clear pattern returns a free row:

```json
{
    "domain": "small-shop.com",
    "status": "no-pattern",
    "error": true,
    "errorCode": "no-named-emails",
    "message": "No personal email addresses are published on the 5 page(s) read. Only 1 role address(es) such as info@ were found.",
    "howToFix": "Raise \"Pages per domain\", or add your own Hunter API key to get the format from Hunter. If you know the person, Work Email Finder tries the likely addresses."
}
```

### Data fields

| Field | Description |
| --- | --- |
| `status` | `pattern-found` (charged), `no-pattern` or `failed` (free). |
| `pattern`, `patternId` | The format as `{first}.{last}` and as `first.last`. Tokens: first, last, f (first initial), l (last initial). |
| `formatExample` | The format applied to a made-up name. |
| `confidence` | 0 to 100. Found rows have 50 or more. |
| `supportingExamples` | How many published addresses fit the format. |
| `alternatives` | Other formats seen on the site, with confidence. |
| `examples` | `{ email, sourceUrl, evidence }`. `name-on-page`: a person name next to the address produces it. `structure-only`: the shape of the address fits. |
| `mx` | `{ found, hosts, provider, note }` from DNS. |
| `catchAll` | `true` or `false` only when your Hunter key reports it, otherwise `null`. The Actor does not probe mail servers. |
| `emailsSeen` | Counts of personal, role, other-domain and suppressed addresses seen. |
| `errorCode` | `no-named-emails`, `pattern-not-clear`, `robots-blocked`, `site-unreachable`, `bot-protection`, `http-error`, `invalid-domain`, `webmail-domain`. |

### Pricing

Pay per event. You pay for domains with a pattern, not for compute time or pages. Discounts apply automatically on paid Apify plans.

| Event | Free plan | Bronze | Silver | Gold |
| --- | --- | --- | --- | --- |
| Domain with a pattern found, per 1,000 | $10.00 | $9.00 | $8.00 | $7.00 |
| Run start, per run | $0.001 | $0.001 | $0.001 | $0.001 |

- **Domains with no pattern are free**: no named emails, unclear format, site down, blocked by robots.txt or bot protection, invalid input.
- Set **Maximum cost per run** in the run options to cap spend. The Actor stops when the limit is reached.
- The Apify free plan's monthly credit covers hundreds of domains.

### Use it from code, Make, Zapier or AI agents

Run it through the Apify API, the JavaScript and Python clients, schedules, webhooks, or integrations such as Make, Zapier, n8n and Google Sheets. AI agents can call it through the Apify MCP server at `mcp.apify.com`.

```bash
curl -X POST "https://api.apify.com/v2/acts/rod_analytics~email-format-finder/run-sync-get-dataset-items" \
  -H "Authorization: Bearer <YOUR_APIFY_TOKEN>" -H "Content-Type: application/json" \
  -d '{"domains": ["acme.com"]}'
```

To find the address of one named person, use [Work Email Finder: Find Email by Name and Domain](https://apify.com/rod_analytics/work-email-finder). It uses the same pattern engine.

### GDPR, ePrivacy and responsible use

This Actor is built for **B2B use**:

- **Only company-published addresses.** Example emails are work addresses that the company itself shows on its public website, each with its source page. Free mail providers (gmail.com, outlook.com, gmx.de and others) and addresses on other domains are dropped.
- **No guessing of people.** The Actor finds the format of a domain. It does not generate or verify addresses of individuals. Work Email Finder does that, for names you give it.
- **No sources outside the company website.** No GitHub commit mining, no LinkedIn or other social network, no logins, no CAPTCHA or bot bypass. `robots.txt` is always respected, at most 2 parallel requests per site.
- **No sensitive inference.** Names are only compared with the local part of an address. Nothing about gender, origin or other traits is derived.
- **Nothing is stored on our side.** Results go only to your own dataset. The log holds counts, never addresses.
- **Suppression list.** Pass emails, domains or SHA-256 hashes in `suppressionList`. Matching addresses are dropped before anything is computed.
- **You are the controller.** If you keep or use the example addresses, you decide the purpose and the means, so you are the data controller under the GDPR. You need a lawful basis, for example a documented legitimate interest for B2B contact, and you must give the people concerned a privacy notice (Art. 14) and honour objections. Check national marketing rules before you send anything. **Germany requires prior consent for advertising emails, also B2B (UWG section 7).** France and Lithuania allow B2B outreach with an easy opt-out when it relates to the person's job.

This is not legal advice. Check your use case with your data protection officer.

### FAQ

**How accurate is the pattern?** The confidence is a heuristic from the evidence on the site, not a guarantee that a given mailbox exists. 70 or more with several name-backed examples is reliable in practice. Companies sometimes use different formats for different teams, which shows in `alternatives`.

**Does it verify that an address exists?** No. It finds the format. To check a single address, use Work Email Finder or Email Validator & Verifier.

**Why is my domain "no-pattern"?** Many small sites show only info@. Some sites show names without addresses. Raise **Pages per domain**, or add your own Hunter key.

**Does it work on JavaScript-only websites?** It reads server HTML without a browser. Sites that load their team list with JavaScript may return fewer pages.

**Some sites fail with 403.** Some large sites block datacenter IPs. Those rows are free. The Actor does not bypass bot protection.

**What happens if my input is wrong?** The run ends **SUCCEEDED** with one free help row: `error`, `errorCode`, `message` and `howToFix`. Only the start fee is charged. Codes: `no-valid-domains`, `no-domains-in-dataset`, `dataset-unreadable` and `bad-hunter-key`.

**Is the Hunter key safe?** It is sent only to Hunter in a header, from your run. It is never logged or stored by this Actor, and the field is a secret input.

**Found a bug or need a custom field?** Open an issue on the **Issues** tab. Replies usually come within a day.

### Related Actors

| Actor | What it does |
| --- | --- |
| [Work Email Finder: Find Email by Name and Domain](https://apify.com/rod_analytics/work-email-finder) | Find a work email from a name and a company domain |
| [Website Content Crawler to Markdown for RAG & LLMs](https://apify.com/rod_analytics/website-to-markdown) | Crawl a site and get clean Markdown for RAG and LLMs |
| [PDF to Markdown & Text Extractor with OCR](https://apify.com/rod_analytics/doc-to-markdown) | Turn PDF, DOCX and scans into Markdown or text |
| [SEO Audit Tool: Site Crawler, Broken Links & Score](https://apify.com/rod_analytics/seo-site-audit) | Crawl a site for broken links and SEO issues |
| [PageSpeed Insights & Lighthouse Bulk Checker](https://apify.com/rod_analytics/lighthouse-audit) | Core Web Vitals and Lighthouse scores for many URLs |
| [Tech Stack Detector: Wappalyzer & BuiltWith Alternative](https://apify.com/rod_analytics/tech-stack-detector) | See which CMS, analytics and frameworks a site uses |
| [Bulk Domain Lookup: DNS, WHOIS, SPF, DMARC & SSL](https://apify.com/rod_analytics/domain-security-audit) | DNS, mail security and SSL checks for domain lists |
| [Speech to Text: Audio, Video & Podcast Transcriber](https://apify.com/rod_analytics/media-transcriber) | Transcribe audio, video and podcasts |
| [Email Validator & Verifier: Bulk MX & Disposable Check](https://apify.com/rod_analytics/bulk-email-verifier) | Clean email lists before you send |
| [Website Contact Scraper: Emails, Phones & Social Links](https://apify.com/rod_analytics/company-contact-extractor) | Company emails, phones and social links from websites |
| [VIES VAT Checker & EU Company Registry Lookup](https://apify.com/rod_analytics/eu-company-lookup) | Validate EU VAT numbers and look up companies |
| [Companies House Scraper: UK Company Search, No API Key](https://apify.com/rod_analytics/uk-companies-house) | UK company profiles, officers and filings |
| [EU TED Tenders Scraper & Alerts: Public Procurement](https://apify.com/rod_analytics/ted-tenders) | EU public tenders with daily alerts |
| [Greenhouse, Lever & Ashby Job Scraper: 8 ATS in One Feed](https://apify.com/rod_analytics/multi-ats-jobs-api) | Jobs from 8 ATS platforms in one feed |
| [GitHub Scraper: Repo Stats, Stars, Trending & Search](https://apify.com/rod_analytics/github-repo-stats) | Stars, activity and trending GitHub repos |
| [Hacker News Scraper](https://apify.com/rod_analytics/hackernews-scraper) | Stories, comments and Who is hiring threads from Hacker News |

# Changelog

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

# Actor input Schema

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

One per line. Bare domains like acme.com and full URLs both work. Duplicates are removed. A domain with a pattern found is billed once. No pattern, no charge.

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

Optional. Pick the dataset of a finished run, for example Google Maps Scraper, Apollo or a directory scraper, and every company website in it is analysed. You can also paste a dataset ID.

## `domainField` (type: `string`):

Field that holds the company website or domain in the dataset rows. Leave empty to try website, websiteUrl, companyWebsite, domain and url. Google Maps place links and social profiles are skipped. Dot paths like company.website work.

## `maxExamples` (type: `integer`):

How many published example addresses, each with the page it was found on, to return as evidence. These are work addresses that the company itself shows on its website.

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

Homepage plus the best matching team, contact, press, impressum and about pages. The crawl stops early when the evidence is clear. The price does not depend on this number.

## `hunterApiKey` (type: `string`):

Optional. Your own key adds Hunter's format for the domain as one more vote and reports Hunter's accept-all flag. It uses at most one credit of your Hunter plan per domain. The key is only used in your run and never logged or stored by this Actor.

## `suppressionList` (type: `array`):

Email addresses, domains or SHA-256 hashes of them (of the lower-case address or domain). Matching addresses are dropped before anything is computed and never appear in the output.

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

How many websites are read at the same time.

## `timeoutSecs` (type: `integer`):

Maximum wait for one page. A whole domain is capped at 6x this value (at least 60 s).

## Actor input object example

```json
{
  "domains": [
    "sorainen.com",
    "tlu.ee",
    "ut.ee"
  ],
  "maxExamples": 3,
  "maxPagesPerDomain": 8,
  "maxConcurrency": 10,
  "timeoutSecs": 15
}
```

# Actor output Schema

## `overview` (type: `string`):

No description

## `examples` (type: `string`):

No description

## `noResult` (type: `string`):

No description

## `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": [
        "sorainen.com",
        "tlu.ee",
        "ut.ee"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("rod_analytics/email-format-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 = { "domains": [
        "sorainen.com",
        "tlu.ee",
        "ut.ee",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("rod_analytics/email-format-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 '{
  "domains": [
    "sorainen.com",
    "tlu.ee",
    "ut.ee"
  ]
}' |
apify call rod_analytics/email-format-finder --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,rod_analytics/email-format-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/mQXrFEGvPEJDZFWAJ/builds/vgE0ZpGXh9fHbx4W4/openapi.json
