How it works
Three phases. One API call to start them.
From the hostname a customer types to a live, HTTPS-terminated domain served at your edge, Custom Domain runs the whole path and reports every state along the way.
Watch state move to live via webhook or poll.
Detect & write
Your customer types theirbrand.com. We detect their DNS provider and write the records, or hand off a signed, provider-hosted one-click setup.
Verify ownership
A value-checked TXT record proves the customer actually controls the hostname. Verification is polled automatically and reported over the API and webhooks.
Go live
HTTPS issues automatically and the edge starts serving the domain, no manual certificate requests, ever.
Architecture
Two planes, deliberately separated
Custom Domain is two systems that share one database and talk only over HTTP. The control plane is the /v1 REST API, the four connection paths, the propagation poller, and webhooks. The edge plane terminates TLS and reverse-proxies traffic to your origin.
The API writes DNS and steps out, it is never in the proxied request path. Certificates issue in the TLS handshake and fail closed.
The only call the edge ever makes into the control plane is a single approval lookup during the TLS handshake, one indexed read, no joins, no billing logic. The two planes scale independently, and a bad day on one is not a bad day on the other.
Lifecycle
One state machine, reported over webhooks
Every connection walks the same states, and every transition fires an event your app can subscribe to, no polling loops in your codebase unless you want them.
POST /v1/connections
│ fires connection.created
▼
pending ───▶ propagating ───▶ live
│ │ fires connection.live
│ │
│ ├─ record_missing a required record dropped out of DNS
│ └─ record_restored ...and came back, serving resumes
│
└───▶ failed records never resolved, a retry re-opens the same setup
Retrying is always safe: creating a connection is idempotent per application and domain, so a failed or abandoned setup picks up where it left off.
Connection paths
Four ways the records get written
Every domain reaches live through one of four paths. You don't pick, the domain check reports the best path available at the customer's provider, and the widget drives it automatically.
PATH 01
OAuth into the provider
The customer approves access in a popup at their DNS host, and we write the records with a one-time token, used once, never stored. The default wherever the provider supports it.
PATH 02
Provider-hosted one-click setup
We hand the customer a signed link and their DNS provider applies the records itself. No token ever passes between servers. Used when the provider hosts the flow.
PATH 03
Bring your own token
Already hold a scoped API token for the zone? Send it with the apply call. It writes the records once and is discarded, unless you explicitly opt in to remembering it. Built for migrations and platforms with existing provider relationships.
PATH 04
Guided manual
The customer copies the exact records from the API or widget, and the propagation poller confirms them the moment they land. Works with every provider, the universal fallback.
Apex domains
Roots are special. Your code shouldn't care.
DNS forbids a CNAME at the root, here's how we support apex on every provider anyway. Where the host supports flattening (ALIAS, ANAME, CNAME flattening), we use it, and theirbrand.com behaves like any other hostname. Everywhere else we fall back to A records pointing at stable edge addresses. Subdomains stay a plain CNAME. The record set the API returns is already the right one for that provider, you never special-case the apex.
HTTPS
No chicken-and-egg on certificates
A certificate can't issue until DNS points at us, and once DNS points at us, traffic is already arriving. On-demand issuance closes that race: the first TLS handshake for a new hostname triggers issuance inside the handshake itself, and the certificate is cached and renewed from then on. A hostname that isn't approved gets no certificate at all, the edge fails closed instead of presenting a default.
What we never do
Never overwrite blindly. Existing records are detected and merged, never blindly overwritten, a conflicting record shows up in the plan before anything is written.
Never keep one-time tokens. Provider tokens from the OAuth path authorize a single write, then they're gone.
Never touch registrar passwords. No flow anywhere in the product asks a customer for one.
Go deeper
Get started →DOCS / CONCEPTS
Architecture
The two planes, the shared database, and the single internal call between them.
Read →
DOCS / CONNECT FLOW
Connect flow
The create → apply → live pipeline and the four paths that write DNS.
Read →
DOCS / DNS
DNS & providers
Records, apex flattening, and what each path needs across 25+ providers.
Read →