Skip to main content

Creating a new tenant

Paid Feature

This is a paid feature.

For self hosted users, Sign up to get a license key and follow the instructions sent to you by email. Creation of tenants is free on the dev license key.

This feature is already enabled for managed service users. Creation of additional tenant is free on the provided development environment.

import Multitenancy from "supertokens-node/recipe/multitenancy";

async function createNewTenant() {
let resp = await Multitenancy.createOrUpdateTenant("customer1", {
firstFactors: ["emailpassword", "thirdparty", "otp-email", "otp-phone", "link-phone", "link-email"]
});

if (resp.createdNew) {
// Tenant created successfully
} else {
// Existing tenant's config was modified.
}
}

The snippet creates a new tenant with the id "customer1". It enables the email password, third party and passwordless login methods for this tenant. You can also disable any of these by not including them in the firstFactors input. If firstFactors is not specified, by default, none of the login methods are enabled.

If you set firstFactors to null the SDK uses any of the login methods.

The built-in Factor IDs that can be used for firstFactors are:

Authentication TypeFactor ID
Email password authemailpassword
Social login / enterprise SSO auththirdparty
Passwordless - Email OTPotp-email
Passwordless - SMS OTPotp-phone
Passwordless - Email magic linklink-email
Passwordless - SMS magic linklink-phone

Providing additional configuration per tenant

You can also configure a tenant to have different configurations as per the core's config.yaml or docker environment variables. Below is how you can specify the config, when creating or modifying a tenant:

import Multitenancy from "supertokens-node/recipe/multitenancy";

async function createNewTenant() {

let resp = await Multitenancy.createOrUpdateTenant("customer1", {
coreConfig: {
"email_verification_token_lifetime": 7200000,
"password_reset_token_lifetime": 3600000,
"postgresql_connection_uri": "postgresql://localhost:5432/db2",
}
});

if (resp.createdNew) {
// new tenant was created
} else {
// existing tenant's config was modified.
}
}

In the above example, different values are assigned for certain configurations for customer1 tenant. All other configurations inherit from the base configuration.

Notice the postgresql_connection_uri. This allows you to achieve data isolation on a tenant level. This configuration is not required. If not provided, the tenant's information is stored in the database as specified in the core's configuration. It is still a different user pool though.

Once you have set the configs for a specific tenant, you can fetch the tenant info as shown below:

import Multitenancy from "supertokens-node/recipe/multitenancy";

async function getTenant(tenantId: string) {

let resp = await Multitenancy.getTenant(tenantId);

if (resp === undefined) {
// tenant does not exist
} else {
let coreConfig = resp.coreConfig;

let firstFactors = resp.firstFactors;

let configuredThirdPartyProviders = resp.thirdParty.providers;
}
}

The returned coreConfig is the same as what we had set when creating / updating the tenant. The rest of the core configurations for this tenant are inherited from the app's (or the public tenant) config. The public tenant, for the public app inherits its configs from the config.yaml / docker environment variables values.

Next steps

Checkout the "Setting up login for tenants" page for next steps in integrating multi tenancy.