Skip to main content

Email Deliverability Setup — Custom Domain with SPF, DKIM, DMARC

1. Overview

Current setup: Resend with default shared sending domain (noreply@agentix.app). Target: Custom sending subdomain (mail.agentix.app) with full email authentication — SPF, DKIM, and DMARC. Why this matters:
  • Custom domain improves deliverability and inbox placement
  • Prevents transactional emails from being classified as spam
  • SPF/DKIM authenticate that emails genuinely originate from Agentix
  • DMARC adds a policy layer with aggregate reporting for monitoring
Emails sent by Agentix (via Better Auth + Resend):
  • Verification email (signup)
  • Password reset email

2. Prerequisites

  • Resend account with API key (RESEND_API_KEY already configured)
  • DNS access for the agentix.app domain (registrar or DNS provider)
  • Railway environment variable access (to update FROM_EMAIL)

3. Step 1 — Add Domain in Resend

  1. Navigate to Resend Dashboard > Domains > Add Domain
  2. Enter: mail.agentix.app
    • Use a subdomain (mail.), not the root domain — keeps the root domain clean for website/corporate email
  3. Select region (use the same region as your Resend API key)
  4. Resend will generate DNS records to add (SPF TXT + DKIM CNAMEs)

4. Step 2 — Configure SPF (Sender Policy Framework)

SPF tells receiving mail servers which IP addresses are authorized to send email on behalf of mail.agentix.app. Resend provides the SPF record when you add the domain. Add the DNS TXT record:
FieldValue
Hostmail.agentix.app (or mail depending on DNS provider)
TypeTXT
ValueThe SPF record Resend provides (typically v=spf1 include:amazonses.com ~all since Resend uses AWS SES)
TTL3600 (1 hour) or DNS provider default
Important: If Resend provides a different SPF include value, use exactly what they show in the dashboard. Wait for DNS propagation (usually 5-30 minutes, can take up to 48 hours). Verify locally:
dig TXT mail.agentix.app
Expected output should contain the SPF record value.

5. Step 3 — Configure DKIM (DomainKeys Identified Mail)

DKIM adds a cryptographic signature to outbound emails, proving the message was not altered in transit and genuinely originated from the domain. Resend generates three CNAME records for DKIM signing. Add all three DNS CNAME records exactly as shown in the Resend dashboard:
FieldValue
Hostresend._domainkey.mail.agentix.app (or as shown by Resend)
TypeCNAME
ValuePoints to Resend’s DKIM key servers
Plus two additional CNAME records for key rotation — copy each record from the Resend dashboard precisely. Critical: Typos in CNAME records will break DKIM validation. Copy-paste exactly. Wait for DNS propagation. Verify locally:
dig CNAME resend._domainkey.mail.agentix.app

6. Step 4 — Verify Domain in Resend

  1. Return to Resend Dashboard > Domains
  2. Click Verify next to mail.agentix.app
  3. All records should show green checkmarks (SPF TXT + 3 DKIM CNAMEs)
  4. If verification fails:
    • Double-check DNS records for typos
    • Wait longer for propagation
    • Some DNS providers add the root domain automatically (e.g., entering mail becomes mail.agentix.app)
Local verification commands:
dig TXT mail.agentix.app
dig CNAME resend._domainkey.mail.agentix.app

7. Step 5 — Configure DMARC (Domain-based Message Authentication, Reporting & Conformance)

DMARC ties SPF and DKIM together with a policy that tells receiving servers what to do with unauthenticated mail, and where to send aggregate reports. Add the DNS TXT record:
FieldValue
Host_dmarc.mail.agentix.app (or _dmarc.mail depending on DNS provider)
TypeTXT
Valuev=DMARC1; p=none; rua=mailto:dmarc-reports@agentix.app; pct=100
TTL3600 (1 hour) or DNS provider default
Start with p=none (monitoring mode) — this collects reports without rejecting any emails. This is critical for safely rolling out DMARC. Verify locally:
dig TXT _dmarc.mail.agentix.app
Expected output: v=DMARC1; p=none; rua=mailto:dmarc-reports@agentix.app; pct=100

8. Step 6 — Update FROM_EMAIL Environment Variable

Once the domain is verified in Resend:
  1. In Railway dashboard > API service > Variables:
    • Change FROM_EMAIL from:
      Agentix Team <noreply@agentix.app>
      
    • To:
      Agentix Team <noreply@mail.agentix.app>
      
  2. Redeploy the API service for the change to take effect
  3. No code changes needed — auth.ts reads process.env.FROM_EMAIL at runtime

9. Verification Checklist

After completing all steps, verify end-to-end:
  • Resend dashboard shows mail.agentix.app domain as Verified
  • dig TXT mail.agentix.app returns the SPF record
  • dig CNAME resend._domainkey.mail.agentix.app returns the DKIM CNAME
  • dig TXT _dmarc.mail.agentix.app returns the DMARC record
  • Send a test email (trigger password reset or signup verification flow)
  • Check email headers in Gmail: Show Original > look for:
    • spf=pass
    • dkim=pass
    • dmarc=pass
  • Use mail-tester.com to score deliverability (aim for 9+/10)

10. Troubleshooting

SPF fails

  • Check TXT record is on the correct subdomain (mail.agentix.app, not agentix.app)
  • Verify you used exactly the SPF value Resend provided
  • Check for duplicate TXT records on the same subdomain

DKIM fails

  • Ensure all three CNAME records are added exactly as shown in Resend
  • Check for trailing dots in CNAME values (some DNS providers require them, others don’t)
  • CNAME records can take longer to propagate than TXT records

DMARC fails

  • Ensure _dmarc prefix is correct for your DNS provider
  • Some providers need _dmarc.mail (without the root domain appended)
  • Verify no conflicting DMARC record exists on the parent domain

Emails still going to spam

  • Check if domain is on any blacklists: mxtoolbox.com/blacklists
  • Verify email content doesn’t trigger spam filters (avoid ALL CAPS, excessive links)
  • Check that Reply-To header is set (some spam filters penalize no-reply addresses)
  • Allow 24-48 hours after DNS changes for reputation to build

11. DMARC Policy Upgrade Path

DMARC enforcement should be rolled out gradually:
TimelinePolicyDNS ValueEffect
Week 0 (now)p=nonev=DMARC1; p=none; rua=mailto:dmarc-reports@agentix.app; pct=100Monitor only — collect reports, don’t reject
Week 2-4ReviewCheck DMARC aggregate reports at dmarc-reports@agentix.app
After clean reportsp=quarantinev=DMARC1; p=quarantine; rua=mailto:dmarc-reports@agentix.app; pct=100Suspicious mail goes to spam
After 2 more weeks cleanp=rejectv=DMARC1; p=reject; rua=mailto:dmarc-reports@agentix.app; pct=100Unauthenticated mail is rejected
How to read DMARC reports:
  • Reports arrive as XML attachments to dmarc-reports@agentix.app
  • Use a DMARC report analyzer like dmarcian.com or postmark DMARC
  • Look for: sources sending as your domain, SPF/DKIM pass rates, any unauthorized senders

References