# Spam filtering

> Protect your webhooks from unwanted emails with built-in spam filtering powered by Rspamd

Source: https://emailconnect.eu/help/spam-filtering/

EmailConnect provides built-in spam filtering powered by [Rspamd](https://rspamd.com/) to protect your webhooks from unwanted emails. For Maker+ users, spam analysis is automatically enabled on all custom domains.

## How spam filtering works

Every email sent to your Maker+ custom domains is automatically analyzed by Rspamd, which:

- Checks SPF, DKIM, and DMARC authentication
- Analyzes email headers and content patterns
- **Detects phishing attempts** (suspicious URLs, display text mismatches)
- Checks URLs against known phishing databases (OpenPhish, PhishTank)
- Assigns a spam score from 0 (ham) to 15+ (definite spam)

The spam score and analysis results are included in every webhook payload, giving you full visibility into email authenticity.

## Phishing protection

EmailConnect automatically detects phishing attempts using multiple techniques:

### What we detect

| Technique | Description |
|-----------|-------------|
| Display text mismatch | Links showing "paypal.com" but pointing to "evil-site.com" |
| Known phishing URLs | URLs matching OpenPhish and PhishTank databases |
| Suspicious redirects | Short URLs and redirect services often used in phishing |
| Brand impersonation | Emails mimicking legitimate services (banks, tech companies) |

### How it works

Phishing detection analyzes the **content** of emails (URLs, HTML, text patterns) rather than sender IP addresses. This means phishing protection works reliably regardless of how the email was delivered.

When phishing is detected, the spam score increases and a phishing indicator appears in the webhook `symbols` array:

```json
{
  "spam": {
    "score": 6.5,
    "symbols": [
      { "name": "PHISHED_URL", "weight": 4.0, "description": "evil-site.com" }
    ]
  }
}
```

Common phishing symbols include:
- `PHISHED_URL` - URL matches known phishing database
- `PHISHING` - General phishing indicators detected
- `PHISHED_DISPLAYED_URL` - Display text doesn't match actual URL

### Phishing vs spam score

Phishing detection contributes to the overall spam score. A detected phishing URL typically adds 3-5 points, pushing the email into the "likely spam" or "very likely spam" range.

You can use alias rules based on spam score to block suspected phishing emails:
- Score above 5 for moderate protection
- Score above 7 for stricter protection

## What's included in webhooks

When spam filtering is active, your webhook payload includes a `spam` object:

```json
{
  "message": {
    "sender": { "email": "user@example.com" },
    "subject": "Hello world"
  },
  "spam": {
    "score": 2.3,
    "symbols": [
      { "name": "DKIM_VALID", "weight": -0.1, "description": "example.com" },
      { "name": "R_SPF_ALLOW", "weight": -0.2, "description": null }
    ],
    "authentication": {
      "dkim": { "result": "pass", "domain": "example.com" },
      "spf": { "result": "pass", "domain": "example.com" },
      "dmarc": { "result": "pass", "domain": "example.com" }
    },
    "engine": "rspamd"
  }
}
```

| Field | Description |
|-------|-------------|
| `score` | The spam score (0 = clean, higher = more likely spam) |
| `symbols` | Array of detection symbols that contributed to the score |
| `authentication` | DKIM, SPF, and DMARC verification results |
| `engine` | The spam detection engine used |

### Why there's no `isSpam` field

The payload gives you the **score**, not a verdict. There's no `isSpam` boolean, no `threshold`, and no `action` field.

"Is this spam?" isn't a question we can answer for you — it depends on your tolerance for a false positive, and that varies enormously between a careers inbox and an abuse inbox. A boolean computed from a threshold you picked tells you nothing that comparing the score yourself wouldn't.

So: compare `spam.score` against your own cut-off in your endpoint, or — better — express the cut-off as an [alias rule](https://emailconnect.eu/help/alias-rules/) and let EmailConnect block or tag the mail before it ever reaches you.

## Controlling spam behavior with alias rules

While spam analysis runs automatically, **you decide what happens** based on the results. Use [alias rules](https://emailconnect.eu/help/alias-rules/) to define actions based on spam score:

### Example: Block high-scoring spam

Create a rule to reject emails scoring above 7:

1. Go to your alias settings
2. Click "Configure rules"
3. Add a condition: **Spam score** above **7**
4. Set action: **Block**
5. Optionally enable sender notification

### Example: Tag suspicious emails

For moderate spam scores, you might want to deliver but tag:

1. Add a condition: **Spam score** above **5**
2. Set action: **Tag**
3. Save the rule

Tagged emails are delivered with an `X-EmailConnect-Tagged` header naming which **kinds** of condition matched — `spam`, `sender`, `attachment`, or a comma-separated combination such as `sender,spam`. When a spam condition was among them, an `X-EmailConnect-Spam-Score` header carries the score. Your endpoint can then handle tagged mail differently without you having to re-derive why it was tagged.

### Example: Never block a trusted sender, whatever they score

This is the one that catches people out, so it's worth reading carefully.

An **Allow** rule means *"accept **only** what matches, block everything else."* It is a guest list, not an exception. So a rule that says nothing but *"Allow: sender domain is @trusted-partner.com"* does not protect your partner — it **blocks every other email you receive**, which is almost certainly not what you wanted.

To carve out an exception, the trusted sender and your normal spam threshold go in the **same rule**, joined with **OR**:

1. Condition 1: **Sender address** → **is one of** → `*@trusted-partner.com`
2. Condition 2, joined with **OR**: **Spam score** → **<** → `7`
3. Set action: **Allow**

Read it as *"accept this if it's from my partner **or** if it's clean."* Mail that is neither — a stranger scoring above 7 — is blocked. Your partner gets through no matter what they score, and everyone else is still filtered.

The same shape works for any exception. The rule to remember:

| What you want | How to say it |
|---|---|
| Accept **only** from X | **Allow** + `sender is X` |
| Accept X **as well as** everything my other rules allow | **Allow** + `sender is X` **OR** *(your other condition)* |

### Use `Sender address` with a wildcard, not `Sender domain`, for exceptions

This matters, and it is not obvious.

**Sender address** → **is one of** → `*@trusted-partner.com` matches the *end* of the full address. Nothing else can satisfy it.

**Sender domain** → **contains** → `trusted-partner.com` is a **substring** match, and it is the only operator that field offers. An attacker who registers `trusted-partner.com.evil.io` sends from `ceo@trusted-partner.com.evil.io` — which *contains* your trusted string. Their mail matches your exception, **skips your spam filter entirely, and lands in your webhook**. We have verified this behaves exactly as described.

So: build sender exceptions with **Sender address + a `*@` wildcard**. Reserve **Sender domain + contains** for coarse, non-security-critical grouping.

### An exception is a skeleton key inside its own rule

An alias has **one** rule set with **one** action. If you put an attachment condition into the same Allow rule as your sender exception, the **OR** means a match on the sender alone is enough to accept the mail — the attachment condition is never consulted. Your trusted partner's `.exe` sails through.

Attachment *type* policy is a separate mechanism (your storage and file-type settings), and it still excludes disallowed files from the payload regardless of rules. But do not assume an attachment **condition** inside an Allow rule survives a sender exception in the same rule. It does not.

## Understanding spam scores

| Score range | Interpretation | Recommended action |
|-------------|----------------|-------------------|
| 0 - 2 | Clean email | Allow |
| 2 - 5 | Slightly suspicious | Allow or monitor |
| 5 - 7 | Likely spam | Tag or block |
| 7 - 10 | Very likely spam | Block |
| 10+ | Definite spam | Block |

These are guidelines - adjust thresholds based on your use case.

## Best practices

### For public-facing addresses (support@, info@)

- Set a rule to block a spam score above 7
- Consider tagging scores above 5 for manual review
- Enable sender notifications for blocked emails

### For transactional addresses (orders@, invoices@)

- Be more conservative — block only a score above 10
- Add your known senders as an **OR** exception inside that rule, not as a rule of their own — and use **Sender address** with a `*@` wildcard, never **Sender domain contains** (see [Never block a trusted sender](#example-never-block-a-trusted-sender-whatever-they-score))
- Monitor for false positives initially

### For internal automation

- Consider a higher threshold: automated mail often trips spam detection because it is machine-generated, not because it is malicious
- If a specific automation source keeps scoring high, add it as an **OR** exception to your existing rule — a standalone Allow rule for it would block everything else that alias receives

## Availability

| Plan | Spam filtering |
|------|----------------|
| Free | Not available |
| Maker | Automatic on all custom domains |
| Business | Automatic on all custom domains |
| Platform | Automatic with custom configuration |

System aliases (`@user.emailconnect.eu`) use basic processing and do not include spam analysis.

## FAQ

### Is spam filtering automatic for Maker+ users?

Yes. Once you have a Maker+ subscription, spam analysis runs on all emails to your custom domains. You don't need to enable anything.

### Do I have to create rules?

No. Without rules, all emails are delivered to your webhook with spam data included. You can filter in your own application using the spam score, or set up rules in EmailConnect to block/tag before delivery.

### What happens to blocked emails?

Blocked emails are rejected at delivery time. If you enable sender notification, the sender receives a bounce message explaining the rejection.

### Can spam filtering block legitimate emails?

It's possible. If you suspect false positives:
1. Check the spam score in your webhook logs — that tells you whether the mail was actually scored high, or whether something else blocked it
2. Raise your blocking threshold, so fewer messages cross it
3. Or carve out an exception for that specific sender — but do it with an **OR** condition inside your existing rule, using **Sender address** and a `*@` wildcard, as shown in [Never block a trusted sender](#example-never-block-a-trusted-sender-whatever-they-score) above. **A bare "Allow: sender is X" rule blocks everything that isn't X**, which turns one false positive into a total outage
4. Contact support if issues persist

### Does spam filtering affect email speed?

No. Spam analysis runs in real-time as part of email processing with negligible latency impact.

### Can I see why an email was flagged?

Yes! Check the `symbols` array in your webhook payload. Each symbol shows what was detected and how much it contributed to the spam score. Common symbols include authentication results (DKIM_VALID, R_SPF_ALLOW), phishing indicators (PHISHED_URL), and content patterns.

### Is phishing detection automatic?

Yes. Phishing detection is part of the standard spam analysis for Maker+ users. No additional configuration needed. When phishing is detected, you'll see phishing-related symbols in your webhook payload and an increased spam score.

### How do I block phishing emails specifically?

Phishing detection contributes to the overall spam score (typically +3 to +5 points). Create an alias rule to block emails scoring above 5, or above 7 if you want to be less aggressive. All detected phishing attempts will be caught by this threshold.

## Related documentation

- [Alias rules](https://emailconnect.eu/help/alias-rules/) - Configure actions based on spam score and other conditions
- [Email processing](https://emailconnect.eu/help/email-processing/) - Understanding the email processing pipeline
- [Domain setup](https://emailconnect.eu/help/domain-setup/) - Setting up custom domains
