Skip to content
Docs

Multi-Tenant Platform Quickstart

Watch the walkthrough on YouTube.

This guide walks you through setting up domains for your multi-tenant application. There are two main approaches:

If you want to offer subdomains like tenant.acme.com, you'll need to:

  1. Configure wildcard domains for subdomains like *.acme.com

If you want to allow tenants to use their own domains, you'll need to:

  1. Enable custom domain support for your tenants
  2. Add domains programmatically using the Vercel SDK
  3. Verify domain ownership with TXT records
  4. Configure domain redirects and handle SEO
  5. Clean up domains when tenants leave

You can implement either approach or both depending on your needs.

If you plan on offering subdomains like *.acme.com, add a wildcard domain to your Vercel project. Vercel needs access to DNS challenges to issue and renew wildcard SSL certificates. To configure the domain with Vercel's nameservers:

  1. Point your domain to Vercel's nameservers (ns1.vercel-dns.com and ns2.vercel-dns.com).
  2. In your Vercel project settings, add the apex domain (e.g., acme.com).
  3. Add a wildcard domain: *.acme.com.

If you can't change your domain's nameservers, follow Use wildcard domains with an external DNS provider to delegate certificate validation and configure wildcard traffic routing.

Now, any tenant subdomain you create, such as tenant1.acme.com or tenant2.acme.com, resolves to your Vercel deployment. Vercel issues one wildcard certificate for *.acme.com that covers every tenant subdomain at that level, so you don't need a certificate per tenant. A wildcard certificate covers only one subdomain level. To serve a deeper subdomain such as docs.tenant1.acme.com over HTTPS, add a wildcard domain for that level, such as *.tenant1.acme.com, which gets its own wildcard certificate.

If tenants can publish content or run code on your subdomains, submit your shared domain to the Public Suffix List so browsers isolate cookies between tenants for improved security. Follow the steps for protecting tenant subdomains with the Public Suffix List.

The following steps guide you through setting up custom domain support for your tenants. This allows them to use their own domains (e.g., customacmesite.com) instead of subdomains.

You can also give tenants the option to bring their own domain. In that case, you'll want your code to:

  1. Provision and assign the tenant's domain to your Vercel project.
  2. Verify the domain (to ensure the tenant truly owns it).
  3. Automatically generate an SSL certificate.

You can add a new domain through the Vercel SDK. For example:

add-domain.ts
import { VercelCore as Vercel } from '@vercel/sdk/core.js';
import { projectsAddProjectDomain } from '@vercel/sdk/funcs/projectsAddProjectDomain.js';
 
const vercel = new Vercel({
  bearerToken: process.env.VERCEL_TOKEN,
});
 
// The 'idOrName' is your project name in Vercel, for example: 'multi-tenant-app'
await projectsAddProjectDomain(vercel, {
  idOrName: 'my-multi-tenant-app',
  teamId: 'team_1234',
  requestBody: {
    // The tenant's custom domain
    name: 'customacmesite.com',
  },
});

Once the domain is added, Vercel attempts to issue an SSL certificate automatically. Each custom domain gets its own certificate, separate from your wildcard certificate.

If the domain is already in use on Vercel, the user needs to set a TXT record to prove ownership of it.

You can check the verification status and trigger manual verification:

verify-domain.ts
import { VercelCore as Vercel } from '@vercel/sdk/core.js';
import { projectsGetProjectDomain } from '@vercel/sdk/funcs/projectsGetProjectDomain.js';
import { projectsVerifyProjectDomain } from '@vercel/sdk/funcs/projectsVerifyProjectDomain.js';
 
const vercel = new Vercel({
  bearerToken: process.env.VERCEL_TOKEN,
});
 
const domain = 'customacmesite.com';
 
const [domainResponse, verifyResponse] = await Promise.all([
  projectsGetProjectDomain(vercel, {
    idOrName: 'my-multi-tenant-app',
    teamId: 'team_1234',
    domain,
  }),
  projectsVerifyProjectDomain(vercel, {
    idOrName: 'my-multi-tenant-app',
    teamId: 'team_1234',
    domain,
  }),
]);
 
const { value: result } = verifyResponse;
 
if (!result?.verified) {
  console.log(`Domain verification required for ${domain}.`);
  // You can prompt the tenant to add a TXT record or switch nameservers.
}

Some tenants might want www.customacmesite.com to redirect automatically to their apex domain customacmesite.com, or the other way around.

  1. Add both customacmesite.com and www.customacmesite.com to your Vercel project.
  2. Configure a redirect for www.customacmesite.com to the apex domain by setting redirect: customacmesite.com through the API or your Vercel dashboard.

This ensures a consistent user experience and prevents issues with duplicate content.

If you offer both tenant.acme.com and customacmesite.com for the same tenant, you may want to redirect the subdomain to the custom domain (or vice versa) to avoid search engine duplicate content. Alternatively, set a canonical URL in your HTML <head> to indicate which domain is the "official" one.

If a tenant cancels or no longer needs their custom domain, you can remove it from your Vercel account using the SDK:

remove-domain.ts
import { VercelCore as Vercel } from '@vercel/sdk/core.js';
import { projectsRemoveProjectDomain } from '@vercel/sdk/funcs/projectsRemoveProjectDomain.js';
import { domainsDeleteDomain } from '@vercel/sdk/funcs/domainsDeleteDomain.js';
 
const vercel = new Vercel({
  bearerToken: process.env.VERCEL_TOKEN,
});
 
await Promise.all([
  projectsRemoveProjectDomain(vercel, {
    idOrName: 'my-multi-tenant-app',
    teamId: 'team_1234',
    domain: 'customacmesite.com',
  }),
  domainsDeleteDomain(vercel, {
    domain: 'customacmesite.com',
  }),
]);

The first call disassociates the domain from your project, and the second removes it from your account entirely.

Last updated September 15, 2026

Was this helpful?

supported.