SOPs
Custom Domain Email — Cloudflare Routing + Resend + Gmail Alias
The Pattern
Section titled “The Pattern”Custom domain email without paying for Google Workspace or running a mail server. Three free pieces wired together:
- Cloudflare Email Routing — receives inbound mail on
@mytechsupport.comand forwards it toojhurst@gmail.com. - Resend — transactional email API. Handles outbound sending with DKIM-signed delivery that the big inboxes actually accept.
- Gmail “Send mail as” alias — lets Gmail compose and reply as
james@mytechsupport.comby routing outgoing messages through Resend’s SMTP relay.
End result: you write and read everything from your normal Gmail UI. Incoming mail lands in your regular inbox. Outgoing mail goes out as the custom address, DKIM-signed from your own domain. Zero monthly cost, zero servers.
Why Not Workspace
Section titled “Why Not Workspace”Google Workspace is $7/month per user per domain. For a single alias on a side project, that is $84/year to move bytes. The Cloudflare + Resend + Gmail stack delivers the exact same user-visible behavior for free because:
- Cloudflare Email Routing is free and handles unlimited inbound forwarding per zone.
- Resend’s free tier is 3,000 emails per month, which covers everything short of a real transactional product.
- Gmail already hosts your reading UI, and its “Send mail as” feature was designed precisely for this.
The one thing you give up is a dedicated IMAP mailbox for the custom address. All mail lives in the underlying Gmail account. For a side-domain address like james@mytechsupport.com that is a feature, not a bug.
Why Not Self-Host
Section titled “Why Not Self-Host”Running your own Postfix + Dovecot on a VPS technically works, but deliverability is the killer. VPS IP ranges from Hostinger, DigitalOcean, and similar providers are pre-blocked by Gmail and Outlook. You would need perfect SPF, DKIM, DMARC, reverse DNS, and weeks of IP warm-up before big inboxes will even accept your mail. Fun project, painful daily driver. Don’t.
Architecture Diagram
Section titled “Architecture Diagram” INBOUND OUTBOUND ------- -------- sender Gmail compose window │ │ │ MX │ SMTP (TLS, port 587) ▼ ▼ route1/2/3.mx.cloudflare.net smtp.resend.com │ │ │ Cloudflare Email Routing │ Resend │ rule: james@mts → ojhurst │ DKIM-signs with cf2024-1._domainkey ▼ ▼ ojhurst@gmail.com inbox recipient inboxInbound and outbound are fully independent paths. One breaking does not affect the other.
MTS Reference Configuration
Section titled “MTS Reference Configuration”This is the live setup for mytechsupport.com as of 2026-04-15. Use it as a template when adding the same pattern to another domain.
DNS Records
Section titled “DNS Records”All in the Cloudflare mytechsupport.com zone.
| Type | Name | Value | Purpose |
|---|---|---|---|
| MX | @ | route1.mx.cloudflare.net (prio 57) | Inbound — Cloudflare Email Routing |
| MX | @ | route2.mx.cloudflare.net (prio 51) | Inbound — Cloudflare Email Routing |
| MX | @ | route3.mx.cloudflare.net (prio 63) | Inbound — Cloudflare Email Routing |
| TXT | @ | v=spf1 include:resend.com include:_spf.mx.cloudflare.net ~all | SPF — authorizes Resend and Cloudflare |
| TXT | cf2024-1._domainkey | v=DKIM1; h=sha256; k=rsa; p=MIIBIjAN... | DKIM key for Resend |
| TXT | _dmarc | v=DMARC1; p=none; rua=mailto:reports@dmarc.jameshurst.com; | DMARC reporting |
Cloudflare’s Email Routing UI adds the MX records automatically when you enable it. Resend adds the SPF and DKIM records automatically when you verify the sending domain.
Cloudflare Email Routing Rules
Section titled “Cloudflare Email Routing Rules”Set in Cloudflare Dashboard → Email → Email Routing → Routes:
| Match | Action |
|---|---|
james@mytechsupport.com | Forward to ojhurst@gmail.com |
support@mytechsupport.com | Forward to ojhurst@gmail.com |
| Catch-all | (optional — forward or drop) |
Resend Domain Setup
Section titled “Resend Domain Setup”Dashboard → Domains → Add Domain → mytechsupport.com. Resend generates DKIM + SPF records for you. Paste them into Cloudflare DNS and click verify.
Once verified, Resend will accept SMTP auth from any address at the domain — no per-address setup.
Gmail “Send Mail As” Alias
Section titled “Gmail “Send Mail As” Alias”Gmail Settings → Accounts and Import → Send mail as → Add another email address:
| Field | Value |
|---|---|
| Name | James Hurst |
| Email address | james@mytechsupport.com |
| Treat as an alias | UNCHECKED |
| SMTP Server | smtp.resend.com |
| Port | 587 |
| Username | resend |
| Password | Resend API key (e.g., re_xxxxxxxx...) |
| Secured connection | TLS |
Unchecking “Treat as an alias” is important. When checked, Gmail merges outgoing mail as if it came from the same person — replies get threaded under your Gmail identity. Unchecked, james@mytechsupport.com is treated as a separate sender identity, which is what you want when the address represents a different context or brand.
After clicking Add Account, Gmail sends a confirmation link to the custom address. Cloudflare Email Routing forwards that email to your real Gmail inbox. Click the confirmation link and the alias is live.
Required Secrets
Section titled “Required Secrets”| Name | Where stored | Used by |
|---|---|---|
RESEND_MTS | shared-secrets.env | Gmail SMTP auth, MTS Vercel env (RESEND_API_KEY) |
The same Resend key is used for both the Gmail alias and the production MyTechSupport.com Next.js app’s transactional email (RESEND_API_KEY in Vercel). Rotating the key requires updating both places — see the rotation checklist below.
Rotation Checklist
Section titled “Rotation Checklist”When a Resend key is leaked or needs to be rotated:
- Create a new key in the Resend dashboard with the same permissions (Sending access is enough for this use case).
- Update
shared-secrets.env:Terminal window python3 ~/apps/cc/secrets/secrets_cli.py add RESEND_MTS 're_new_value' - Update
.env.localin the mytechsupport repo with the new value. - Update all three Vercel environments (production, preview, development):
Terminal window cd ~/apps/mytechsupportfor ENV in production preview development; dovercel env rm RESEND_API_KEY $ENV --yesprintf '%s' 're_new_value' | vercel env add RESEND_API_KEY $ENVdone - Bump build number and push — this triggers a Vercel redeploy so production picks up the new key from its env vars. Key changes alone do not redeploy.
- Update the Gmail alias password — Gmail Settings → Accounts → edit the Send mail as entry and paste the new key into the SMTP password field.
- Verify production email is working by triggering a test send (e.g., a password reset).
- Verify Gmail alias is working by sending a test message as
james@mytechsupport.com. - Revoke the old key in the Resend dashboard.
Do not revoke the old key until you have confirmed all three consumers (Vercel production, Gmail alias, shared-secrets) are on the new one. Otherwise you will get delivery failures that are hard to correlate.
Troubleshooting
Section titled “Troubleshooting”| Symptom | Cause | Fix |
|---|---|---|
| Sent mail disappears, no bounce | Gmail alias using stale SMTP password | Update the Send mail as SMTP password to the current Resend key |
Bounce: 550 5.7.26 ... DKIM/SPF | DKIM record missing or wrong | Re-verify domain in Resend dashboard, confirm Cloudflare DNS matches |
Bounce: 421 unable to verify sender | SPF record missing include:resend.com | Add resend.com to the SPF record at the zone apex |
| Inbound mail not forwarding | Cloudflare routing rule missing or address not added | Check Cloudflare → Email → Email Routing → Routes |
| Gmail verification email never arrives | Cloudflare routing rule for the custom address is missing | Add the forwarding rule before clicking “Add Account” in Gmail |
| Gmail shows “could not authenticate” | Wrong username | Username is literally the string resend, not the email address |
Extending to Other Domains
Section titled “Extending to Other Domains”To add the same pattern for a new domain (e.g., hello@newdomain.com):
- Add the domain to Cloudflare and let it manage DNS.
- Enable Email Routing on the zone — Cloudflare adds the MX records.
- Add a routing rule for the custom address pointing to your real Gmail.
- Add the domain to Resend — paste Resend’s SPF and DKIM records into Cloudflare DNS.
- Add a “Send mail as” alias in Gmail using
smtp.resend.comand a Resend API key (reuse the existing key or create a new one for audit isolation). - Save the key to shared-secrets with a domain-specific name if you made a new one (e.g.,
RESEND_NEWDOMAIN).
The same Resend account can send from any number of verified domains on its free tier. No per-domain charges.
Related
Section titled “Related”- Notify-James Pattern — how scripts under
~/apps/actually call Resend to fire alerts (the helper, the from-address, the existing callers) - Cloudflare Pages deploy SOP
- Resend dashboard
- Cloudflare Email Routing docs