Skip to main content
Thirdwatchthirdwatch
Business & local data

Segment Leads by Email Provider: Workspace or Microsoft 365

Split a raw local lead list into Google Workspace, Microsoft 365, Zoho and GoDaddy cohorts using MX provider data from Thirdwatch's lead enrichment actor.

Jul 28, 2026 · 8 min read · 1,882 words
See the scraper →

Thirdwatch's Google Maps Lead Enrichment actor returns an email_mx_provider field on every enriched lead: google, microsoft365, zoho, godaddy or other. That single value splits a raw local list into cohorts that each need a different product angle, a different integration story and a different opener. Pair it with email_is_freemail and you separate paid Workspace tenants from consumer Gmail, which is the difference between an ICP-fit account and a one-person shop.

Why email provider is a targeting signal, not a hygiene check

If you sell a Chrome extension, a Teams app, a calendar tool, a document add-on or anything that installs into a mail and productivity suite, the first question a prospect asks is "does it work with what we already use." You can answer that before you send the first email.

The mail stack a business runs on is published. Every domain that receives mail has MX records, and those records name the provider handling delivery — this is the routing mechanism defined in RFC 5321. Google Workspace tells administrators exactly which MX values to set, and Microsoft 365 publishes its own required record, which always ends in mail.protection.outlook.com. Reading them is a DNS query, not a scrape.

That makes provider a rare thing in local prospecting: a free, honest, non-declared technographic. A business cannot fake it, does not fill it into a form, and does not know you can see it. In our own enrichment runs across small businesses in the US, UK, India and Australia, roughly three out of four readable websites publish at least one email address — and the ordering of providers behind those addresses was consistent, with Google first, Microsoft 365 second, and a long tail of Zoho, GoDaddy and regional hosts after them.

How does this compare to the alternatives?

Three ways to attach a mail provider to a local lead list.

Approach Cost Reliability Setup time Maintenance
DIY: scrape sites, then dig MX each domain Your engineering time Works, but you own the crawler, the email extraction and the resolver caching Days Every site redesign and DNS edge case is yours
Technographic data vendor Annual subscription, seat-based Good on enterprise, thin on plumbers and dental practices Weeks including procurement Vendor refresh cadence, not yours
Thirdwatch Google Maps Lead Enrichment Transparent pay-per-result Finds the business, reads the site, extracts the email and resolves the MX in one run 5 minutes Thirdwatch tracks site and extraction changes

The DIY route is the one most RevOps teams start with and abandon, because the hard part is never the DNS lookup — it is getting a real email address off 100,000 small-business websites in the first place. Technographic vendors solve the opposite problem: they have deep coverage of companies with 200+ employees and almost none of the 8-person local businesses that make up a local territory. The Google Maps Lead Enrichment actor covers exactly that gap, because the email and the MX lookup happen on the same row.

How to segment leads by email provider in 4 steps

How do I authenticate against Apify?

Sign in at apify.com (free tier, no credit card), open Settings, then Integrations, and copy your API token. Every example below reads it from the environment:

export APIFY_TOKEN="apify_api_xxxxxxxxxxxxxxxx"

How do I run an enrichment that returns the MX provider?

The provider field only populates when the DNS check runs, so keep verifyEmailDomains on — it is the default, but set it explicitly so nobody turns it off later. Set onlyWithContact to false on your first pass so you can measure coverage honestly rather than silently dropping the rows that failed.

import os, requests, pandas as pd

ACTOR = "thirdwatch~google-maps-lead-enrichment"
TOKEN = os.environ["APIFY_TOKEN"]

resp = requests.post(
    f"https://api.apify.com/v2/acts/{ACTOR}/run-sync-get-dataset-items",
    params={"token": TOKEN},
    json={
        "queries": [
            "accounting firms Leeds UK",
            "architecture studios Melbourne AU",
            "IT consultancies Austin TX",
        ],
        "maxResults": 300,
        "maxPagesPerSite": 4,
        "concurrency": 8,
        "verifyEmailDomains": True,
        "onlyWithContact": False,
    },
    timeout=1800,
)
df = pd.DataFrame(resp.json())
print(df[["business_name", "email_domain", "email_mx_provider", "email_is_freemail"]].head())

If you already have a lead list from another source, skip the Maps step entirely and pass websites (a list of URLs) or businesses (objects that each carry a website field). The businesses path carries your existing columns straight through onto the enriched rows, so the join is free.

How do I split the rows into provider cohorts?

Provider alone is not the segment. email_mx_provider: "google" covers both a paid Workspace tenant on smithaccounting.co.uk and a consumer address at smithaccounting@gmail.com. email_is_freemail is what separates them, and email_domain_mx_ok is what tells you the domain resolves at all.

def cohort(row):
    if not row.get("email_domain_mx_ok"):
        return "unusable"          # theme placeholder or dead domain
    provider = row.get("email_mx_provider") or "unknown"
    freemail = bool(row.get("email_is_freemail"))
    if freemail:
        return "freemail"          # real contact, but no tenant to sell into
    return {
        "google": "workspace",
        "microsoft365": "m365",
        "zoho": "zoho",
        "godaddy": "godaddy",
    }.get(provider, "other_hosted")

df["cohort"] = df.apply(cohort, axis=1)
have_email = df[df["primary_email"].notna() & (df["primary_email"] != "")]

print(have_email["cohort"].value_counts())
print(f"{len(have_email)} of {len(df)} businesses carry an email")

unusable is a genuinely useful bucket: around one in twenty of the email domains we find do not resolve at all, because the address was shipped inside a website theme and nobody ever changed it. Those rows should never reach a sending tool.

How do I route each cohort to the right offer?

The point of the split is that the same product needs four different first sentences. Build the routing table once and attach it to the frame, then export one file per cohort so each sequence is genuinely separate.

ANGLE = {
    "workspace": ("Google Workspace add-on", "Installs from the Workspace Marketplace, no admin migration"),
    "m365":      ("Microsoft 365 / Teams app", "Deploys via the M365 admin center, SSO with Entra ID"),
    "zoho":      ("Zoho-compatible, IMAP + API", "Usually cost-sensitive, lead with price not features"),
    "godaddy":   ("Hosted mail, likely M365 underneath", "Bought through their web host — sell simplicity"),
    "other_hosted": ("Standards-based, works anywhere", "Older stack, migration story lands well"),
    "freemail":  ("Solo operator", "Low ACV — self-serve tier or nurture only"),
}

for name, group in have_email.groupby("cohort"):
    if name == "unusable":
        continue
    product, note = ANGLE.get(name, ("generic", ""))
    group = group.assign(offer=product, sending_note=note)
    group.sort_values("business_rating", ascending=False).to_csv(f"leads_{name}.csv", index=False)
    print(f"{name}: {len(group)} leads -> leads_{name}.csv")

Two practical notes from running this on real territories. First, the m365 cohort skews larger and more regulated — accountancy, law, medical practices, anything with a compliance officer — so it converts on integration and audit-trail messaging. Second, godaddy is a distribution channel more than a mail stack: many of those tenants are Microsoft 365 seats resold through a web host, and they buy on "one less thing to configure."

How do I keep the segmentation fresh as businesses migrate?

Mail migrations are slow but real, and a migration is itself a trigger — a business that moved from a shared host to Microsoft 365 last quarter has budget and an IT decision-maker. Point Apify's scheduler at the same input monthly, keep the previous run's dataset, and diff on email_domain.

prev = pd.read_parquet("leads_2026_06.parquet")[["email_domain", "email_mx_provider"]]
curr = df[["business_name", "email_domain", "email_mx_provider", "primary_email"]]

moved = curr.merge(prev, on="email_domain", suffixes=("", "_prev"))
moved = moved[
    moved["email_mx_provider"].notna()
    & moved["email_mx_provider_prev"].notna()
    & (moved["email_mx_provider"] != moved["email_mx_provider_prev"])
]
print(moved[["business_name", "email_mx_provider_prev", "email_mx_provider"]])

Anything appearing in moved goes to the top of the queue. It is a small list every month, and it is the highest-intent list you will build from public data.

Sample output

Three enriched rows, trimmed to the fields that matter for segmentation. Each one lands in a different cohort.

[
  {
    "source_query": "IT consultancies Austin TX",
    "business_name": "Austin Plumbing",
    "business_category": "Plumber",
    "business_rating": 4.8,
    "website": "https://austinplumbing.com/",
    "final_url": "https://www.austinplumbing.com/",
    "primary_email": "service@austinplumbing.com",
    "primary_email_source": "text",
    "emails_count": 1,
    "email_domain": "austinplumbing.com",
    "email_is_freemail": false,
    "email_domain_mx_ok": true,
    "email_mx_provider": "microsoft365",
    "primary_phone": "+15129004663",
    "linkedin_url": "https://www.linkedin.com/company/austin-plumbing/",
    "social_profiles_count": 7,
    "fetch_status": "ok",
    "pages_fetched": 4,
    "has_contact": true
  },
  {
    "source_query": "architecture studios Melbourne AU",
    "business_name": "Northcote Design Studio",
    "business_rating": 4.9,
    "website": "https://northcotedesign.example/",
    "primary_email": "studio@northcotedesign.example",
    "primary_email_source": "mailto",
    "email_domain": "northcotedesign.example",
    "email_is_freemail": false,
    "email_domain_mx_ok": true,
    "email_mx_provider": "google",
    "fetch_status": "ok",
    "has_contact": true
  },
  {
    "source_query": "accounting firms Leeds UK",
    "business_name": "Hardwick Bookkeeping",
    "business_rating": 4.6,
    "website": "https://hardwickbooks.example/",
    "primary_email": "hardwickbooks@gmail.com",
    "primary_email_source": "cfemail",
    "email_domain": "gmail.com",
    "email_is_freemail": true,
    "email_domain_mx_ok": true,
    "email_mx_provider": "google",
    "fetch_status": "ok",
    "has_contact": true
  }
]

Read them together and the nuance is obvious. Row one is a Microsoft 365 tenant on a custom domain: email_mx_provider: microsoft365, email_is_freemail: false. Row two is a paid Google Workspace tenant. Row three is google as well — but email_is_freemail: true means it is a consumer Gmail account, so it belongs in a self-serve nurture, not in a Workspace Marketplace pitch. primary_email_source: cfemail on that row means the address was recovered from obfuscated markup that a naive scraper would have read as empty. email_domain_mx_ok gates all of it.

Common pitfalls

Provider comes from the primary email's domain only. The lookup runs once per lead, on email_domain. If a business publishes both info@theirdomain.com and a personal Gmail, only the domain of primary_email is resolved. Check the full emails array before you conclude a business has no custom domain.

"Other" is a bucket, not a lookup failure. The actor reports five values. Everything outside Google, Microsoft 365, Zoho and GoDaddy collapses into other — regional hosts, cPanel mail, ISP mail, self-managed servers. That is a real segment worth its own sequence; do not discard it as noise.

GoDaddy often means Microsoft underneath. GoDaddy resells Microsoft 365 mailboxes, so a godaddy MX can sit in front of a Microsoft tenant. Treat it as a distinct buying context (bought from a web host, wants simplicity) rather than a distinct technology.

Roughly a quarter of businesses yield no email at all, so they carry no provider. That share is worst in US home services (around 55-60% email coverage) and best in wellness, design and professional services abroad (around 85-90%). Budget your cohort sizes from the low end of that range.

Reading deeper does not help. The crawl is capped at four pages per site because we measured going to ten: it recovered 2 of 18 email-less sites while tripling the bandwidth per site. And the check is domain-level — email_domain_mx_ok proves the domain can receive mail, not that info@ exists.

Thirdwatch's actor caches the MX lookup per domain, so a hundred leads sharing one domain cost a single DNS query, and every row carries fetch_status and http_server_header so you can tell "this site is broken" apart from "this site blocked us."

Related use cases

Frequently asked questions

How do I identify companies using Google Workspace or Microsoft 365?

Look up the MX records of the company's email domain. Google Workspace domains point at Google's mail hosts, Microsoft 365 domains point at a mail.protection.outlook.com host. The actor does this lookup for you and reports the result in email_mx_provider.

Does email_mx_provider tell me the company pays for Workspace?

Not on its own. A gmail.com address also resolves to google. Combine email_mx_provider with email_is_freemail: provider google plus freemail false means a custom domain on Google Workspace, which is a paid seat.

What does the 'other' bucket contain?

Everything outside Google, Microsoft 365, Zoho and GoDaddy. In practice that is regional hosts, cPanel and shared-hosting mail, ISP mail, and self-managed servers. It is a real segment, not a failure, and it skews toward smaller and older businesses.

How many of my leads will carry a provider value?

Only rows that produced an email on a reachable site with a resolving domain. Around three-quarters of readable business websites yield an email, so plan on provider coverage of roughly two-thirds of the businesses you enrich, not all of them.

Is this the same as checking SPF, DKIM and DMARC?

No. SPF, DKIM and DMARC answer whether your own mail will land. The MX provider answers which mail stack the prospect runs on. One is deliverability hygiene, the other is a targeting and buying signal.

Related

Try it yourself

100 free credits, no credit card.

About 30 real searches. Add the MCP to Claude or Cursor in two minutes.