How each product brand maps to one app host, how to add a brand, and the checklist for the cutover from the api, docs and sample hosts to path routing.
One deployment serves every product brand. Each brand has one app.<brand> host, and the REST API, the MCP server and these docs are paths on it: /api, /mcp and /docs. The decision and its trade-offs are in ADR 0011.
The brand registry in packages/foundation/src/brands.ts lists the hosts per environment. The environment comes from VERCEL_ENV: production on main, development on develop, and local everywhere else.
| Brand | Production | Development | Local |
|---|---|---|---|
| CentraKit | app.centrakit.com | app.centrakit.dev | app.localhost |
| MechUp | app.mechup.com | mechup.centrakit.dev | mechup.localhost |
| StableDock | app.stabledock.app | stabledock.centrakit.dev | stabledock.localhost |
| Caresly | app.caresly.app | caresly.centrakit.dev | caresly.localhost |
| PropDock | none yet | propdock.centrakit.dev | propdock.localhost |
| MarryDuck | none yet | marryduck.centrakit.dev | marryduck.localhost |
| SignalDock | none yet | signaldock.centrakit.dev | signaldock.localhost |
| Spacelio | none yet | spacelio.centrakit.dev | spacelio.localhost |
| LegalDock | none yet | legaldock.centrakit.dev | legaldock.localhost |
The apex and www domains (centrakit.com, mechup.com, stabledock.app and caresly.app) host each brand's public website on Lovable. They point there through DNS and are not Vercel domains. A host that is not in the registry, such as a generated *.vercel.app deployment URL, renders the default brand.
A brand without a production domain, such as PropDock, lists no production host. brandAppHost and brandUrls then fall back to the default brand's host, which serves every tenant, so its organizations open on app.centrakit.com until the brand gets its own domain.
Each organization belongs to one brand (organizations.brand). The CentraKit host lists and opens the organizations of every brand, so the platform team manages all tenants from app.centrakit.com and app.centrakit.dev. A product brand host such as app.mechup.com lists and opens only its own organizations. Platform admins move an organization to another brand from its detail page in /admin/organizations.
brandIds and brands in packages/foundation/src/brands.ts, with its name, description, website, hosts per environment and assets. Set shadcnPreset when the brand has its own theme.https://<host>/** for its hosts to additional_redirect_urls in supabase/config.toml, under [auth] for local and under [remotes.main.auth] and [remotes.develop.auth].dev:portless:brands script.apps/saas/lib/brand/fonts.ts.apps/saas/public/brands/<id>/ (and the mark to apps/docs/public/brands/<id>/), then point the registry's assets at them.packages/ui/src/styles/brands.css and its hex twins to brandThemeColors in packages/ui/src/lib/brand-chrome.ts.DESIGN.md.Work through these steps for production (main) and repeat them with the development hosts for develop.
app.centrakit.com on the project and add app.mechup.com, app.stabledock.app and app.caresly.app as production domains.app.centrakit.dev on the develop branch and add mechup.centrakit.dev, stabledock.centrakit.dev, caresly.centrakit.dev, propdock.centrakit.dev, marryduck.centrakit.dev, signaldock.centrakit.dev, spacelio.centrakit.dev and legaldock.centrakit.dev to the same branch.api.centrakit.com, docs.centrakit.com, sample.centrakit.com, centrakit.com and www.centrakit.com, and their .dev counterparts. The cutover has no redirects from the old hosts.NEXT_PUBLIC_SITE_URL from the production and preview environments. Hosts come from the registry there, and the variable only overrides the default brand's origin in the local environment.app.mechup.com, app.stabledock.app and app.caresly.app at Vercel with the record the Vercel domain settings show.www host at Lovable with the records from the Lovable custom domain settings.api, docs and sample records once the old hosts are off the Vercel project.supabase/config.toml lists every brand host in additional_redirect_urls for main and develop. The Supabase GitHub integration applies it when the change reaches each branch. Confirm the list under Authentication, URL Configuration in the dashboard afterwards.site_url plus /oauth/consent, so it stays on the CentraKit host for every brand./api/v1/email/supabase/auth on app.centrakit.com (and app.centrakit.dev for develop).https://api.centrakit.com/api/mcp to https://app.<brand>/mcp. Tokens are accepted for the /mcp URL of every brand host in the environment, Supabase's default authenticated audience and MCP_RESOURCE_AUDIENCE.MCP_RESOURCE_AUDIENCE to https://api.centrakit.com/api/mcp so tokens issued for the old resource keep working after a client switches its URL. Tell MCP users to update their server URL, then remove the value once those tokens have been replaced.https://app.centrakit.com/api and takes --host for another brand.mechup.com, stabledock.app and caresly.app to the authorized domains if the screen or the client lists URLs on those domains. The consent screen still shows the CentraKit app name.https://app.centrakit.com/api/v1/billing/stripe/webhook in live mode, and to the app.centrakit.dev URL for the test mode endpoint develop uses. The signing secret does not change unless you create a new endpoint./api/v1/email/resend/webhook on the app host.EMAIL_FROM address, with the brand name as the sender name. Before a brand sends from its own domain, verify that domain in Resend (SPF, DKIM and DMARC)./api/v1/public/webhooks/{token}) and REST clients move from api.centrakit.com to the organization's brand host. Tell the owners of existing integrations to update them.Run these checks on every brand host, for example https://app.mechup.com:
/login renders the brand's name and mark, and signing in lands on an organization of that brand./api/v1/health answers from the API./mcp answers 401 with a WWW-Authenticate header whose resource_metadata points at /.well-known/oauth-protected-resource on the same host./.well-known/oauth-protected-resource returns "resource": "https://<host>/mcp"./docs, /docs/developers/mcp.md, /llms.txt and /docs/mcp serve the docs, and /api-docs redirects to /docs/developers/api./robots.txt and /docs/sitemap.xml load, and the sitemap lists pages on the canonical docs origin. Submit the sitemaps in Google Search Console for each brand host.api.*, docs.* and sample.* hosts no longer resolve to the deployment./admin/organizations.Last updated on