
# Flexible SPF Record Matching

When monitoring SPF (Sender Policy Framework) records, strict exact matching can cause false alerts when customers add additional mail services to their SPF configuration. Flexible matching solves this by verifying only that your required SPF components are present.

## The Challenge with Exact Matching

Imagine you require customers to include `include:_spf.service.com` in their SPF record. With exact matching enabled, you might set up monitoring like this:

```
POST https://api.dnsradar.dev/monitors

domain: piedpiper.com
  record_type: TXT
  expected_value: v=spf1 include:_spf.service.com -all
  is_exact_match: true
```

This works initially, but if the customer adds Google Workspace to their email setup, their SPF record becomes:

```
v=spf1 include:_spf.service.com include:_spf.google.com -all
```

With exact matching, your monitor would trigger a `MISMATCH` alert, even though your required include is still present.

## Enabling Flexible Matching

Set `is_exact_match` to `false` and specify only the SPF components you require:

```
POST https://api.dnsradar.dev/monitors

domain: piedpiper.com
  record_type: TXT
  expected_value: v=spf1 include:_spf.service.com
  is_exact_match: false
```

> ℹ️ **INFO:** **SPF Version Required**: The `v=spf1` prefix is required in your `expected_value` to indicate you're monitoring an SPF record. DNSRadar uses this to apply SPF-specific matching rules.

## How Flexible Matching Works

With flexible matching enabled for SPF records, DNSRadar:

1. Verifies the SPF record starts with `v=spf1`
2. Checks that all mechanisms and modifiers in your `expected_value` are present
3. Ignores additional mechanisms, modifiers, or qualifiers


## Valid SPF Variations

With the flexible configuration above, these SPF records would all be considered VALID:

```
v=spf1 include:_spf.service.com -all
v=spf1 include:_spf.service.com ~all
v=spf1 include:_spf.service.com include:_spf.google.com -all
v=spf1 ip4:1.2.3.4 include:_spf.service.com include:_spf.microsoft.com -all
```

All these records contain your required `include:_spf.service.com` mechanism, so they pass validation regardless of additional components or modified qualifiers.

## Monitoring Multiple SPF Components

You can require multiple specific SPF components:

```
POST https://api.dnsradar.dev/monitors

domain: piedpiper.com
  record_type: TXT
  expected_value: v=spf1 include:_spf.service.com ip4:1.2.3.4
  is_exact_match: false
```

This configuration ensures both the `include:_spf.service.com` mechanism and the `ip4:1.2.3.4` mechanism are present, while allowing additional SPF components.

## When Monitors Trigger

A `MISMATCH` alert will be triggered if:

- Your required include is removed: `v=spf1 include:_spf.google.com -all`
- The SPF version is missing: `include:_spf.service.com -all`
- The SPF record is completely removed
- The SPF syntax is invalid

> ✅ **SUCCESS:** **Qualifier Changes Allowed**: Using flexible matching, if you omit the final qualifier (`~all`, `-all`, `?all`), there won't be any `MISMATCH` triggered by DNSRadar when your customer changes it.

If you want to ensure that the qualifier is correctly set at a specific value, you can include in your list of parts to match on your SPF record, such as setting the `expected_value` to `v=spf1 include:_spf.service.com -all` will check that both `include:_spf.service.com` and `-all` are present.

## Limitations

> ⚠️ **WARNING:** **Mechanism Order**: Flexible matching checks for presence, not order. If the order of SPF mechanisms matters for your use case, use exact matching instead.

## Best Practices

1. **Specify Minimum Requirements**: Only include the SPF components you absolutely need to verify
2. **Omit Final Qualifiers**: Let customers choose `-all`, `~all`, or `?all` based on their needs
3. **Test Configurations**: Use the [webhook testing endpoint](/docs/test-webhooks) to verify your monitoring setup
4. **Document Requirements**: Clearly communicate to customers which SPF components you require

## Combining with Other Record Types

Often, you'll want to monitor SPF alongside other DNS records:

```
POST https://api.dnsradar.dev/monitors/bulk

monitors:
    - domain: piedpiper.com
      record_type: TXT
      expected_value: v=spf1 include:_spf.service.com
      is_exact_match: false
    - domain: piedpiper.com
      subdomain: _dmarc
      record_type: TXT
      expected_value: v=DMARC1
      is_exact_match: false
    - domain: piedpiper.com
      record_type: MX
      expected_value: ["mx1.service.com", "mx2.service.com"]
      is_exact_match: false
  group: email-infrastructure
```

## Next Steps

- [Flexible DMARC Record Matching](/docs/dmarc-flexible-matching)
- [Flexible MX Record Matching](/docs/mx-flexible-matching)
- [Configure webhook notifications](/docs/configure-webhooks)
