Domain Forwarding in 2026: 301s, 302s, and an API to Do It at Scale
Domain forwarding is the most-implemented and least-talked-about feature in the custom-domain stack. It's also the one most people get wrong, because they outsource it to whatever the registrar offers.
This post: what forwarding actually is, when to use 301 vs 302, why registrar-level forwarding falls over on HTTPS, and how to add programmatic per-customer forwarding to your SaaS.
Forwarding vs masking vs DNS pointing
Three things people conflate:
| The visitor types | The address bar shows | Mechanism | |
|---|---|---|---|
| Forwarding | old.com | new.com (after redirect) | HTTP 301/302 |
| Masking (proxy) | shop.acme.com | shop.acme.com (stays) | Server-side reverse proxy |
| DNS pointing | shop.acme.com | shop.acme.com | DNS record points the hostname at the same origin |
Forwarding tells the browser to go somewhere else. Masking keeps the visitor on the typed URL while serving content from elsewhere. DNS pointing is just an address record — same origin, no redirect.
This post is about the first one.
301 vs 302: it matters more than people think
The HTTP status code in the redirect response is the SEO call:
- 301 Moved Permanently — browsers cache it aggressively. Google passes ranking signals from the source URL to the destination. Use this for rebrands, domain consolidations, anything that won't revert.
- 302 Found (temporary) — browsers re-check the source on every request. Google treats the source as the canonical URL and doesn't transfer authority. Use this for short campaigns, A/B tests, geo splits, or anywhere you might flip back.
Real-world rule: if you'd be sad if the source domain disappeared from search results, use 301. If you'd be sad if the destination took over the source's ranking, use 302. They're not interchangeable.
// 301: move forever
{ "redirectStatus": 301 }
// 302: testing, might revert
{ "redirectStatus": 302 }
Why registrar-level forwarding falls over
Most registrars offer domain forwarding for free — Namecheap, GoDaddy, Cloudflare Registrar all have a checkbox. Here's why it's not enough for a SaaS:
It's HTTP only. The registrar-issued forwarder ships plain HTTP. Modern browsers warn (or block) navigation from https:// to http://, and Google treats HTTPS as the canonical form. Your 301 chain breaks before the redirect lands.
It's per-domain, manual, GUI-only. You can't programmatically forward 50 customer domains from your SaaS — your customer has to log into their registrar and click a checkbox. Most don't. Support load follows.
It can't be flipped. Registrar forwarding doesn't have an API for "now switch this to masking instead." When your customer rebrands again, they're back in the registrar UI deleting the rule.
It often serves the redirect from a slow far-away IP. No edge presence, no latency optimization. A redirect that costs 400ms at p95 isn't great for SEO crawlers or buyer-flow.
The fix: programmatic forwarding with edge TLS. One API, one CNAME, full HTTPS, PATCH-able.
Architecture
[ visitor: https://old.acme.com/pricing ]
|
v TLS handshake (cert for old.acme.com)
[ Domainee edge ]
|
v responds 301
Location: https://new.acme.com/pricing
|
v
[ visitor's browser follows ]
|
v
[ new.acme.com — your real origin ]
The edge holds a valid Let's Encrypt cert for old.acme.com. When a visitor hits it, the edge responds with a 301 (or 302) pointing at the target URL. Path and query are preserved by default; both are toggleable per-domain.
Tutorial: forward via API
Step 1 — Register the source hostname in redirect mode:
$ curl https://api.domainee.dev/v1/domains \
-H "Authorization: Bearer sk_live_…" \
-d '{
"hostname": "old.acme.com",
"mode": "redirect",
"targetUrl": "https://new.acme.com",
"redirectStatus": 301,
"preservePath": true,
"preserveQuery": true,
"metadata": { "customerId": "acme-42" }
}'
The response gives you a CNAME record to hand to your customer:
{
"domain": {
"id": "f7a2…",
"hostname": "old.acme.com",
"mode": "redirect",
"targetUrl": "https://new.acme.com",
"redirectStatus": 301,
"status": "pending",
"dnsRecords": [
{ "type": "CNAME",
"name": "old.acme.com",
"value": "edge.domainee.dev" }
]
}
}
Step 2 — Customer adds the CNAME. TLS provisions automatically. Domain goes live in about a minute.
Step 3 — Flip behavior with one PATCH:
# Switch to temporary (302) for an A/B test
$ curl -X PATCH https://api.domainee.dev/v1/domains/f7a2… \
-H "Authorization: Bearer sk_live_…" \
-d '{ "redirectStatus": 302 }'
# Change destination
$ curl -X PATCH https://api.domainee.dev/v1/domains/f7a2… \
-H "Authorization: Bearer sk_live_…" \
-d '{ "targetUrl": "https://new.acme.com/welcome" }'
# Convert to masking (proxy) instead of redirect
$ curl -X PATCH https://api.domainee.dev/v1/domains/f7a2… \
-H "Authorization: Bearer sk_live_…" \
-d '{ "mode": "proxy",
"originUrl": "https://acme.fly.dev" }'
Hostname, TLS cert, and DNS stay the same across all of these. Only the edge behavior changes.
SEO tips for 301s
A few things that bite teams running rebrands:
Match destination paths to source paths. A 301 from old.com/pricing to new.com/ loses the path-level signal. Either preserve the path (default in Domainee) or build a path mapping at the destination. Don't 301 everything to the root.
Don't chain redirects. old.com → new.com → newer.com loses authority on each hop and trips Google's crawl budget. If you've migrated twice, point the original directly at the current home.
Keep the source alive forever after a rebrand. Yes, forever. The 301 is what tells search engines (and old bookmarks) where you went. Delete the source domain three years later and you lose every backlink that pointed at it. The $10/year for the registration is cheap insurance.
Verify with curl, not the browser. Browsers cache 301s aggressively. After a config change, test with curl -I https://old.acme.com to see actual headers; the browser might be showing you yesterday's redirect from cache.
Use cases at scale
A SaaS that adds programmatic forwarding usually hits two or three of these in the first year:
- Rebrands. Customer renamed their company. Old domain redirects to new. 301 + path preservation.
- Vanity URLs.
promo.acme.com→acme.com/campaigns/spring-2026. Campaign-scoped, retired after. - Domain consolidation. Customer owns three typo variants. All redirect to the canonical.
- Help-center migrations.
help.oldproduct.com→docs.newproduct.com/legacy. The old hostname stays alive but every visitor lands on the new tree. - Country splits.
acme.com→acme.defor German visitors (geo-based 302).
Same API, same workspace, one Bearer key. The decision isn't "do I need forwarding sometimes" — it's "do my customers need forwarding sometimes." Usually yes.
Ship it
The Domain Forwarding API is one POST per hostname, full edge TLS, PATCH-able status, path and query preserved by default. 50 customer hostnames free, no card.
If your customers also need masking (URL stays put while serving your content), see Domain Masking API. Same API, different mode.