# What is a role-based email address?

_2026-11-04 · Boundstone (https://boundstone.io/blog/what-is-a-role-based-email)_


## What is a role-based email address?

A role-based email address is one whose local part — the bit before the `@` — names a function instead of a person: `info@`, `support@`, `admin@`, `sales@`, `billing@`, `no-reply@`. Ask "what is a role-based email address" and the short answer is a mailbox that belongs to a team, not an individual. `jane@acme.com` is almost certainly Jane. `support@acme.com` is a queue that three people, a shared inbox, and a ticketing bot all read.

That distinction sounds academic until you send to one.

## Why role addresses matter

Three reasons, in rough order of how much they'll cost you.

**Personalization breaks.** Your onboarding sequence opens with "Hi Jane" — except there's no Jane behind `info@`. A first-name merge on a role address reads as a mass email, because it is one. The people who see it never signed up as themselves; they inherited the inbox.

**Deliverability risk goes up.** Shared inboxes get more mail, get read less carefully, and generate more spam complaints per send. Some are monitored as spam traps. A pile of role addresses on your list drags your sender reputation down, which quietly costs you inbox placement for every other address too.

**It can be a weak fraud signal.** Someone spinning up throwaway signups sometimes reaches for `admin@` or `test@` on a domain they don't personally own. On its own that proves nothing — plenty of real buyers sign up with `orders@` — but combined with other signals it's worth noticing.

## How detection works — and where it stops

Role detection is not clever. You take the local part, lowercase it, and check it against a list of known role names:

```python
ROLE_LOCAL_PARTS = {
    "admin", "administrator", "info", "support", "sales", "billing",
    "help", "helpdesk", "contact", "office", "hello", "team",
    "marketing", "noreply", "no-reply", "postmaster", "webmaster",
    "abuse", "hr", "jobs", "careers", "accounts", "orders",
}

def is_role_account(email: str) -> bool:
    local = email.rsplit("@", 1)[0].strip().lower()
    return local in ROLE_LOCAL_PARTS

is_role_account("support@acme.com")   # True
is_role_account("jane.doe@acme.com")  # False
```

That is genuinely the whole mechanism, and for a lot of teams that fifteen-line function is all you need — ship it and move on.

Here's the honest limit: a list reads the local part, and nothing else. It cannot see who is actually behind the mailbox. `info@` at a one-person consultancy is read by exactly one human who takes it personally. `j.smith@` might be a shared alias three people watch. The list will call the first a role account and miss the second, and it will do that every time, because the only thing it has to go on is a string. Role detection is a heuristic about a name, not a fact about a person.

## Where Boundstone fits

If you already validate email — see [validating email in Python](/blog/validate-email-python) — you can add role detection with the set above and never call an API. Do that first; often it's enough.

The API earns its place when you want one consistent contract across every client and every check in one call. `POST /v1/verify/email` returns a `role_account` boolean alongside syntax, live-MX, and disposable checks — the last being a [separate concept worth understanding on its own](/blog/what-is-disposable-email):

```bash
curl -s https://api.boundstone.io/v1/verify/email \
  -H "Authorization: Bearer bs_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"email":"support@acme.com"}'
```

```json
{
  "valid_syntax": true,
  "domain": "acme.com",
  "mx_found": true,
  "disposable": false,
  "role_account": true,
  "free_provider": false,
  "checks": {
    "performed": ["syntax", "mx", "disposable_list", "role_list"],
    "not_performed": ["smtp_mailbox", "catch_all"]
  }
}
```

Note `checks`. `role_list` sits in `performed` — we checked the local part against a role list, and that's exactly what `role_account` reflects, nothing more. Meanwhile `smtp_mailbox` and `catch_all` sit in `not_performed`: Boundstone does not knock on the mailbox to confirm a specific human reads it, and does not detect catch-all domains. `mx_found: true` means the domain accepts mail; it does not mean `support@acme.com` is a live, monitored inbox. We'd rather list what we skipped than let a green checkmark imply more than it earned. That `not_performed` array is the point — it's why you can trust the fields that are filled in.

## Treat it as a signal, not a switch

`role_account: true` is information, not a verdict. Reject on it blindly and you'll bounce real customers whose company routes signups through `accounts@` or `purchasing@`. Use it to route instead:

```javascript
const res = await fetch("https://api.boundstone.io/v1/verify/email", {
  method: "POST",
  headers: {
    "Authorization": "Bearer bs_live_YOUR_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({ email }),
});
const { role_account } = await res.json();

if (role_account) {
  // Don't block. Skip the "Hi {first_name}" merge and
  // send the team-friendly welcome instead.
  sendGenericWelcome(email);
} else {
  sendPersonalizedOnboarding(email);
}
```

Same door for everyone; different mat depending on who's likely on the other side.

## The short version

- A role-based email address names a function (`info@`, `support@`, `no-reply@`), so it belongs to a team, not a person.
- It matters because personalization falls flat, deliverability risk rises, and it's an occasional fraud signal.
- Detection is a local-part list — fifteen lines of your own code, and often all you need. Its limit: it reads the name, never the human behind it.
- Boundstone returns a `role_account` flag with `role_list` in `checks.performed`, in one call alongside syntax, MX, and disposable — and tells you plainly, via `not_performed`, that it never checked the mailbox itself.
- Use the flag to route, not to reject. Try it with no key on the [free email validator](/tools/email-validator).
