# SPF Record Generator

Generate an SPF (RFC 7208) TXT record from structured choices: mail providers (Google Workspace, Microsoft 365, SendGrid, Mailchimp, Amazon SES and more), custom includes, your own IPv4/IPv6 addresses or networks, mx/a, and a policy qualifier (~all, -all, ?all) or redirect. Inputs are validated and normalised; returns the record, TXT strings split at 255 bytes, a zone-file line, the DNS-lookup count against the limit of 10 (marked as an estimate when included services are opaque) and warnings. Pure calculation, no DNS queries.

**Not for:** Checking a published SPF record (use spf_check).

- Tool id: `spf-generator`
- Category: email
- Execution: pure
- MCP tool `spf_generate` at https://lookupowl.com/mcp
- REST `GET https://lookupowl.com/api/v1/tools/spf-generator` (or POST a JSON body)
- OpenAPI: https://lookupowl.com/api/openapi.json

## Input

| Field | Type | Required | Default | Description |
|---|---|---|---|---|
| `domain` | string | no |  | Your domain, e.g. example.com. Optional: used for the zone-file line and publishing notes. URLs, e-mail addresses and Unicode names are reduced to the ASCII domain. max length 253 |
| `providers` | "amazon-ses" \| "brevo" \| "cloudflare-email-routing" \| "constant-contact" \| "fastmail" \| "godaddy" \| "google-workspace" \| "mailchimp" \| "mailgun" \| "mandrill" \| "microsoft-365" \| "postmark" \| "proton-mail" \| "salesforce" \| "sendgrid" \| "sparkpost" \| "zendesk" \| "zoho-mail"[] | no |  | Mail services that send as your domain; each adds its documented include. Known ids: amazon-ses, brevo, cloudflare-email-routing, constant-contact, fastmail, godaddy, google-workspace, mailchimp, mailgun, mandrill, microsoft-365, postmark, proton-mail, salesforce, sendgrid, sparkpost, zendesk, zoho-mail. max 20 items |
| `includes` | string[] | no |  | Extra domains to include (include:<domain>) for services not in the provider list. max 20 items |
| `ip4` | string[] | no |  | Your own IPv4 addresses or networks, e.g. 192.0.2.10 or 203.0.113.0/24. max 50 items |
| `ip6` | string[] | no |  | Your own IPv6 addresses or networks, e.g. 2001:db8::/32. max 50 items |
| `includeMx` | boolean | no | `false` | Authorize the servers in your MX records (mx). |
| `includeA` | boolean | no | `false` | Authorize the A/AAAA address of your domain (a). |
| `redirect` | string | no |  | Delegate the whole policy to another domain (redirect=domain) instead of ending with an "all" qualifier. max length 253 |
| `all` | "~all" \| "-all" \| "?all" | no | `"~all"` | What receivers should do with mail from other servers: ~all softfail (recommended while testing), -all fail (strictest), ?all neutral (no protection). |

## Output

Results are wrapped in an envelope: `tool`, `version`, `requestId`, `data`, `summary`, `meta` (cache status, timing), `permalink`. `data` has these fields:

| Field | Type | Description |
|---|---|---|
| `domain` | string |  |
| `host` | string | TXT record name: "@" (the domain itself) when no domain was given, else the domain. |
| `record` | string | The complete SPF record value. |
| `length` | integer | Record length in bytes. min -9007199254740991, max 9007199254740991 |
| `chunks` | string[] | The record split into DNS character-strings of at most 255 bytes (one entry when it fits). |
| `zoneLine` | string | A ready-to-paste zone-file line. |
| `terms` | string[] |  |
| `lookups` | object |  |
| `providers` | object[] |  |
| `valid` | boolean |  |
| `issues` | object[] |  |
| `notes` | string[] |  |

## Examples

### Google Workspace only

```json
{"domain":"example.com","providers":["google-workspace"],"includeMx":false,"includeA":false,"all":"~all"}
```

```bash
curl 'https://lookupowl.com/api/v1/tools/spf-generator?all=%7Eall&domain=example.com&includeA=false&includeMx=false&providers=google-workspace'
```

Web page: https://lookupowl.com/spf-record-generator?q=example.com&providers=google-workspace

### Microsoft 365 plus SendGrid, strict

```json
{"providers":["microsoft-365","sendgrid"],"includeMx":false,"includeA":false,"all":"-all"}
```

```bash
curl 'https://lookupowl.com/api/v1/tools/spf-generator?all=-all&includeA=false&includeMx=false&providers=microsoft-365&providers=sendgrid'
```

Web page: https://lookupowl.com/spf-record-generator?all=-all&providers=microsoft-365&providers=sendgrid

### Your own mail servers

```json
{"domain":"example.org","ip4":["203.0.113.0/28"],"ip6":["2001:db8:25::/48"],"includeMx":true,"includeA":false,"all":"-all"}
```

```bash
curl 'https://lookupowl.com/api/v1/tools/spf-generator?all=-all&domain=example.org&includeA=false&includeMx=true&ip4=203.0.113.0%2F28&ip6=2001%3Adb8%3A25%3A%3A%2F48'
```

Web page: https://lookupowl.com/spf-record-generator?q=example.org&all=-all&includeMx=true&ip4=203.0.113.0%2F28&ip6=2001%3Adb8%3A25%3A%3A%2F48

## Web pages

- https://lookupowl.com/spf-record-generator

## Limits and caching

- Cost: 1 unit for a live lookup, 1 unit for a cached one. Budgets are per network and published in the `RateLimit` response headers.
- Cache: results are kept for 86400 s.
- Timeout: 1 s.

## Related tools

- [SPF Record Checker](https://lookupowl.com/tools/spf-checker.md): Check a domain's SPF record, count its DNS lookups against the limit of 10 and find errors.
- [DMARC Record Generator](https://lookupowl.com/tools/dmarc-generator.md): Build a valid DMARC record, with report authorization records and a step-by-step rollout plan.
- [DMARC Record Checker](https://lookupowl.com/tools/dmarc-checker.md): Look up and validate a domain's DMARC policy, report addresses and alignment settings.

## Guide: SPF record generator

Tick the services you send mail with and we'll write a correct SPF record.

### What the generator does

Choose the services that send mail as your domain, add your own servers if you have any and pick how the record should end. The generator writes the SPF record, gives you a zone-file line (the plain-text format DNS servers store records in), shows how many of the 10 allowed DNS lookups the record uses and warns you about anything that would cause trouble. Because the record is built from your choices, its syntax is always right.

An SPF record is one line of text in your DNS, but a small mistake in it can quietly break delivery. The limit of 10 DNS lookups is one of the most common ways a record fails, which is why the generator counts them.

The generator makes no DNS requests, so it does not know what your DNS already holds. If you already have an SPF record, merge the new terms into it. Your choices go to our server, which builds the record. They are not part of our routine logs and are held in memory for at most a day. On the website, Google Analytics also records what you enter, as the [privacy policy](https://lookupowl.com/privacy) explains.

### How to build your record

1. **Choose your mail services**: Pick every service that sends mail as your domain. The list has 18, among them Google Workspace, Microsoft 365, SendGrid, Mailchimp, Amazon SES, Mailgun, Postmark, Zoho Mail and Fastmail. Each one adds the include its provider documents. For a service that is not listed, type its include domain under Other includes.
2. **Add your own servers**: Enter IPv4 or IPv6 addresses or networks for mail you host yourself. Turn on "Allow my MX servers" or "Allow my domain's A record" only if those hosts really send mail.
3. **Pick the ending**: The "Everything else" menu says what happens to mail from every other server. `~all` (softfail, the default) marks it as suspicious, `-all` (fail) asks receivers to reject it and `?all` (neutral) makes no statement. The questions below explain which to use. If another domain already holds your full policy, the advanced option "Redirect to another domain" hands the decision to it and the record needs no ending.
4. **Publish it**: Create one TXT record on your domain, with the host shown as `@` in most panels, and paste in the generated value. Delete or merge any older SPF record. Then check the result with the [SPF checker](https://lookupowl.com/spf-record-checker) once DNS has updated.

> **In Claude, ChatGPT or Cursor** Connect the LookupOwl MCP server and ask: “Write an SPF record for example.com that sends through Google Workspace and SendGrid.” The assistant calls `spf_generate`, and can follow with `spf_check` once you have published.

### Understanding the output

For a domain that sends through Google Workspace and SendGrid, with a softfail ending, the generator produces:

```text
v=spf1 include:_spf.google.com include:sendgrid.net ~all
```

- **The record and its length.** Terms always come in the same order: `mx`, `a`, `ip4`, `ip6`, your includes, then the ending. A record longer than 255 bytes is also shown as several quoted strings inside one TXT record, together with a zone-file line.
- **The lookup count.** Each `include`, `a`, `mx` and `redirect` costs one lookup, plus whatever the included record uses itself. The generator has those inner counts for only a few services, from a snapshot taken when it was built, and providers change their records. When any are unknown, or you add an include of your own, the count is shown as a minimum. Publish the record and run the SPF checker for the exact number.
- **Warnings and errors.** Warnings cover `?all`, private or loopback addresses that receivers will never see, a record with 8 or more lookup terms and a record longer than 450 bytes. Errors cover invalid addresses and prefixes and a record that needs more than 10 lookups. A record with an error is not shown, so you cannot copy it by mistake. Duplicate terms are removed for you.
- **The host name.** The record belongs on the domain itself, shown as `@` in most DNS panels.

### Mistakes to avoid when publishing

- **Adding a second SPF record.** Edit the existing one. Two records are invalid, and receivers ignore both.
- **Forgetting a sender.** Invoicing tools, CRMs, ticket systems and web forms often send as your domain. Look at the headers of your sent mail before you move to `-all`.
- **Using too many services.** Past 10 lookups the generator refuses to show a record. Move bulk senders to a subdomain such as `news.example.com` with its own SPF record, or remove services you no longer use.
- **Using `a` or `mx` out of habit.** They add lookups and may allow servers that never send mail.
- **Listing a private address.** An address such as `10.0.0.5` never appears as the sender of mail from the internet. List the public address of your mail server instead.
- **Letting the DNS host change the value.** Some panels need the value in quotes and others add them. Some want a long value split into 255-byte parts. Check what was published with a [TXT lookup](https://lookupowl.com/txt-lookup).
- **Expecting subdomains to inherit.** SPF does not pass from a parent domain to its subdomains. Each domain that appears in the return path needs its own record. A subdomain that never sends mail can publish `v=spf1 -all`.

> **Do the next step too** SPF is one of three parts. Turn on DKIM signing at your mail provider, then publish a [DMARC record](https://lookupowl.com/dmarc-record-generator). The guide to [SPF, DKIM and DMARC](https://lookupowl.com/learn/spf-dkim-dmarc-explained) explains how they fit together.

### How it works

The generator cleans your input (lowercase domains, standard IP notation, no stray spaces), checks each term against RFC 7208 and writes the record. It adds the lookup terms in your record to the inner counts it knows for each listed service. If a service's inner count is unknown, the total is marked as a minimum. The same function runs behind the REST API and the MCP server.

### Standards

- **RFC 7208**: SPF syntax, qualifiers, the limit of 10 lookups and the rule that a domain publishes one record. It also dropped the separate SPF record type, so SPF lives in TXT records.
- **RFC 1035**: TXT records and the 255-byte limit of one character string. RFC 7208 joins the strings of a TXT record with nothing between them.
- **RFC 5321**: the SMTP envelope sender that SPF checks.

### Frequently asked questions

**How do I create an SPF record?**

Pick your sending services and servers, choose an ending (`~all` or `-all`) and copy the generated line. Publish it as a TXT record on your domain, then check it with the [SPF checker](https://lookupowl.com/spf-record-checker). If you already have an SPF record, add the new `include:` and `ip4:` terms to it instead of creating a second record.

**Where do I put the SPF record?**

Put it in your domain's DNS zone as a TXT record on the domain itself, often shown as `@`. It is not a separate record type. RFC 7208 dropped the old dedicated SPF type, so receivers read only the TXT record. Add it wherever your DNS is managed, which is usually your registrar or hosting provider.

**Can I combine Google Workspace and another service?**

Yes. Select both. They become separate `include` terms in one record, and the generator shows how many lookups the pair uses. Add as many services as you need, as long as the total stays at 10 or below. If it does not, send bulk mail from a subdomain.

**What does include:_spf.google.com do?**

It tells receivers to also accept the servers listed in Google's own SPF record. Google maintains that record, so you do not have to track its addresses. The include costs one DNS lookup, plus any lookups inside Google's record. Prefer the include your provider documents over a copy of its IP addresses, which goes stale.

**Should I use ~all or -all?**

Start with `~all` while you confirm that every sender is included, then move to `-all` if you want strict failure. Once DMARC is enforcing, `~all` is common and enough, because receivers then follow your DMARC policy. The generator offers `~all`, `-all` and `?all`, and uses `~all` unless you choose otherwise.

**How do I make an SPF record for a domain that sends no email?**

Leave every service and address empty and choose `-all`. The generator gives you `v=spf1 -all`, which tells receivers that no server may send mail as the domain. Publish it on parked domains and on subdomains that never send mail, together with a [DMARC record](https://lookupowl.com/dmarc-record-generator) of `p=reject`.

**Does the generator check whether my providers are really configured?**

No, it only builds the record. It never looks at your DNS or your mail setup. After publishing, use the [SPF checker](https://lookupowl.com/spf-record-checker) to validate the record against live DNS, and send a test message from each service to confirm it passes.
