CursivaDocs
Publish & access

Custom domain and white-label

Every organization gets a Cursiva address the day it is created, and can graduate to its own domain. This page explains the two addresses your school lives at, how to connect your own, and the one invisible seam — login — that keeps the white-label experience seamless.

The org subdomain and public storefront

The moment an organization exists it is reachable at its own subdomain: {slug}.cursiva.io, where slug is the organization's slug. All host-based routing happens at the edge (in proxy.ts): a request to acme.cursiva.io is rewritten into that organization's /[org]/… routes, so the school never has to configure anything to go live.

A handful of subdomains are reserved and can never be taken as an org slug — www, app, api, docs, cdn, assets, and mail. Everything else under cursiva.io that resolves to a single label is treated as an org slug.

Two public surfaces are built from the organization's published catalog:

SurfaceRouteWhat it shows
Storefront/[org] (served at {slug}.cursiva.io)The organization's branding — logo, name, bio — over its published, listed courses as cards.
Explore/exploreThe cross-organization marketplace: every published, listed course on Cursiva.

The storefront lists only content that is published and listed for that organization, drawn from listPublished, with review stars per course. A visitor who lands there sees the school's own page; the Explore all button links out to the shared /explore catalog.

Connecting your own domain

An organization can serve its storefront and courses from a domain it owns — escola.com.br, courses.yourbrand.com — under Settings → Domains. You enter the domain, add two DNS records at your registrar, and Cursiva takes care of the rest.

The DNS records

Saving a domain produces exactly two records to add at your DNS provider, both with a TTL of 3600 (kept low so the change propagates fast enough for automatic verification):

TypeNameValuePurpose
CNAMEyour domain (e.g. escola.com.br)cname.vercel-dns.comPoints the domain at Cursiva's hosting so requests reach the app.
TXT_cursiva-verify.<your-domain>a unique verification tokenProves you own the domain before it goes live.

Each value has a copy button in the Domains card, so you can paste it straight into your registrar.

Automatic verification and TLS

Once the domain is saved but not yet verified, the Domains card polls your DNS automatically every few seconds — you never have to click anything. When the TXT record at _cursiva-verify.<domain> matches the expected token, Cursiva:

  1. Registers the domain on Vercel, which provisions and renews the TLS certificate and routes the host to the app.
  2. Marks the domain verified, and the card flips to a live confirmation linking to https://<your-domain>.

A manual Verify button is available too, for when you would rather not wait for the next poll. Until the records resolve, the card simply keeps checking and shows the pending DNS instructions.

Behind the scenes, the edge resolves an incoming custom-domain request to its organization and serves that org's public routes — the same /[org] storefront and course pages, just on your host.

The white-label learner experience

On a connected domain, a learner browses the catalog and takes the entire course on the school's own domain. Reading, progress, drip release, community — all of it happens at escola.com.br. There is one exception, and it is invisible: the login step runs on Cursiva and hands the session back.

Why login makes a detour

Two hard facts about the web force this design:

  • Cookies do not cross domains. A session cookie set on .cursiva.io is simply not sent to escola.com.br — the browser will not share it. Each domain needs its own cookie.
  • OAuth, 2FA, and passkeys are registered on the canonical host. Social sign-in redirect URLs, TOTP two-factor, and passkey credentials are all bound to Cursiva's own hostname. They cannot be re-registered per custom domain.

So authentication happens where it is set up — on the canonical {slug}.cursiva.io — and the result is carried back to the custom domain.

How the hand-off works

When a learner on the custom domain hits a login-related path, the edge sends them through a one-time-token bridge:

  1. The custom domain redirects the shared auth path to /sso/bridge on the canonical host {slug}.cursiva.io, carrying the target domain and where to land afterward (next).
  2. The bridge signs the learner in normally — here cookies live on .cursiva.io and OAuth works. If they are not signed in yet, it sends them to /login and returns to the bridge afterward.
  3. Once signed in, the bridge mints a one-time token and bounces the browser to /api/sso/consume on the custom domain.
  4. Consume verifies the token, lets Better Auth create the session, and re-scopes that cookie to this host only — dropping the .cursiva.io domain so it becomes a host-only cookie on escola.com.br.

From then on the learner is signed in on the custom domain and stays there for the whole course. The token is single-use and short-lived; an invalid or expired one simply returns the learner to the page, logged out.

What stays on Cursiva

The public, learner-facing experience is what white-labels. The admin dashboard does not: producers and staff always manage their school from Cursiva itself.

  • The dashboard (/dashboard) — the editor, learners, sales, insights, and settings — is served from the app host (app.cursiva.io) and gated on a session cookie. It is not rewritten onto custom domains.
  • Shared auth pages (/login, /signup, /two-factor, /accept-invitation, and the /sso bridge) render on the canonical .cursiva.io hosts, where the session cookie is valid across subdomains.

In short: learners live on your domain, the team works in Cursiva.

Keep exploring