DomaineeDocs

Embeddable widget

Drop-in connect UI, so you don't build the DNS setup screen yourself.

The widget is the whole last mile of a custom-domain setup as one script tag: provider detection, the record written the way that provider's form wants it, step-by-step instructions, the provider's own gotchas, one-click setup where it's available, and automatic polling until the domain goes live.

<div id="domain-setup"></div>
<script src="https://domainee.dev/widget.js"></script>
<script>
  Domainee.mount('#domain-setup', {
    token: '<connect session token from your server>',
    onVerified: function (domain) {
      window.location.reload();
    },
  });
</script>

Getting a token

Never put an sk_live_ key in a browser. It is workspace-wide and anyone can read it in devtools. The widget refuses to start if you pass one.

Instead, mint a connect session on your server. It is scoped to one domain, expires quickly, and can only reach that domain's setup endpoints:

curl -X POST https://api.domainee.dev/v1/domains/$DOMAIN_ID/connect-session \
  -H "Authorization: Bearer $DOMAINEE_API_KEY" \
  -H "content-type: application/json" \
  -d '{ "ttlSeconds": 3600 }'
{
  "connectSession": {
    "token": "dmn_cs_eyJ3Ijoi…",
    "expiresAt": "2026-09-09T18:36:15.000Z",
    "domainId": "8f09b47c-…",
    "hostname": "acme.com"
  }
}

Hand token to the browser. The widget reads the domain id out of it, so you don't pass one separately.

What the token can do

Only these, and only for its own domain:

GET /v1/domains/{id}read status
GET /v1/domains/{id}/instructionsthe setup steps
POST /v1/domains/{id}/checkre-probe DNS
POST /v1/domains/{id}/dns/applywrite records with a customer token

Everything else returns 403, including listing domains, deleting one, touching a different domain, and minting another session. The allowlist is enforced centrally, so a route added later is not reachable by default.

Tokens are signed rather than stored, so they cannot be revoked before they expire. Keep ttlSeconds short. The default is one hour; the maximum is 24.

Options

OptionRequiredNotes
tokenyesThe connect session token.
apiBaseDefaults to https://api.domainee.dev.
hostnameShown while the first request is in flight.
onVerifiedCalled once when the domain goes live.

mount() returns { destroy(), refresh() }. Call destroy() when unmounting in a single-page app, or the poll keeps running.

Behaviour

  • Polls every 15 seconds and stops as soon as the domain verifies.
  • Where the DNS provider has enabled our Domain Connect templates (Cloudflare, for example), the widget shows a one-click button above the records. The records and steps stay visible, so a customer who would rather add them by hand still can.
  • The button opens the provider's approval screen in a popup, or a new tab if the browser blocks popups. When the customer comes back to your page, the widget re-checks the domain straight away and twice more over the next 30 seconds, so onVerified fires without waiting for the next poll.
  • If provider detection fails, it still shows correct generic records rather than an error.
  • An expired token renders "this setup link has expired" rather than a blank panel, so mint a fresh one on page load.

Styling

Styles are inlined, so the widget can't restyle your page and your CSS can't break it. There is deliberately no theming API yet. If you need the setup UI to match your product exactly, build it against GET /v1/domains/{id}/instructions, which returns everything the widget renders.

On this page