EmailGuard
  • Pricing
Log inRegister
Person filling a work email field on a signup form

How to Require a Work Email at Signup

by EmailGuard Marketing

Unsplash
September 3, 2026engineering10 min read

Share this article

On this page

  • What you'll accomplish
  • Freemail is not a syntax error
  • Gmail the product is not Gmail the domain
  • Ranking how-tos get this wrong
  • Step 1: Name the product job
  • Step 2: Assign block, warn, or route
    • Decision matrix
  • Step 3: Combine flags before you apply the public-domain rule
  • Step 4: Enforce on the server, re-check on change
  • Common mistakes
  • FAQ
    • How do I require a work email at signup?
    • Will blocking gmail.com block Google Workspace users?
    • Is Gmail a work email?
    • What is the difference between a free email and a disposable email?
    • What is Apple Hide My Email?
    • Can users bypass a JavaScript domain blocklist?
  • Next steps

Enjoyed this article?

More notes on building products, infrastructure, and teams.

EmailGuard

Email validation API for signup and lead intake—syntax, disposable, role, relay, and public-domain signals in one request.

Product

  • What's included

Docs

  • Documentation
  • API Reference
  • Knowledge Base

Resources

  • Blog
  • Changelog
  • Free tools
  • Alternatives
  • Legal & security
  • Contact
  • Data correction

Pricing

  • Pricing

© 2026 EmailGuard

A Baker Assets company

A work-email signup policy is a per-field rule: block, warn, or route when the address is consumer freemail such as Gmail, Outlook.com, or Yahoo. The product job for that field decides the action. An enterprise demo form is not the same job as a PLG trial. A static Set of gmail.com in client JavaScript is not a policy. It is a denylist that misses Workspace on a custom domain, conflates privacy relays with Gmail, and is trivial to bypass.

This guide is the implementation counterpart to public email domains. You will leave with a written matrix, a server-side check on public_domain, and a clear split from disposable and relay flags.

What you'll accomplish

By the end, you will:

  1. Map each email field to a product job.
  2. Assign block, warn, or route when public_domain is true.
  3. Keep disposable and relay_domain on their own rows.
  4. Enforce the rule on the server with EmailGuard's detect API.
  5. Re-check on email change, not only on create.

Prerequisites: A signup or form handler you control, an API key with the email:detect scope, and a boolean or enum on the user (email_kind: work, public, relay, disposable). Staging first. Try sample addresses in the public domain checker before you freeze a client-side list.

Freemail is not a syntax error

alex@gmail.com is a valid RFC 5322 address. There is no RFC that defines "work email." Classification is operational data: a maintained list of consumer mailbox providers. EmailGuard sets public_domain true for those providers after syntax checks.

Three flags people mash together:

FlagMeaningTypical signup action
disposableThrowaway domainBlock on almost every product
relay_domainPrivacy forwarding (Apple Hide My Email, Firefox Relay)Usually allow; see privacy relay vs disposable
public_domainConsumer/freemail host (Gmail, Outlook.com, Yahoo, iCloud, Proton free, regional webmail)Block, warn, or route by job

A disposable Gmail-lookalike is still disposable. A Gmail address is not disposable. An Apple Hide My Email address is @privaterelay.appleid.com, documented in Apple Support HT105078 (published 2025-12-04). It is not gmail.com and it is not icloud.com.

Gmail the product is not Gmail the domain

Hard-blocking gmail.com does not block Google Workspace users on alex@acme.com. Those mailboxes never use the consumer domain. Google's own Help article Choose your Google Workspace edition (updated 2026-08-26) treats @gmail.com as a personal Gmail address and a verified custom domain as a separate path.

The trap in the other direction: Google also sells Gmail-based Workspace and Individual plans that stay on gmail.com / hotmail.com / yahoo.com. "Pays Google for Workspace" is not the same as "has a company hostname." Domain classification is the signal. A Workspace badge is not.

Microsoft draws the same consumer line. Outlook.com mailboxes use @outlook.com, @hotmail.com, @live.com, and @msn.com. Microsoft 365 on alex@acme.com is not those domains.

Corporate Google Workspace and Microsoft 365 on a customer hostname return public_domain: false.

Ranking how-tos get this wrong

Framer and form-tool posts publish a client-side list of gmail.com, yahoo.com, and outlook.com, then call setCustomValidity. That pattern has four failure modes:

  1. Bypass. Anyone can POST the form without the script.
  2. False friends. Token checks like "the label is mail" block mail.company.com.
  3. False enemies. zoho.com as a literal block hits Zoho's consumer domain and says nothing about Zoho-hosted custom domains.
  4. Missing classes. Relays, disposables, and googlemail.com drift off the list.

GitLab's signup restrictions are a real product version of allowlist and denylist, including wildcards. Two details to steal: restrictions apply to external self-signup, and users can change their email after create to a banned domain unless you re-check. Cognito's Pre Sign-up trigger is the same idea: deny by throwing on the server before the user exists.

Step 1: Name the product job

Write the email field's job in one sentence. If you cannot, you will over-block founders who live on Gmail.

Product jobWhat "work email" is for
Enterprise demo / sales-led trialA company hostname sales can enrich and route
Self-serve PLG workspaceA recoverable human; Gmail is often fine
Consumer appFreemail is the ICP
NewsletterConsent, not firmographics
Invite / SSOThe IdP already named the person; public_domain is unused on that path
Edtech / university.edu is work for that product; it is not Gmail

Same flag, different jobs. public_domain: true on a design-tool signup is a customer. On an enterprise RFP form it is a tire kicker, or a consultant you still want.

Step 2: Assign block, warn, or route

Three actions. Not a boolean.

Block. Reject the request. Use this when a company hostname is a hard eligibility rule (vendor security questionnaire, closed beta for named accounts). Tell the user to use their work address. Do not say "invalid email."

Warn. Accept, show that you noticed, and ask for a company address as optional. Use this when you prefer work email but Gmail founders are real buyers.

Route. Accept with no extra friction. Store public_domain and send consumer domains to self-serve. Send public_domain: false to sales or a higher-touch trial. Mailbeam's glossary describes this split. It does not require a hard block.

Decision matrix

Product jobRecommended actionWhy
Enterprise demo requestBlock or warnYou are filtering for accounts you can enrich. Warn if consultants on Gmail are still in ICP.
B2B self-serve trialRouteBlocking Gmail cuts solopreneurs Google itself sells Workspace Individual to.
Consumer loginAllow (ignore the flag)Freemail is the product.
NewsletterAllowFirmographics are not the job.
Invite / SAMLIgnoreThe IdP assertion is identity. GitLab's domain lists do not replace SSO.
Regional B2B (CN, RU, DE webmail)Warn or allowQQ, 163, Mail.ru, GMX, and Yandex are default professional addresses in those markets. A US Gmail list exports a US ICP.

Do not infer company size from the provider. Paid Proton still sits on proton.me. That is public_domain: true, not "cannot pay."

Step 3: Combine flags before you apply the public-domain rule

Call detect once. Branch in order.

  1. Fail syntax.
  2. Hard-block disposable. A Gmail-shaped local part on a throwaway domain is still throwaway.
  3. Apply role-based policy if the local part is info@ / sales@.
  4. Apply relay policy. Do not fold privaterelay.appleid.com into freemail.
  5. Apply the public-domain action from the matrix.
  6. Do not reject + tags. jane+trial@acme.com is still acme.com (RFC 5233 subaddressing). Normalize if you dedupe; see plus-addressed emails at signup.
function applyWorkEmailPolicy(result, job) {
  if (!result.syntax_validation) {
    return { action: "block", reason: "syntax" };
  }
  if (result.disposable) {
    return { action: "block", reason: "disposable" };
  }
  if (result.relay_domain) {
    return { action: "allow", reason: "relay", kind: "relay" };
  }
 
  if (!result.public_domain) {
    return { action: "allow", reason: "work_domain", kind: "work" };
  }
 
  switch (job) {
    case "enterprise_demo":
      return { action: "block", reason: "need_work_email", kind: "public" };
    case "plg_trial":
      return { action: "route", reason: "self_serve", kind: "public" };
    case "consumer":
    case "newsletter":
      return { action: "allow", reason: "freemail_ok", kind: "public" };
    default:
      return { action: "warn", reason: "prefer_work_email", kind: "public" };
  }
}

Worked responses (same endpoint):

InputFlags to expectNotes
alex@gmail.compublic_domain: trueConsumer Gmail
alex@googlemail.compublic_domain: trueLegacy Gmail domain; lists that omit it are already stale
alex@acme.com (Workspace MX)public_domain: falseWork email. Not Gmail.
alex+trial@acme.compublic_domain: false, subaddressing trueSame company mailbox
alex@privaterelay.appleid.comrelay_domain: trueHide My Email. Not iCloud freemail.
alex@qq.compublic_domain: trueConsumer/webmail; may be "work" in CN ICP

Copy is specific:

  • Block: "Use your work email (your company domain). Personal inboxes like Gmail are not eligible for this form."
  • Warn: "You can continue with this address. A company domain helps us set up your workspace faster."
  • Route: no extra copy. Internal tag only.

If the checker is down, do not fail closed on a missing public_domain flag unless this form is the enterprise demo. See fail open vs fail closed.

Step 4: Enforce on the server, re-check on change

Keep the API key off the browser. Run detect in the register handler and in the "change email" handler. GitLab documents the bypass: denylist at create, then a later email edit onto a banned domain.

For Cognito, throw in Pre Sign-up when action === "block". For Better Auth, the documented before-hook on /sign-up/email is the same place. For a generic POST /register, return 422 with the copy above.

When SSO is on, skip the public-domain gate for that path. Store the flag for analytics if you still collect an email claim.

Common mistakes

Client-only Gmail list. Attackers skip it. Legitimate Workspace users on custom domains were never on it.

Treating Gmail as disposable. You will send paying consumers to the throwaway error.

Blocking Hide My Email as Gmail. The domain is privaterelay.appleid.com.

Rejecting plus addresses. That is a work mailbox with a tag.

Never re-validating. The GitLab footgun. A denylist at create is worthless if settings allow gmail.com later.

One global policy. Demo form and PLG trial should not share a boolean.

FAQ

How do I require a work email at signup?

Call a classifier on the server, read public_domain, and block or warn only on the fields where a company hostname is the job. Do not ship a browser list of Gmail, Yahoo, and Outlook.

Will blocking gmail.com block Google Workspace users?

No. Workspace on a verified company domain uses that domain, not @gmail.com. Google's Help article on Workspace editions (updated 2026-08-26) separates personal Gmail from custom-domain Workspace. Gmail-based Workspace Individual still uses @gmail.com and will hit public_domain.

Is Gmail a work email?

Sometimes for the human, never as a company hostname. Solopreneurs and consultants work from Gmail. If they are in your ICP, route or warn. Do not pretend a denylist equals firmographics.

What is the difference between a free email and a disposable email?

Freemail is a long-lived consumer provider (Gmail, Outlook.com). Disposable is a throwaway domain. Block disposables first. Decide on public_domain second.

What is Apple Hide My Email?

A privacy relay. Addresses use @privaterelay.appleid.com (Apple Support, 2025-12-04). Treat relay_domain, not public_domain. icloud.com is consumer Apple Mail, a different flag.

Can users bypass a JavaScript domain blocklist?

Yes. Enforce on the server. Re-check when they change email.

Next steps

  1. Write the job matrix for each form.
  2. Call detect and store public_domain even on paths you allow.
  3. Add a change-email test that tries gmail.com after a work-domain create.
  4. Start from a free plan and confirm the flag in staging before you hard-block production demos.