The Five Header Values

Every message processed by Spam Killer v1.9.1+ / v2.6.1+ gets an X-Spam-Classification header set to one of:

  • ham — normal mail, below spam threshold, no special classification
  • social — social platform notification (LinkedIn, Facebook, etc.)
  • promotional — marketing mail, below spam threshold
  • spam-promotional — marketing mail that also exceeds spam threshold
  • spam — high-scoring mail not classified as social or promotional

The values are stable, lowercase, and do not contain spaces or special characters — they're designed to be matched on by exact string comparison rather than parsed.

Why Match on the Header, Not the Subject

You might be tempted to write rules that match on the [SPAM], [SOCIAL], or [PROMOTION] tags in the subject line. This works, but it's brittle. Subject lines can be modified by intermediate mail systems, forwarded messages may double-prefix the tag, and users can manually edit the subject when replying — losing the tag in any reply chain.

The X-Spam-Classification header is set once at the proxy, never modified by downstream systems, and is invisible to users so it can't be inadvertently stripped. Match on the header for any rule that needs to be reliable.

Microsoft Exchange / Outlook Mail Flow Rules

In the Exchange Admin Center, navigate to Mail flow → Rules → Add a rule. Create one rule per category you want to route:

Social mail rule:

  • Condition: A message header includes — Header: X-Spam-Classification, Value: social
  • Action: Move the message to folder — Social (set up the destination folder per-mailbox or via PowerShell)

Promotional mail rule:

  • Condition: A message header includes — Header: X-Spam-Classification, Value: promotional
  • Action: Move the message to folder — Promotions

Spam-promotional and spam rules: route both to junk, or split them into separate folders if you want to scan aggressive marketing separately from regular spam.

For desktop Outlook client-side rules, use File → Manage Rules & Alerts → New Rule, choose "with specific words in the message header," and enter X-Spam-Classification: social (or whichever value) as the search phrase.

Gmail and Google Workspace

Google Workspace administrators can create routing rules in Admin → Apps → Google Workspace → Gmail → Compliance → Content compliance. Set the match field to Full headers and use a regex like:

X-Spam-Classification:\s*social

Set the action to apply a label and skip the inbox, or to route to a quarantine.

Individual Gmail users have a harder time — Gmail's standard filter UI doesn't expose custom header matching directly. The workaround is to match on subject tags ([SOCIAL], [PROMOTION]) instead. Less robust than header matching, but works without admin privileges:

  • Filter: Subject contains "[SOCIAL]"Skip Inbox, Apply label "Social", Mark as read
  • Filter: Subject contains "[PROMOTION]"Skip Inbox, Apply label "Promotions"

Postfix header_checks

If you run Postfix as the upstream for Spam Killer, you can use header_checks to act on the header before delivery. Add to /etc/postfix/main.cf:

header_checks = regexp:/etc/postfix/header_checks

Then in /etc/postfix/header_checks:

# Tag social mail for Sieve to route
/^X-Spam-Classification:\s*social/ PREPEND X-Mail-Folder: Social

# Tag promotional mail
/^X-Spam-Classification:\s*promotional/ PREPEND X-Mail-Folder: Promotions

# Discard very high-scoring spam outright
/^X-Spam-Classification:\s*spam/ PREPEND X-Mail-Folder: Junk

Then have your Sieve or Procmail rules at delivery time act on the X-Mail-Folder header to route to the appropriate IMAP folder. This pattern keeps the Postfix config simple while moving the actual delivery logic to the user-level filter system that already understands per-user folder layouts.

Sieve (Dovecot, Cyrus)

If your IMAP server supports Sieve, you can write user-level rules that match on X-Spam-Classification directly. Example .dovecot.sieve snippet:

require ["fileinto"];

if header :is "X-Spam-Classification" "social" {
  fileinto "Social";
  stop;
}

if header :is "X-Spam-Classification" "promotional" {
  fileinto "Promotions";
  stop;
}

if header :is "X-Spam-Classification" "spam-promotional" {
  fileinto "Junk Marketing";
  stop;
}

if header :is "X-Spam-Classification" "spam" {
  fileinto "Junk";
  stop;
}

This is the cleanest setup if your mail infrastructure supports it. Per-user Sieve files mean each user can customize their own routing without admin involvement.

Thunderbird and Apple Mail

Both clients support custom header matching. In Thunderbird, Tools → Message Filters → New → Customize to add X-Spam-Classification as a header to match on, then build filters with conditions like "X-Spam-Classification is social".

In Apple Mail, Mail → Settings → Rules → Add Rule → Any header, set Contains X-Spam-Classification: social, and route to the appropriate mailbox.

Recommended Folder Structure

For most users, this folder structure works well:

  • Inbox — only ham mail. Real correspondence requiring attention.
  • Social — all X-Spam-Classification: social mail. Check once a day.
  • Promotions — all X-Spam-Classification: promotional mail. Check weekly.
  • Junk Marketingspam-promotional mail. Scan briefly when you have time.
  • Junk / Spamspam mail. Scan occasionally for false positives.

The result is an inbox that contains only mail that might require your attention today, with everything else sorted into folders you visit on a schedule that matches the urgency of that mail type.