SPF for Developers

Understand SPF from a developer perspective. Learn how to set up SPF for application email, use subdomains for different environments, automate DNS management, and test SPF records.

Your App Sends Email but You Never Set Up SPF

You built the authentication flow, integrated SendGrid, and your app sends beautiful password reset emails. In development, everything works. In staging, everything works. In production, users say they never got the verification email. You check the SendGrid dashboard — delivered. But "delivered" means the receiving server accepted the connection, not that the message reached the inbox. Without SPF, your app's emails are unauthenticated, and unauthenticated email gets filtered.

The Developer SPF Problem

As a developer, email authentication is probably not the first thing on your mind. You chose an email API, wrote the integration code, and tested that messages get sent. But SPF lives in the DNS layer, outside your application code, and it's easy to overlook.

Here's what developers commonly run into:

  • You set up SendGrid or SES in your app but nobody added the SPF record to DNS
  • Your staging and production environments send from different domains or subdomains, each needing separate SPF records
  • You deploy a new service that sends email (monitoring alerts, cron job notifications) and forget to update SPF
  • Multiple microservices send email through different providers, and the SPF record needs to cover all of them
  • Infrastructure-as-code deploys everything except DNS records, creating a gap in your automation

SPF is a DNS TXT record, not an application-level configuration. No matter which language, framework, or email API you use, SPF setup happens in your domain's DNS — not in your code.

How SPF Creator Helps

Quick record generation

Select your email providers, get a valid record, paste it into DNS. No need to read RFC 7208 to understand SPF syntax.

Multi-environment support

Generate separate SPF records for production, staging, and development subdomains. Each environment gets its own authentication.

Provider presets

SendGrid, Amazon SES, Mailgun, Postmark — all pre-configured. Select from the list instead of searching provider documentation.

Lookup counter

When your microservices use different email providers, the lookup count adds up fast. SPF Creator tracks it in real time.

Monitor your application's email authentication

Track SPF, DKIM, and DMARC across all your environments. Get alerts before users report missing emails.

Start Monitoring

Setting Up SPF for Application Email

1

Inventory your sending services

Check your codebase and infrastructure for every service that sends email from your domain. This includes your email API (SendGrid, SES), your corporate email (Google Workspace), monitoring tools, and any SaaS that sends notifications as your domain.

2

Generate the SPF record

Open SPF Creator and add each provider. For self-hosted services (like a Postfix relay), add the server IP directly using ip4: mechanisms.

3

Set up subdomain records if needed

If staging sends from staging.yourdomain.com and production from yourdomain.com, create separate SPF records for each. Use SPF Creator to generate both.

4

Add to DNS (or your IaC)

Add the TXT record to your DNS provider. If you use Terraform, Pulumi, or CloudFormation for DNS, add the SPF record to your infrastructure code so it's versioned and reproducible.

5

Test with real messages

Trigger actual emails from your application (password resets, welcome emails) and inspect the headers. Look for Authentication-Results: spf=pass in the raw message headers. You can also verify your record programmatically using SPF Record Check.

Using Subdomains for Different Environments

One SPF record per domain means you can't easily separate concerns on a single domain. Subdomains solve this.

# Production: yourdomain.com
v=spf1 include:_spf.google.com include:sendgrid.net ~all

# Staging: staging.yourdomain.com
v=spf1 include:sendgrid.net ~all

# Transactional: mail.yourdomain.com
v=spf1 include:amazonses.com ~all

# Marketing: marketing.yourdomain.com
v=spf1 include:servers.mcsv.net ~all

Subdomain isolation

Subdomains don't inherit SPF records from the parent domain. Each subdomain that sends email needs its own SPF TXT record. This is actually useful — it lets you isolate email reputation per environment or use case.

Benefits of the subdomain approach:

  • Each subdomain gets a fresh 10-lookup budget
  • A deliverability problem on your marketing subdomain doesn't affect transactional email
  • You can use ~all in staging and -all in production
  • Infrastructure-as-code can manage subdomain records independently

Automating SPF with Infrastructure as Code

If you manage DNS through Terraform, here's what the resource looks like:

resource "aws_route53_record" "spf" {
  zone_id = aws_route53_zone.main.zone_id
  name    = ""
  type    = "TXT"
  ttl     = 300
  records = ["v=spf1 include:_spf.google.com include:sendgrid.net ~all"]
}

For CloudFormation:

SPFRecord:
  Type: AWS::Route53::RecordSet
  Properties:
    HostedZoneId: !Ref HostedZone
    Name: !Ref DomainName
    Type: TXT
    TTL: 300
    ResourceRecords:
      - '"v=spf1 include:_spf.google.com include:sendgrid.net ~all"'

TXT record values in CloudFormation and Terraform need to be wrapped in escaped quotes. The actual DNS value must be enclosed in double quotes. Missing these quotes is a common source of deployment failures.

While you're automating DNS, consider adding DKIM keys and a DMARC policy to your IaC templates as well. All three records (SPF, DKIM, DMARC) should be part of your infrastructure baseline for any domain that sends email.

Testing SPF Records

Command-line testing

# Check the SPF record for a domain
dig TXT yourdomain.com +short | grep spf

# On Windows
nslookup -type=TXT yourdomain.com

# Check what a specific include resolves to
dig TXT _spf.google.com +short

Programmatic testing

Most email APIs include headers in webhook payloads. Check the Authentication-Results header:

Authentication-Results: mx.google.com;
  spf=pass (google.com: domain of user@yourdomain.com designates 167.89.123.45 as permitted sender)

If you see spf=fail or spf=softfail, your SPF record doesn't cover the sending IP.

Common Developer Pitfalls

MistakeImpactFix
Forgetting SPF during deployAll app email unauthenticatedAdd SPF record to IaC templates
Not covering all environmentsStaging email fails SPFCreate SPF records per subdomain
Exceeding 10 lookupsSPF returns permerrorUse subdomains or ip4 mechanisms
Adding a second SPF recordBoth records invalidMerge into one TXT record
Hardcoding -all too earlyLegitimate email rejectedStart with ~all, switch after testing

Pricing

Free

$0

  • Up to 3 items
  • Email alerts
  • Basic support

Pro

$9/month

  • Unlimited items
  • Email + Slack alerts
  • Priority support
  • API access

Monitor Your New SPF Record

You've created your SPF record — now make sure it keeps working. The Email Deliverability Suite watches your SPF, DKIM, DMARC, and MX records daily and alerts you when something breaks.

Never miss an SPF issue

Monitor your SPF, DKIM, DMARC and MX records daily. Get alerts when something breaks.

Start Monitoring