> ## Documentation Index
> Fetch the complete documentation index at: https://docs.sendkit.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# SPF

> Understand how SPF works and why it's essential for email authentication.

## What is SPF?

SPF (Sender Policy Framework) is an email authentication protocol that lets you declare which mail servers are allowed to send emails on behalf of your domain. It's one of the first checks a receiving mail server performs when an email arrives.

Without SPF, anyone can send an email that claims to come from your domain. SPF prevents this by publishing a list of authorized senders in your DNS.

## How SPF works

When someone sends an email from `hello@acme.com`, the recipient's mail server:

1. Looks up the SPF record for `acme.com` in DNS
2. Gets a list of IP addresses and servers authorized to send for that domain
3. Checks if the sending server's IP is on that list
4. Returns a **pass** or **fail** result

<Steps>
  <Step title="Email sent from hello@acme.com">
    The email leaves your server and arrives at the recipient's mail server.
  </Step>

  <Step title="DNS lookup">
    The recipient's server looks up the SPF record for `acme.com` and finds `v=spf1 include:sendkit.dev ~all`.
  </Step>

  <Step title="IP authorization check">
    The server checks if the sending IP is listed in the SPF record.
  </Step>

  <Step title="Result">
    **Pass** — the IP is authorized, email is accepted. **Fail** — the IP is not authorized, email is flagged or rejected.
  </Step>
</Steps>

## SPF record syntax

An SPF record is a TXT record in your DNS. Here's the anatomy of a typical record:

```
v=spf1 include:sendkit.dev ~all
```

| Part                  | Meaning                                                    |
| --------------------- | ---------------------------------------------------------- |
| `v=spf1`              | Version identifier — always `spf1`                         |
| `include:sendkit.dev` | Authorize all servers listed in SendKit's SPF record       |
| `~all`                | Soft fail for any server not listed (see qualifiers below) |

### Mechanisms

Mechanisms define who is authorized to send:

| Mechanism | Description                                | Example               |
| --------- | ------------------------------------------ | --------------------- |
| `include` | Authorize another domain's SPF record      | `include:sendkit.dev` |
| `ip4`     | Authorize a specific IPv4 address or range | `ip4:192.168.1.1`     |
| `ip6`     | Authorize a specific IPv6 address or range | `ip6:2001:db8::/32`   |
| `a`       | Authorize the domain's A record IP         | `a`                   |
| `mx`      | Authorize the domain's MX record IPs       | `mx`                  |
| `all`     | Match everything (used at the end)         | `~all`                |

### Qualifiers

Qualifiers tell the receiving server what to do with emails that match (or don't match) a mechanism:

| Qualifier | Symbol        | Meaning                                                 |
| --------- | ------------- | ------------------------------------------------------- |
| Pass      | `+` (default) | The server is authorized                                |
| Fail      | `-`           | The server is **not** authorized — reject the email     |
| Soft fail | `~`           | The server is probably not authorized — accept but mark |
| Neutral   | `?`           | No opinion — treat as if there's no SPF                 |

**Recommendation:** Use `~all` (soft fail) while setting up, then switch to `-all` (hard fail) once you're confident all legitimate senders are listed.

## The 10-lookup limit

SPF has a hard limit of **10 DNS lookups** per evaluation. Each `include`, `a`, `mx`, and `redirect` mechanism counts as one lookup. If your record exceeds 10 lookups, the SPF check automatically fails.

This is a common problem when you use multiple email services (SendKit, Google Workspace, marketing tools, etc.), each adding their own `include`.

### How to check your lookup count

Count each `include` in your SPF record. Then count the `include` statements inside each of those records (they're recursive). The total must be 10 or fewer.

### How to stay under the limit

* **Use `ip4`/`ip6` instead of `include`** when possible — IP mechanisms don't count as lookups
* **Remove unused includes** — if you stopped using a service, remove it from SPF
* **Use subdomains** — send different types of email from different subdomains, each with their own SPF record
* **Flatten your SPF record** — replace nested includes with their resolved IPs (but you'll need to update them if the IPs change)

## SPF with SendKit

When you add a domain in SendKit, we generate an SPF record for the `send` subdomain. This keeps your root domain's SPF record clean and avoids conflicts with other services.

| Field     | Value                               |
| --------- | ----------------------------------- |
| **Type**  | TXT                                 |
| **Name**  | `send.yourdomain.com`               |
| **Value** | Provided on your domain detail page |
| **TTL**   | 3600                                |

Since SendKit uses a subdomain (`send.yourdomain.com`), it doesn't add to your root domain's lookup count.

## Common SPF issues

| Problem       | Cause                            | Fix                                                  |
| ------------- | -------------------------------- | ---------------------------------------------------- |
| SPF permerror | More than 10 DNS lookups         | Reduce includes, use IPs, or split across subdomains |
| SPF softfail  | Sending server not in SPF record | Add the missing `include` or IP                      |
| SPF none      | No SPF record found              | Add the SPF TXT record to your DNS                   |
| SPF temperror | DNS timeout during lookup        | Usually transient — retry. Check your DNS provider   |

## FAQ

<AccordionGroup>
  <Accordion title="Can I have multiple SPF records for the same domain?">
    No. A domain must have exactly **one** SPF TXT record. If you have multiple, SPF evaluation will fail. Combine all authorized senders into a single record.
  </Accordion>

  <Accordion title="Does SPF check the 'From' header?">
    No. SPF checks the **envelope sender** (Return-Path), not the visible "From" header. This is why SPF alone isn't enough — you need DKIM and DMARC to protect the "From" address that recipients see.
  </Accordion>

  <Accordion title="What's the difference between ~all and -all?">
    `~all` (soft fail) tells receiving servers that unauthorized senders should be treated with suspicion but not rejected. `-all` (hard fail) tells them to reject unauthorized senders outright. Start with `~all` and move to `-all` when you're confident in your setup.
  </Accordion>
</AccordionGroup>
