Domain Forwarding API

One CNAME from your customer.
Programmatic 301s from you.

Per-customer domain forwarding with edge TLS. 301 or 302, path and query preserved by default, status flippable with a single PATCH. The endpoint registrar-level forwarders should have been.

50 customer hostnames free, forever. TLS issued on every source domain.

301 + 302
status codes supported
HTTPS
on every source hostname
1 PATCH
to retire a forwarder
~30ms
warm redirect, edge-side

Trusted by teams building the future of SaaS

  • Common Ninja
  • Embeddable
  • Vidocu
  • Brackets Ninja

Why API forwarding over registrar forwarding

301 + 302, programmatic per customerPATCH mode

Set permanent or temporary redirects via API. PATCH a single field to switch a customer's domain from forwarding to masking, or retire a vanity URL with one call. No DNS-only forwarders, no opaque registrar UI.

TLS on the source domain, automaticLet's Encrypt

Registrar-level forwarding ships HTTP — your customer's https://old.acme.com fails. We issue TLS for the source hostname so the redirect happens over HTTPS, browser stays happy, SEO juice passes correctly.

Path + query preservation, your callpreservePath + preserveQuery

Choose to carry /pricing?ref=twitter from old.acme.com to new.acme.com, or strip everything to land on a clean target URL. Default behavior matches what you'd expect (preserve both); toggle off when you're consolidating to a single page.

Why this doesn't belong at the registrar: registrar-level forwarding is per-domain, manual, HTTP-only, and stuck inside each registrar's UI. A SaaS product giving forwarding to its customers needs one programmatic API, edge TLS, and the ability to flip a redirect into a proxy without re-doing DNS. Same code path, different mode.

Forward · then flip · then retire

One API. Three operations.

Create a 301, swap it to 302, switch to masking, or delete entirely — same hostname, same TLS cert, different behavior.

Step 1 — Create the forwarder

Set mode: redirect with a target

mode: "redirect" + a destination URL. Status defaults to 301; path + query preserved by default.

curl — register a forwarder
$ curl https://api.domainee.dev/v1/domains \
    -H "Authorization: Bearer sk_live_…" \
    -H "Content-Type: application/json" \
    -d '{
      "hostname":       "old.acme.com",
      "mode":           "redirect",
      "targetUrl":      "https://new.acme.com",
      "redirectStatus": 301,
      "preservePath":   true,
      "preserveQuery":  true
    }'

{
  "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 — Flip status or retire

One PATCH, no DNS change

Switch 301 → 302, change the target, or convert to masking. The hostname, TLS cert, and DNS stay; only the edge rule changes.

curl — flip behavior
# Make it temporary
$ curl -X PATCH https://api.domainee.dev/v1/domains/f7a2… \
    -H "Authorization: Bearer sk_live_…" \
    -d '{ "redirectStatus": 302 }'

# Convert to a masked proxy instead
$ curl -X PATCH https://api.domainee.dev/v1/domains/f7a2… \
    -H "Authorization: Bearer sk_live_…" \
    -d '{ "mode": "proxy",
          "originUrl": "https://acme.fly.dev" }'

# Retire entirely
$ curl -X DELETE https://api.domainee.dev/v1/domains/f7a2… \
    -H "Authorization: Bearer sk_live_…"

What teams use forwarding for.

Most teams hit two or three of these in their first year. Same endpoint, same workspace, same Bearer key.

Rebrands

oldbrand.com permanently moves to newbrand.com with a clean 301 + path preservation. Every link out in the wild lands on the right destination, search rank transfers.

Vanity / campaign URLs

promo.acme.com points at acme.com/campaigns/spring. Per-customer, programmatic, retire-able with one PATCH call.

Domain consolidation

Your customer owns five typo-domains. Forward all of them to the canonical one. Search engines pick one signal, customers always land in the right place.

Legacy URL retirement

Help center moved? Forward help.oldproduct.com to docs.newproduct.com/legacy. Keep the old hostname alive for stragglers without maintaining two copies of the content.

Forward vs mask

Same API. One field.

Forward changes the URL bar; mask keeps it. Switch between modes with a single PATCH — no re-issued cert, no new DNS.

mode: “redirect”

Forward — URL changes

Visitor types old.acme.com, gets a 301 to new.acme.com. Address bar updates. The default for rebrands, vanity URLs, and legacy retirements.

mode: “proxy”

Mask — URL stays

Visitor types shop.acme.com, address bar stays there forever. See Domain Masking API for the dedicated page.

FAQ

Common questions

What's the difference between 301 and 302?
301 is permanent — browsers cache it aggressively, and Google passes SEO authority from the source to the destination. Use 301 for rebrands, consolidations, anything that won't revert. 302 is temporary — browsers re-check the source on every visit, and Google doesn't transfer authority. Use 302 for short campaigns, A/B tests, or anywhere you might flip back. Domainee defaults to 301; set redirectStatus: 302 to override.
Does the source domain need TLS?
Yes, and we handle it for you. The visitor's browser opens an HTTPS connection to your customer's source hostname (old.acme.com), the edge presents a valid Let's Encrypt cert for it, then we serve the 301/302 over HTTPS. Most registrar-level forwarders skip this and ship HTTP — modern browsers warn or block, and the redirect fails before it lands.
Does forwarding preserve query strings and paths?
By default, yes — both. preservePath: true carries /pricing from old.acme.com/pricing to new.acme.com/pricing. preserveQuery: true carries ?ref=twitter through. Set either to false to strip and land on a clean URL. The PATCH endpoint flips them in place without re-issuing the cert.
Will Google pass authority from the old domain to the new one?
Yes, for 301 redirects with matching content. Google treats a 301 as a signal that the source has permanently moved; ranking signals transfer to the destination over a few crawls. 302 doesn't transfer — use 301 for any rebrand or consolidation where you want SEO continuity.
Can I redirect to a path on the destination, not just the root?
Yes. Set targetUrl to https://new.acme.com/welcome and every request to the source hostname lands on /welcome. Combine with preservePath: true to append the visitor's original path on top: a hit on old.acme.com/about becomes new.acme.com/welcome/about.
Can the source be an apex domain (acme.com, not www.acme.com)?
Yes. Apex pointing requires the registrar to support ALIAS / ANAME / Cloudflare CNAME-flattening, or an A record to our edge IPs. POST /v1/domains returns both record options in dnsRecords so your customer can pick whichever their registrar supports.
How do I switch a customer from forwarding to masking, or vice versa?
One PATCH. PATCH /v1/domains/{id} with mode: "proxy" flips a forwarder into a masked tenant; mode: "redirect" goes the other way. The hostname, TLS cert, and DNS record stay the same — only the edge behavior changes. Useful when a customer rebrands mid-flight or wants to A/B a redirect against a real landing page.
How fast is the redirect?
One round-trip to the nearest edge POP (multi-region, latency-routed). On a warm connection the 301 response is sub-30ms. The destination request then resolves from the visitor's browser at whatever your destination's normal latency is.

Forward your first hostname today.

50 customer hostnames free, no card. The first 301 fires within a minute of the CNAME resolving.