Email Pattern Finder - Work Email Format by Name + Domain
Pricing
from $1.40 / 1,000 person processeds
Email Pattern Finder - Work Email Format by Name + Domain
Work email finder: give a person's name and a company domain and get ranked address guesses (first.last@, flast@, first@...). Crawls the company site to detect its real email format and pattern, and MX-checks the domain + provider. Confidence-scored, no API key, pay-per-result.
Pricing
from $1.40 / 1,000 person processeds
Rating
0.0
(0)
Developer
Flash Scrape
Maintained by CommunityActor stats
0
Bookmarked
3
Total users
0
Monthly active users
13 hours ago
Last modified
Categories
Share
Work Email Finder - Email Format & Pattern by Name + Domain
Email pattern finder for any company: find the email address pattern a company uses and turn plain names into ranked work-email guesses. Give it a company domain and a list of full names; it reads a few public pages of the company's own site to observe its real address format, returns each person's most likely addresses (first.last@, flast@, first@…) scored by evidence and pattern frequency, and runs a DNS check that the domain can actually receive mail and which provider runs it (Google Workspace vs Microsoft 365). It's the natural front end of a find → verify → enrich prospecting flow — no API key, no proxies, no per-seat email-finder subscription, just pay-per-result.
What it does
- Detects the company's actual email pattern from its website (
crawlForPattern, on by default): reads up to 9 public pages (home, about, team, people, staff, contact) for real same-domain addresses. If one matches an input name, or has a personal shape (jane.diaz@), that pattern is promoted to 98 confidence and flaggedobservedfor every name. Role aliases (info@,sales@,customer.service@) never count as evidence. - Generates up to 12 ranked email candidates per person from a library of common corporate patterns:
first.last,flast,firstlast,f.last,first,first_last,firstl,first-last,lastfirst,last.first,lfirst,last. - Scores each candidate 0–99 — 98 means observed on the company's own site; below that, the score is the pattern's real-world frequency prior (
first.last= 95 …last= 35) — and surfaces the singlebest_guessper person. - Checks the domain's MX records via DNS-over-HTTPS to confirm the domain can receive mail at all — if no mail server exists, every candidate's confidence is cut to 60% of its base, so dead domains can't inflate your list. If the check itself cannot complete, the row says so (
mx_status: lookup_failed,mx_found: null) instead of pretending the domain is dead. - Detects the email provider from the MX host (Google Workspace, Microsoft 365, Proofpoint, Zoho, or other) — useful both as a deliverability signal and as a firmographic data point.
- Normalizes names: strips accents (
José→jose), drops titles and credentials (Dr. Jane Doe, PhD→jane.doe@) and parenthesised notes, skips duplicates, and handles single-name inputs (those only get thefirst@pattern rather than fabricated surnames). - Accepts messy domain input —
acme.com,https://www.acme.com/about,acme.com:443, evenjane@acme.com— it all resolves to the bare domain. - Lets you restrict generation to specific pattern IDs when you already know the company's format and just want it applied to a batch of names.
Everything is read-only and privacy-respecting: the actor builds address strings from the names you provide, performs an MX lookup on the domain, and fetches at most nine public pages of the company's website (no proxies, no login). It never sends an email and never probes individual mailboxes.
Use cases
- Sales prospecting — you found 20 decision-makers on LinkedIn at a target account but no contact info. Paste the names + domain, get ranked address guesses in seconds instead of paying per-credit on Hunter or Apollo.
- Recruiting outreach — reach engineers and managers directly at their work address instead of fighting the InMail queue.
- Lead-list completion for agencies — you're delivering a lead list on Fiverr/Upwork and half the rows have a name and company but no email; batch-fill the gap and mark each row with its confidence score.
- CRM enrichment — export contacts missing an email, group them by company domain, run each group through the finder, and re-import the
best_guesscolumn. - Pattern discovery — confirm one address for any employee (from a signature, a press release), see which pattern it matches, then re-run the actor with that pattern locked in via
patternsfor the whole department.
Input
| Field | Type | Default | Description |
|---|---|---|---|
domain | string | (required) | The company's email domain, e.g. acme.com. A URL, port or pasted address is reduced to the bare domain. One domain per run. |
names | array | (required) | People to generate addresses for, one full name per line (e.g. Jane Doe). Titles/credentials stripped, duplicates skipped. Each usable name is one billed row. |
verifyMx | boolean | true | Look up the domain's MX records (DNS-over-HTTPS) to confirm it can receive mail and detect the provider. No mailbox probing, no email sent. |
crawlForPattern | boolean | true | Read up to 9 public pages of the company site for real same-domain addresses and infer the company's actual pattern from them. |
maxCandidatesPerPerson | integer | 6 | How many ranked addresses to return per person (1–12). The observed pattern, when there is one, is always in the list. |
patterns | array | (empty) | Optional: only generate these pattern ids (see the list above). Unknown ids are ignored and named in the status message. Leave empty for all 12. |
Example input:
{"domain": "stripe.com","names": ["Patrick Collison", "Jane Doe"],"verifyMx": true,"crawlForPattern": true,"maxCandidatesPerPerson": 6}
Output
One dataset row per person:
| Field | Description |
|---|---|
name / first_name / last_name | The input name and its parsed (lower-cased, accent-free) parts |
domain | Normalized company domain |
mx_found | true = mail servers found, false = the domain has no MX record, null = check skipped (verifyMx: false) or could not complete — see mx_status |
email_provider | Detected provider from MX (e.g. Google Workspace, Microsoft 365) |
best_guess | The single most likely address |
best_guess_confidence | Its 0–99 score (98 = pattern observed on the company site) |
pattern_source | observed_name_match (an input name's real address was found), observed_structure (a personal address of that shape was found), or heuristic |
observed_pattern | The pattern id the site evidence points to, or null |
evidence_email | The real address that proved the pattern, or null |
observed_emails | Up to 10 same-domain addresses found on the site (raw, may include role aliases) |
candidates | All ranked guesses, each with email, pattern, confidence (and evidence: "observed" on the promoted one) |
best_guess_pattern | The pattern id of best_guess |
mx_status | found, none, lookup_failed or skipped |
pages_crawled | How many company pages were actually read (0 = the site could not be read; null = crawl off) |
Example row:
{"name": "Jane Doe","first_name": "jane","last_name": "doe","domain": "stripe.com","mx_found": true,"email_provider": "Google Workspace","best_guess": "jane.doe@stripe.com","best_guess_confidence": 98,"pattern_source": "observed_structure","observed_pattern": "first.last","evidence_email": "jane.diaz@stripe.com","observed_emails": ["jane.diaz@stripe.com"],"candidates": [{ "email": "jane.doe@stripe.com", "pattern": "first.last", "confidence": 98, "evidence": "observed" },{ "email": "jdoe@stripe.com", "pattern": "flast", "confidence": 88 },{ "email": "janedoe@stripe.com", "pattern": "firstlast", "confidence": 78 },{ "email": "j.doe@stripe.com", "pattern": "f.last", "confidence": 72 },{ "email": "jane@stripe.com", "pattern": "first", "confidence": 65 },{ "email": "jane_doe@stripe.com", "pattern": "first_last", "confidence": 60 }],"best_guess_pattern": "first.last","mx_status": "found","pages_crawled": 4}
Export to CSV, Excel, or JSON from the Apify Console or via API.
Example output
A sample with the site crawl off (crawlForPattern: false), so every score is the heuristic prior:
| name | domain | best_guess | best_guess_confidence | mx_found |
|---|---|---|---|---|
| Patrick Collison | stripe.com | patrick.collison@stripe.com | 95 | true |
| John Smith | stripe.com | john.smith@stripe.com | 95 | true |
| Jane Doe | stripe.com | jane.doe@stripe.com | 95 | true |
| Maria Garcia | stripe.com | maria.garcia@stripe.com | 95 | true |
How the confidence score works
- 98 — the pattern was observed on the company's own website (
pattern_sourcetells you whether an input name's real address was found, or a personal address of that shape). Strongest signal the actor can give without probing mailboxes. - 95 … 35 — the pattern's frequency prior: how common that format is across corporate mailboxes (
first.last95,flast88,firstlast78,f.last72,first65,first_last60,firstl52,first-last48,lastfirst/last.first44,lfirst40,last35). - × 0.6 (floor 5) when the domain has no MX record (
mx_status: none) — it cannot receive mail at that apex. This applies to the observed pattern too (98 → 58), which therefore still ranks first and keeps itsevidence: "observed"flag. - Unchanged when the MX check could not complete (
mx_status: lookup_failed) — the actor never turns a DNS outage into "this domain is dead".
Every run comes with a report
Each delivering run also saves a one-page HTML REPORT in the run's key-value store (Output tab → REPORT, or the link in the run's status message): the delivered count, the detected pattern and its evidence, the MX/provider result, the best-guess pattern split and confidence bands, the first 100 rows, and the run's notes. It is a single self-contained HTML file, safe to forward or screenshot. The dataset stays the source of truth.
What the status message and RUN_SUMMARY tell you
- A successful run's status message states exactly how many person rows were delivered (= billed), how the pattern was decided (
observed pattern first.last (evidence …)orheuristic ranking), the mail provider, and every caveat: names skipped or duplicated, a domain with no MX record, an MX check that could not complete, a company site that could not be read (e.g. HTTP 403 from datacenter IPs), a charge-limit trim, or a run-time budget cut. - A zero-row run exits SUCCEEDED (no stack trace) with the real cause — no domain, no names, unknown pattern ids, single-word names with two-part patterns only, or a charge limit that leaves no budget — and always ends with "You were not charged." A failed lookup is never reported as "no results".
- Every run also writes a
RUN_SUMMARYkey-value record (status,delivered,charge_requested/charge_confirmed,billing,cause,domain, name counts,mx_status,email_provider,pattern_source,observed_pattern,evidence_email,pages_crawled,crawl_errors,deadline_hit,budget_trimmed,report_url) for pipelines that want a machine-readable verdict.statusisdelivered,zero_rows,push_failedor — when the run crashed before delivering anything —failedwith the exception incause(the run itself then ends FAILED, and the status message says you were not charged).billingrecords how the rows were billed (pay-per-event, orplatform:<model>when the platform bills per dataset item);charge_confirmedisnullin the latter case rather than a misleading0.
Reliability
- Every network wait (MX lookup, each page read) is bounded by the run's own remaining time with a reserve for delivery, so a short
timeoutSecsstill returns rows instead of a timed-out empty run. - Page bodies are capped at 1 MB and scanned in linear time — one base64-heavy marketing page can no longer stall the run.
- Rows are pushed in bounded chunks before billing; exactly the pushed rows are charged, once. If a later chunk fails, only the rows that landed are billed.
Pricing
Pay-per-result: you're charged only per person row delivered — a fraction of a cent each. Names that produced no address, duplicates and rows trimmed by your charge limit are never billed. No subscription, no monthly credit packs that expire. A free Apify plan is enough to run your first batches and test the output on real accounts before paying anything.
Tips / FAQ
Does it verify that the mailbox actually exists?
No — and that's deliberate. The actor generates pattern-based guesses ranked by site evidence and real-world commonality and verifies the domain (MX lookup), not individual mailboxes. It performs no SMTP handshakes and sends nothing. For mailbox-level checking, pipe the best_guess column into the Bulk Email Verifier.
How accurate are the guesses?
When the company site publishes even one personal address, the observed pattern (98) is right for most colleagues at companies with standardized IT. Without evidence, first.last@ alone covers the largest share of corporate mailboxes, which is why it scores 95. Accuracy is lower at very large enterprises with legacy formats or duplicate-name collisions. The confidence score tells you how much to trust each row — and if you can confirm one real address at the company yourself, lock its pattern via patterns for the whole batch.
pages_crawled is 0 — what happened?
The company site could not be read from the Apify datacenter (typically HTTP 403 from a bot shield, or the site is down); the status message names the response. Ranking then falls back to the heuristic priors. pages_crawled > 0 with pattern_source: heuristic means the pages were read but published no personal address.
What happens with single names or names with accents or titles?
Accents and diacritics are transliterated (René Müller → rene.muller@…); Dr., Prof., PhD, Jr. and parenthesised notes are dropped. Tokens that are both a credential and a real name are kept as names unless written in their credential form: Anh Do → anh.do@, Hon Lam → hon.lam@, but Jane Doe, DO → jane.doe@ and Hon. Jane Doe → jane.doe@. A single-token name (e.g. just Madonna) only generates the first@ pattern — the actor won't invent a surname. Names without Latin letters cannot be built and are skipped without charge.
Why did all my confidences drop for one domain?
The MX check found no mail servers (mx_status: none), so every candidate's score was reduced to 60% of its base (floor 5) and mx_found is false. That usually means the domain can't receive mail at that apex — check whether the company actually uses a different email domain. If mx_found is null with mx_status: lookup_failed, the check itself could not complete and scores were left untouched; re-run to get it.
Can I process people from many different companies in one run?
One run handles one domain with any number of names. For a multi-company list, group your rows by domain and trigger one run per domain via the Apify API — each run is billed only for the people it delivers.
How do I integrate it?
Start runs from the Apify API or SDK, schedule recurring runs with Apify Schedules, and export the dataset as CSV/Excel/JSON or push it onward with Apify integrations (webhooks, Zapier, Make). Read RUN_SUMMARY from the run's key-value store for a machine-readable verdict.
Related actors
- Bulk Email Verifier — the natural next step: verify and score the guessed addresses before you send.
- Company & Domain Enricher — enrich the same domains with company name, socials, and tech stack.
- Phone Number Validator — clean the phone column of the same lead list.
Found a bug or missing a feature? Open an issue on this actor's Issues tab — typical response within 1 business day.
Related Flash Scrape actors
- Multi Job Board Scraper — LinkedIn, Indeed, Glassdoor + 9 more boards, deduplicated, with only-new job alerts
- Local Business Leads Scraper — any category, any city, verified emails, lead scores
- Remote Jobs Aggregator — 10 keyless remote boards in one deduplicated feed
- All Flash Scrape actors — same house rules everywhere: pay per delivered row, honest status messages, only-new monitoring, webhook alerts, and a run report on every run.
More from Flash Scrape
Same publisher, same rules: no API keys, pay per row, filters run before billing.
- Multi Job Board Scraper - LinkedIn, Indeed, Glassdoor and 9 more boards in one deduplicated table
- Local Business Leads Scraper - local businesses in any category and city with MX-verified emails, phones and socials
- Remote Jobs Aggregator - 10 remote job boards in one feed, only-new-jobs monitoring
- Creator Leads Scraper - YouTube, TikTok and Instagram creator emails in one run