
Your customer's domain.
Your content. No iframe.
Server-side reverse-proxy at the edge: the visitor stays on shop.acme.com while your app serves the response. No address-bar flips, no SEO penalty, no iframe breakage. One CNAME, one API call per hostname.
50 customer hostnames free, forever. No card to start.
Trusted by teams building the future of SaaS
Modern masking, not the iframe trick
Our edge accepts the visitor's TLS connection on your customer's hostname, forwards the request to your origin server-side, and streams the response back. The browser sees one document on one hostname. Iframe masking embeds your origin inside the customer's domain — different surface, broken cookies, broken history, empty frame to crawlers.
Identical content to crawlers and humans (because there's only one response). Google indexes your customer's hostname directly, your customer's content ranks under their domain. Iframe masking ships an empty page to crawlers; proxy masking ships the real one.
document.location, fetch, cookies, history, WebSockets — all behave as if the app was deployed natively at the customer's hostname. We don't rewrite HTML or inject scripts. The only thing in the middle of the request is our edge.
Why people still call this “masking”: the visitor sees their typed URL throughout — that's the outcome iframe masking was trying to achieve. We deliver the outcome via the right mechanism (edge proxy), so you get the UX without any of the iframe baggage.
POST hostname, GET edge routing + TLS.
Register a customer hostname in proxy mode and we'll provision the edge, issue the TLS cert, and start routing traffic to your origin the moment the CNAME lands.
Set mode: proxy for masking
mode: "proxy" is the default. Visitors keep your customer's URL in the address bar; your origin serves the response.
$ curl https://api.domainee.dev/v1/domains \
-H "Authorization: Bearer sk_live_…" \
-H "Content-Type: application/json" \
-d '{
"hostname": "shop.acme.com",
"originUrl": "https://acme-tenant-42.fly.dev",
"mode": "proxy",
"keepHost": true,
"metadata": { "tenantId": "acme-42" }
}'
{
"domain": {
"id": "8f09b47c-…",
"status": "pending",
"mode": "proxy",
"dnsRecords": [
{ "type": "CNAME",
"name": "shop.acme.com",
"value": "edge.domainee.dev" }
]
}
}One DNS record, then it's live
Your customer adds one CNAME at their registrar pointing at our edge. TLS provisions automatically. We fire a webhook the moment the hostname goes live so your dashboard can flip from “pending” to “live” without polling.
POST https://app.your-saas.com/webhooks/domainee
X-Domainee-Signature: t=1716800000,v1=…
{
"id": "evt_01j…",
"type": "domain.verified",
"data": {
"domain": {
"id": "8f09b47c-…",
"hostname": "shop.acme.com",
"status": "verified",
"verifiedAt": "2026-05-28T10:14:08Z",
"metadata": { "tenantId": "acme-42" }
}
}
}Who masks domains.
Anywhere your customer's URL matters more than yours. White-label products, multi-tenant SaaS, creator platforms.
Storefront builders
Sellers want their store on shop.acme.com, not yourplatform.com/acme. Mask their domain to your store renderer, keep checkout on their URL.
Course / membership platforms
School operators want learn.theirschool.com to look like theirs end-to-end. Mask their domain to your course player, the URL never gives you away.
Link-in-bio + creator pages
Creators bring a vanity domain; you serve the page. They get bio.creator.com, you keep one app and one deploy.
Help center / docs
Customers want help.theirbrand.com to feel native. Mask to your docs renderer, keep their support URL clean.
Which mode for which job?
Same API, one field changes. Mask when the customer's URL should stay put. Forward when you're retiring or consolidating a domain.
Mask — URL stays
Visitor types shop.acme.com, address bar stays as shop.acme.com forever. Edge proxies to your origin. The default for white-label SaaS.
Forward — URL changes
Visitor types old.acme.com, gets a 301 to new.acme.com. Address bar updates. See Domain Forwarding API for the dedicated page.
Common questions
- How is this different from an iframe?
- An iframe loads your page inside the customer's domain in the browser — the address bar lies, but the actual request goes to your origin, search engines see an empty frame, JS context is split, and cookies, history, and back/forward all break. Domain masking via reverse-proxy is different: the visitor's request goes to our edge over their hostname, we forward it to your origin server-side, and the response comes back as a real HTTP response on their domain. Browser, search engines, and your JS all see a single first-class document.
- Will Google penalize masked content?
- No. Cloaking — what Google penalizes — is showing different content to crawlers and humans. Reverse-proxy masking serves identical content to both. The content is genuinely served at the customer's URL, indexed normally. Treat it the same as if you'd hosted their site directly — because that's what's happening.
- Will my React/Next/SPA app break?
- No, because the visitor's browser never knows it's been proxied. document.location is the customer's hostname, fetch() resolves their domain, cookies are scoped correctly, WebSockets connect over their host. The only thing different from running on your own domain is that requests transit our edge — which is one extra ~30-50ms TLS hop, no JS rewriting.
- What about absolute URLs in my responses?
- Pass them through unchanged. If your app emits links to its own absolute URLs, they'll work fine — the visitor is already on the customer's hostname, so a link to /pricing resolves correctly. If you emit your own internal URLs (like https://yourplatform.com/...), those go to your platform's domain — which is usually the right behavior for things like signup links.
- Can the customer's apex (acme.com, not www) be masked?
- Yes. Apex pointing requires the registrar to support ALIAS / ANAME / Cloudflare CNAME-flattening, or an A record to our edge IPs. We surface both record options in the dnsRecords response from POST /v1/domains so your customer can pick whichever their registrar supports.
- What about WebSockets and streaming responses?
- Both work. Our edge is HTTP/1.1 + HTTP/2 with WebSocket upgrade support and streaming (chunked + SSE). Long-lived connections route the same way as normal requests.
- What's the latency cost?
- One additional TLS hop. Our edge is multi-region (currently us-west-2 + eu-central-1 with latency-based routing), so for most visitors the edge is ~30-50ms away. The added latency on a cold connection is roughly one round-trip; warm connections are negligible. If your origin is also at the edge (Cloudflare Workers, Vercel, Fly), you pay this twice — for most apps it's still imperceptible.
- Can I mix masked and forwarded domains?
- Yes. Each domain you register has a mode field: proxy (mask, address bar stays) or redirect (forward, address bar changes). Set per hostname, change with one PATCH. Most platforms use proxy for primary white-label and redirect for legacy URL retirements.
Mask your first customer hostname today.
50 hostnames free, no card. The first CNAME goes live in about a minute.


