Tenants with SDKs
If you wish to learn more about Tenants in general, see the Tenants page.
Descopers (Descope admins) can create and update tenants either manually in the Descope Console, using the Tenant Management APIs, or using our Management SDKs as shown below.
Tenant management using the management SDK
Backend SDK
Install SDK
npm i --save @descope/node-sdkpip3 install descopego get github.com/descope/go-sdk// Include the following in your `pom.xml` (Maven)
<dependency>
<artifactId>java-sdk</artifactId>
<groupId>com.descope</groupId>
<version>sdk-version</version> // Check https://github.com/descope/descope-java/releases for the latest versions
</dependency>gem install descopecomposer require descope/descope-phpdotnet add package DescopeImport and initialize SDK
import DescopeClient from '@descope/node-sdk';
try{
// baseUrl="<URL>" // When initializing the Descope client, you can also configure the baseUrl ex: https://auth.company.com - this is useful when you utilize a custom domain within your Descope project.
const descopeClient = DescopeClient({ projectId: '__ProjectID__' });
} catch (error) {
// handle the error
console.log("failed to initialize: " + error)
}
from descope import (
REFRESH_SESSION_TOKEN_NAME,
SESSION_TOKEN_NAME,
AuthException,
DeliveryMethod,
DescopeClient,
AssociatedTenant,
RoleMapping,
AttributeMapping,
LoginOptions
)
try:
# You can configure the baseURL by setting the env variable Ex: export DESCOPE_BASE_URI="https://auth.company.com - this is useful when you utilize custom domain within your Descope project."
descope_client = DescopeClient(project_id='__ProjectID__')
except Exception as error:
# handle the error
print ("failed to initialize. Error:")
print (error)import "github.com/descope/go-sdk/descope"
import "github.com/descope/go-sdk/descope/client"
// Utilizing the context package allows for the transmission of context capabilities like cancellation
// signals during the function call. In cases where context is absent, the context.Background()
// function serves as a viable alternative.
// Utilizing context within the Descope GO SDK is supported within versions 1.6.0 and higher.
import (
"context"
)
// DescopeBaseURL // within the client.Config, you can also configure the baseUrl ex: https://auth.company.com - this is useful when you utilize a custom domain within your Descope project.
descopeClient, err := client.NewWithConfig(&client.Config{ProjectID:"__ProjectID__"})
if err != nil {
// handle the error
log.Println("failed to initialize: " + err.Error())
}import com.descope.client.Config;
import com.descope.client.DescopeClient;
var descopeClient = new DescopeClient(Config.builder().projectId("__ProjectID__").build());require 'descope'
@project_id = ENV['__ProjectID__']
@client = Descope::Client.new({ project_id: @project_id})require 'vendor/autoload.php';
use Descope\SDK\DescopeSDK;
$descopeSDK = new DescopeSDK([
'projectId' => $_ENV['__ProjectID__'],
]);using Descope;
// Configure the Descope client
var options = new DescopeClientOptions
{
ProjectId = "__ProjectID__", // Required
ManagementKey = "DESCOPE_MANAGEMENT_KEY", // Optional, for management APIs
BaseUrl = "__BaseURL__", // Optional, auto-detected from project ID, only set to override
JwksCacheDuration = TimeSpan.FromMinutes(5) // Optional, how long public signing keys are cached (default: 5 minutes)
};
// Option 1: Dependency Injection - best for ASP.NET Core apps; registers IDescopeClient so it can be injected into your services
builder.Services.AddDescopeClient(options);
// Then inject IDescopeClient wherever you need it
public class MyService
{
private readonly IDescopeClient descopeClient;
public MyService(IDescopeClient client)
{
descopeClient = client;
}
}
// Option 2: Factory (Create once and reuse this instance) - best for console apps, background workers, or when you need to manually control the client's lifetime
var descopeClient = DescopeManagementClientFactory.Create(options);Load All tenants
Use the code below to load all existing tenants within the project
let resp = await descopeClient.management.tenant.loadAll();
if (!resp.ok) {
console.log("Unable to load tenants.")
console.log("Status Code: " + resp.code)
console.log("Error Code: " + resp.error.errorCode)
console.log("Error Description: " + resp.error.errorDescription)
console.log("Error Message: " + resp.error.errorMessage)
}
else {
console.log("Successfully loaded tenants:")
console.log(resp.data)
}try:
resp = descope_client.mgmt.tenant.load_all()
print ("Successfully loaded tenants:")
print(json.dumps(resp, indent=2))
except AuthException as error:
print ("Unable to load tenants.")
print ("Status Code: " + str(error.status_code))
print ("Error: " + str(error.error_message))// Args:
// ctx: context.Context - Application context for the transmission of context capabilities like
// cancellation signals during the function call. In cases where context is absent, the context.Background()
// function serves as a viable alternative.
// Utilizing context within the Descope GO SDK is supported within versions 1.6.0 and higher.
ctx := context.Background()
res, err := descopeClient.Management.Tenant().LoadAll(ctx)
if (err != nil){
fmt.Println("Unable to load tenants: ", err)
} else {
fmt.Println("Successfully loaded tenants: ")
for _, t := range res {
fmt.Println(t)
}
}TenantService ts = descopeClient.getManagementServices().getTenantService();
// Load all tenants
try {
List<Tenant> tenants = ts.loadAll();
for (Tenant t : tenants) {
// Do something
}
} catch (DescopeException de) {
// Handle the error
}try
{
var response = await descopeClient.Mgmt.V1.Tenant.All.GetAsync();
foreach (var tenant in response!.Tenants!)
{
// do something
var parent = tenant.Parent; // parent tenant ID (empty if top-level)
var successors = tenant.Successors; // direct sub-tenant IDs
}
}
catch (DescopeException ex)
{
// Handle the error
}Load Tenant by ID
This function allows for you to load a specific tenant based on the tenant's ID.
// Args:
// id (String): The ID of the tenant which you want to load
const id = "xxxx"
let resp = await descopeClient.management.tenant.load(id);
if (!resp.ok) {
console.log("Failed to load tenant.")
console.log("Status Code: " + resp.code)
console.log("Error Code: " + resp.error.errorCode)
console.log("Error Description: " + resp.error.errorDescription)
console.log("Error Message: " + resp.error.errorMessage)
}
else {
console.log("Successfully loaded tenant.")
console.log(resp.data)
}# Args:
# id (String): The ID of the tenant which you want to load
id = "xxxx"
try:
resp = descope_client.mgmt.tenant.load(id=id)
print("Successfully loaded tenant")
print(json.dumps(resp, indent=4))
except AuthException as error:
print ("Failed to load tenant")
print ("Status Code: " + str(error.status_code))
print ("Error: " + str(error.error_message))// Args:
// ctx: context.Context - Application context for the transmission of context capabilities like
// cancellation signals during the function call. In cases where context is absent, the context.Background()
// function serves as a viable alternative.
// Utilizing context within the Descope GO SDK is supported within versions 1.6.0 and higher.
ctx := context.Background()
// id (String): The ID of the tenant which you want to load
id := "xxxx"
res, err := descopeClient.Management.Tenant().Load(ctx, id)
if (err != nil){
fmt.Println("Unable to load tenant: ", err)
} else {
fmt.Println("Successfully loaded tenant: ")
fmt.Println(res)
}TenantService ts = descopeClient.getManagementServices().getTenantService();
try {
ts.load("my-custom-id");
} catch (DescopeException de) {
// Handle the error
}// Args:
// tenantID (string): The ID of the tenant to load.
var tenantID = "tenant-id";
try
{
var response = await descopeClient.Mgmt.V1.Tenant.GetWithIdAsync(tenantID);
var parent = response!.Tenant!.Parent; // parent tenant ID (empty if top-level)
var successors = response.Tenant.Successors; // direct sub-tenant IDs
}
catch (DescopeException ex)
{
// Handle the error
}Search Tenants
This function allows for you to search Descope tenants by ID, name, self service provisioning domain, and custom attributes.
// Args:
// ids (String[]): Array of tenant IDs to search for.
const ids = ["TestTenant"]
// names (String[]): Array of tenant names to search for.
const names = ["TestTenant"]
// selfProvisioningDomains (String[]): Array of self service provisioning domains to search for.
const selfProvisioningDomains = ["example.com", "company.com"]
// customAttributes (String[]): Array of self service provisioning domains to search for.
const customAttributes = {"mycustomattribute": "Test"}
// When searching based on one of these items or a few of these items, leave the applicable items you are not searching for to null.
let resp = await descopeClient.management.tenant.searchAll(ids, names, selfProvisioningDomains, customAttributes);
if (!resp.ok) {
console.log("Failed to search tenants.")
console.log("Status Code: " + resp.code)
console.log("Error Code: " + resp.error.errorCode)
console.log("Error Description: " + resp.error.errorDescription)
console.log("Error Message: " + resp.error.errorMessage)
}
else {
console.log("Successfully searched tenants.")
resp.data.forEach((tenant) => {
console.log(tenant)
});
}# Args:
# ids (String[]): Array of tenant IDs to search for.
ids = ["TestTenant"]
# names (String[]): Array of tenant names to search for.
names = ["TestTenant"]
# selfProvisioningDomains (String[]): Array of self service provisioning domains to search for.
self_provisioning_domains = ["example.com", "company.com"]
# customAttributes (String[]): Array of self service provisioning domains to search for.
custom_attributes = {"mycustomattribute": "Test"}
# When searching based on one of these items or a few of these items, leave the applicable items you are not searching for to null.
try:
resp = descope_client.mgmt.tenant.search_all(ids=ids, names=names, self_provisioning_domains=self_provisioning_domains, custom_attributes=custom_attributes)
print("Successfully searched tenants")
print(json.dumps(resp, indent=4))
except AuthException as error:
print ("Failed to search tenants")
print ("Status Code: " + str(error.status_code))
print ("Error: " + str(error.error_message))// Args:
// ctx: context.Context - Application context for the transmission of context capabilities like
// cancellation signals during the function call. In cases where context is absent, the context.Background()
// function serves as a viable alternative.
// Utilizing context within the Descope GO SDK is supported within versions 1.6.0 and higher.
ctx := context.Background()
// searchOptions (&descope.TenantSearchOptions{}): Search options for your tenant search
searchOptions := &descope.TenantSearchOptions{}
searchOptions.IDs = []string{"TestTenant"}
searchOptions.Names = []string{"TestTenant"}
searchOptions.SelfProvisioningDomains = []string{"example.com", "company.com"}
searchOptions.CustomAttributes = map[string]any{"mycustomattribute": "Test"}
res, err := descopeClient.Management.Tenant().SearchAll(ctx, searchOptions)
if (err != nil){
fmt.Println("Unable to search tenants: ", err)
} else {
fmt.Println("Successfully searched tenants: ")
for _, t := range res {
fmt.Println(t)
}
}TenantService ts = descopeClient.getManagementServices().getTenantService();
try {
List<Tenant> tenants = ts.searchAll(TenantSearchRequest.builder()
.ids(Arrays.asList("TestTenant"))
.names(Arrays.asList("TestTenant"))
.customAttributes(Map.of("mycustomattribute", "Test"))
.selfProvisioningDomains(Arrays.asList("example.com", "company.com")));
for (Tenant t : tenants) {
// Do something
}
} catch (DescopeException de) {
// Handle the error
}// Args:
// searchRequest (SearchTenantsRequest): Fine-tune filters.
var searchRequest = new SearchTenantsRequest
{
TenantIds = new List<string> { "my-custom-id" },
TenantNames = new List<string> { "My Tenant" },
TenantSelfProvisioningDomains = new List<string> { "domain.com", "company.com" },
CustomAttributes = new SearchTenantsRequest_customAttributes
{
AdditionalData = new Dictionary<string, object> { { "mycustomattribute", "Test" } }
},
};
try
{
var response = await descopeClient.Mgmt.V1.Tenant.Search.PostAsync(searchRequest);
foreach (var tenant in response!.Tenants!)
{
// do something
}
}
catch (DescopeException ex)
{
// Handle the error
}Create Tenant
At the time of creation, the tenant must be given a name and a tenant-id. If you don't provide a tenant-id, a tenant-id is automatically generated. The tenant-id is used for sign-up/sign-in and other management operations later. In addition, you can also set domains for the tenant. The domain is used to automatically assign the end-user to a tenant at the time of sign-up and sign-in. The tenant name must be unique per project. The tenant ID is generated automatically for the tenant when not provided.
// There are two ways to create a tenant via SDK. createWithId (which will assign the given id) and create (which will automatically generate the id). Examples below:
// createWithId: Create a new tenant with a given name and tenant id.
// ==================================================================
// Args:
// name (str): The tenant's name
var name = "TestTenantCreateWithId"
// id (str): The tenant's id.
var id = "TestConfiguredId"
// selfProvisioningDomains (List[str]): An optional list of domains that are associated with this tenant. Users authenticating from these domains will be associated with this tenant.
var selfProvisioningDomains = ["TestDomain1.com", "TestDomain2.com"]
// customAttributes (dict): Optional, set the different custom attributes values of the keys that were previously configured in Descope console app
const customAttributes = {"attribute1": "Value 1", "attribute2": "Value 2"}
let resp = await descopeClient.management.tenant.createWithId(id, name, selfProvisioningDomains, customAttributes)
if (!resp.ok) {
console.log(resp)
console.log("Unable to create tenant.")
console.log("Status Code: " + resp.code)
console.log("Error Code: " + resp.error.errorCode)
console.log("Error Description: " + resp.error.errorDescription)
console.log("Error Message: " + resp.error.errorMessage)
}
else {
console.log("Successfully created tenant.")
console.log(resp.data)
}
// Create: Create a new tenant with the given name. The id will be automatically generated and returned.
// ==================================================================
// Args:
// name (str): The tenant's name
name = "TestTenantCreateGeneratedId"
// selfProvisioningDomains (List[str]): An optional list of domains that are associated with this tenant. Users authenticating from these domains will be associated with this tenant.
selfProvisioningDomains = ["TestDomain3.com", "TestDomain4.com"]
// customAttributes (dict): Optional, set the different custom attributes values of the keys that were previously configured in Descope console app
const customAttributes = {"attribute1": "Value 1", "attribute2": "Value 2"}
resp = await descopeClient.management.tenant.create(name, selfProvisioningDomains, customAttributes)
if (!resp.ok) {
console.log("Unable to create tenant.")
console.log("Status Code: " + resp.code)
console.log("Error Code: " + resp.error.errorCode)
console.log("Error Description: " + resp.error.errorDescription)
console.log("Error Message: " + resp.error.errorMessage)
}
else {
console.log("Successfully created tenant.")
console.log(resp.data)
}# Create a new tenant with the given name. Tenant IDs are provisioned automatically, but can be provided explicitly if needed. Both the name and ID must be unique per project.
# Args:
# name (str): The tenant's name
name = "TestTenantCreateWithId"
# id (str): Optional tenant ID. If not provided, it will be auto assigned.
id = "TestTenantCreateWithId"
# self_provisioning_domains (List[str]): An optional list of domains that are associated with this tenant. Users authenticating from these domains will be associated with this tenant.
self_provisioning_domains = ["TestDomain1.com", "TestDomain2.com"]
# custom_attributes (dict): Optional, set the different custom attributes values of the keys that were previously configured in Descope console app
custom_attributes = {"attribute1": "Value 1", "attribute2": "Value 2"}
try:
resp = descope_client.mgmt.tenant.create(name=name, id=id, self_provisioning_domains=self_provisioning_domains, custom_attributes=custom_attributes)
print ("Successfully created tenant.")
print(json.dumps(resp, indent=2))
except AuthException as error:
print ("Unable to create tenant.")
print ("Status Code: " + str(error.status_code))
print ("Error: " + str(error.error_message))// There are two ways to create a tenant via SDK. CreateWithID (which will assign the given id) and Create (which will automatically generate the id). Examples below:
// CreateWithID: Create a new tenant with a given name and tenant id.
// ==================================================================
// Args:
// ctx: context.Context - Application context for the transmission of context capabilities like
// cancellation signals during the function call. In cases where context is absent, the context.Background()
// function serves as a viable alternative.
// Utilizing context within the Descope GO SDK is supported within versions 1.6.0 and higher.
ctx := context.Background()
// tenantRequest (&descope.TenantRequest{}): Tenant options for creation
tenantRequest := &descope.TenantRequest{}
tenantRequest.Name = []string{"TestTenant"}
tenantRequest.SelfProvisioningDomains = []string{"example.com", "company.com"}
tenantRequest.CustomAttributes = map[string]any{"mycustomattribute": "Test"}
// id (str): The tenant's id.
id := "TestConfiguredId"
err := descopeClient.Management.Tenant().CreateWithID(ctx, id, tenantRequest)
if (err != nil){
fmt.Println("Unable to create tenant with specified ID: ", err)
} else {
fmt.Println("Successfully created tenant with specified ID")
}
// Create: Create a new tenant with the given name. The id will be automatically generated and returned.
// ==================================================================
// Args:
// ctx: context.Context - Application context for the transmission of context capabilities like
// cancellation signals during the function call. In cases where context is absent, the context.Background()
// function serves as a viable alternative.
// Utilizing context within the Descope GO SDK is supported within versions 1.6.0 and higher.
ctx := context.Background()
// tenantRequest (&descope.TenantRequest{}): Tenant options for creation
tenantRequest := &descope.TenantRequest{}
tenantRequest.Name = []string{"TestTenant"}
tenantRequest.SelfProvisioningDomains = []string{"example.com", "company.com"}
tenantRequest.CustomAttributes = map[string]any{"mycustomattribute": "Test"}
tenantID, err := descopeClient.Management.Tenant().Create(ctx, tenantRequest)
if (err != nil){
fmt.Println("Unable to create tenant: ", err)
} else {
fmt.Println("Successfully created tenant. The automatically generated ID is: ", tenantID)
}TenantService ts = descopeClient.getManagementServices().getTenantService();
// The self provisioning domains or optional. If given they'll be used to associate
// Users logging in to this tenant
try {
ts.create("My Tenant", Arrays.asList("domain.com"), new HashMap<String, Object>() {{
put("custom-attribute-1", "custom-value1");
put("custom-attribute-2", "custom-value2");
}});
} catch (DescopeException de) {
// Handle the error
}
// You can optionally set your own ID when creating a tenant
try {
ts.createWithId("my-custom-id", "My Tenant", Arrays.asList("domain.com"), new HashMap<String, Object>() {{
put("custom-attribute-1", "custom-value1");
put("custom-attribute-2", "custom-value2");
}});
} catch (DescopeException de) {
// Handle the error
}// Args:
// createRequest (CreateTenantRequest): Configuration for the new tenant (name required).
var createRequest = new CreateTenantRequest
{
Name = "name",
Id = "my-tenant-id", // optional — omit to auto-generate
SelfProvisioningDomains = new List<string> { "domain" },
CustomAttributes = new CreateTenantRequest_customAttributes
{
AdditionalData = new Dictionary<string, object> { { "mycustomattribute", "test" } }
},
};
try
{
var createResponse = await descopeClient.Mgmt.V1.Tenant.Create.PostAsync(createRequest);
var newTenantId = createResponse!.Id;
}
catch (DescopeException ex)
{
// Handle the error
}Update Tenant
Use the code below to update an existing tenant with the given name and domains. All parameters are used as overrides to the existing tenant. Empty fields will override populated fields.
// Args:
// id (str): The tenant's id.
var id = "xxxxxx"
// name (str): The tenant's name
var name = "Test Updated Name"
// selfProvisioningDomains (List[str]): An optional list of domains that are associated with this tenant. Users authenticating from these domains will be associated with this tenant. If changed, it will be the new list of self provisioned domains.
var selfProvisioningDomains = ["TestUpdatedDomain1.com", "TestUpdatedDomain2.com"]
// customAttributes (dict): Optional, set the different custom attributes values of the keys that were previously configured in Descope console app
const customAttributes = {"attribute1": "Value 1", "attribute2": "Value 2"}
const resp = await descopeClient.management.tenant.update(id, name, selfProvisioningDomains, customAttributes);
if (!resp.ok) {
console.log(resp)
console.log("Failed to update tenant.")
console.log("Status Code: " + resp.code)
console.log("Error Code: " + resp.error.errorCode)
console.log("Error Description: " + resp.error.errorDescription)
console.log("Error Message: " + resp.error.errorMessage)
}
else {
console.log("Successfully update tenant.")
console.log(resp.data)
}# Args:
# id (str): The ID of the tenant to update.
id = "xxxxxx"
# name (str): The tenant's name, if changed, it will be the new name.
name = "Test Updated Name"
# self_provisioning_domains (List[str]): An optional list of domains that are associated with this tenant. Users authenticating from these domains will be associated with this tenant. If changed, it will be the new list of self provisioned domains.
self_provisioning_domains = ["TestUpdatedDomain1.com", "TestUpdatedDomain2.com"]
# custom_attributes (dict): Optional, set the different custom attributes values of the keys that were previously configured in Descope console app
custom_attributes = {"attribute1": "Value 1", "attribute2": "Value 2"}
try:
resp = descope_client.mgmt.tenant.update(id=id, name=name, self_provisioning_domains=self_provisioning_domains, custom_attributes=custom_attributes)
print ("Successfully updated tenant.")
except AuthException as error:
print ("Unable to update tenant.")
print ("Status Code: " + str(error.status_code))
print ("Error: " + str(error.error_message))// Args:
// ctx: context.Context - Application context for the transmission of context capabilities like
// cancellation signals during the function call. In cases where context is absent, the context.Background()
// function serves as a viable alternative.
// Utilizing context within the Descope GO SDK is supported within versions 1.6.0 and higher.
ctx := context.Background()
// id (str): The id of the tenant you want to update.
id := "xxxxxx"
// tenantRequest (&descope.TenantRequest{}): Tenant options for update
tenantRequest := &descope.TenantRequest{}
tenantRequest.Name = []string{"TestTenant"}
tenantRequest.SelfProvisioningDomains = []string{"example.com", "company.com"}
tenantRequest.CustomAttributes = map[string]any{"mycustomattribute": "Test"}
err := descopeClient.Management.Tenant().Update(ctx, id, tenantRequest)
if (err != nil){
fmt.Println("Unable to update tenant: ", err)
} else {
fmt.Println("Successfully updated tenant")
}TenantService ts = descopeClient.getManagementServices().getTenantService();
// Update will override all fields as is. Use carefully.
try {
ts.update("my-custom-id", "My Tenant", Arrays.asList("domain.com", "another-domain.com"), new HashMap<String, Object>() {{
put("custom-attribute-1", "custom-value1");
put("custom-attribute-2", "custom-value2");
}});
} catch (DescopeException de) {
// Handle the error
}// Args:
// tenantID (string): The ID of the tenant to update.
var tenantID = "tenant-id";
// updateRequest (UpdateTenantRequest): New details to set (all fields override existing).
var updateRequest = new UpdateTenantRequest
{
Id = tenantID,
Name = "Updated Name",
SelfProvisioningDomains = new List<string> { "domain" },
CustomAttributes = new UpdateTenantRequest_customAttributes
{
AdditionalData = new Dictionary<string, object> { { "mycustomattribute", "test" } }
},
};
try
{
await descopeClient.Mgmt.V1.Tenant.Update.PostAsync(updateRequest);
}
catch (DescopeException ex)
{
// Handle the error
}Delete Tenant
Use the code below to delete an existing tenant. Please note that this action is irreversible.
// Args:
// id (str): The tenant's id.
var id = "xxxxxx"
// cascade (boolean): Pass true to cascade value, in case you want to delete all users/keys associated only with this tenant
var cascade = false
let resp = await descopeClient.management.tenant.delete(id, cascade);
if (!resp.ok) {
console.log(resp)
console.log("Unable to delete tenant.")
console.log("Status Code: " + resp.code)
console.log("Error Code: " + resp.error.errorCode)
console.log("Error Description: " + resp.error.errorDescription)
console.log("Error Message: " + resp.error.errorMessage)
}
else {
console.log("Successfully deleted tenant.")
console.log(resp.data)
}# Args:
# id (str): The id of the tenant to be deleted.
id = "xxxxxx"
# cascade (boolean): Pass true to cascade value, in case you want to delete all users/keys associated only with this tenant
cascade = False
try:
resp = descope_client.mgmt.tenant.delete(id=id, cascade=cascade)
print("Successfully deleted tenant.")
except AuthException as error:
print ("Unable to delete tenant.")
print ("Status Code: " + str(error.status_code))
print ("Error: " + str(error.error_message))
// Args:
// ctx: context.Context - Application context for the transmission of context capabilities like
// cancellation signals during the function call. In cases where context is absent, the context.Background()
// function serves as a viable alternative.
// Utilizing context within the Descope GO SDK is supported within versions 1.6.0 and higher.
ctx := context.Background()
// id (str): The id of the tenant you want to delete.
id := "xxxxxx"
// cascade (boolean): Pass true to cascade value, in case you want to delete all users/keys associated only with this tenant
cascade := false
err := descopeClient.Management.Tenant().Delete(ctx, id, cascade)
if (err != nil){
fmt.Println("Unable to delete tenant: ", err)
} else {
fmt.Println("Successfully deleted tenant")
}TenantService ts = descopeClient.getManagementServices().getTenantService();
// Tenant deletion cannot be undone. Use carefully.
try {
ts.delete("my-custom-id");
} catch (DescopeException de) {
// Handle the error
}// Args:
// tenantID (string): The ID of the tenant to delete (irreversible).
var tenantID = "tenant-id";
// cascade (bool): Pass true to delete users/keys associated only with this tenant.
var cascade = false;
try
{
await descopeClient.Mgmt.V1.Tenant.DeletePath.PostAsync(new DeleteTenantRequest
{
Id = tenantID,
Cascade = cascade,
});
}
catch (DescopeException ex)
{
// Handle the error
}Update Tenant Password Policy
Use the code below to update password policy for your tenant.
// Args:
//tenantId (str): The tenant Id whose password policy has to be updated.
//enabled (boolean): To enable
//minLength (int) : minimum passwords length
//lowercase (boolean): Requires atleast one lowercase letter
//uppercase (boolean): Requires atleast one uppercase letter
//number (boolean): Requires atleast one number
//nonAlphaNumeric (boolean) : Requies at least one non-alphanumeric character
//expiration (boolean): Enable password expiration
//expirationWeeks (int): Password expiration period in weeks
//reuse (boolean): Enable/Disable prevent password reuse
//reuseAmount (int): Number of passwords to remember
//lock (boolean) : Enable/Disable account locking
//lockAttempts (int) : Lock account after this number of attempts
const tenantId = "xxxx"
const policysetting = {
enabled: true,
minLength: 8,
expiration: true,
expirationWeeks: 4,
lock: true,
lockAttempts: 5,
reuse: true,
reuseAmount: 6,
lowercase: true,
uppercase: false,
number: true,
nonAlphaNumeric: false,
}
const resp = await descopeClient.management.password.configureSettings(tenantId, policysetting);
if (!resp.ok) {
console.log("Failed to update access key.")
console.log("Status Code: " + resp.code)
console.log("Error Code: " + resp.error.errorCode)
console.log("Error Description: " + resp.error.errorDescription)
console.log("Error Message: " + resp.error.errorMessage)
}
else {
console.log("Successfully updated password policy.")
console.log(resp.data)
}// Args:
// ctx: context.Context - Application context for the transmission of context capabilities like
// cancellation signals during the function call. In cases where context is absent, the context.Background()
// function serves as a viable alternative.
// Utilizing context within the Descope GO SDK is supported within versions 1.6.0 and higher.
ctx := context.Background()
tenantId = "xxxx"
// policy (descope.PasswordSettings): Policy object to update password policy.
policy := &descope.PasswordSettings{
Enabled: true,
MinLength: 8,
Lowercase: true,
Uppercase: true,
Number: true,
NonAlphanumeric: true,
Expiration: true,
ExpirationWeeks: 3,
Reuse: true,
ReuseAmount: 3,
Lock: true,
LockAttempts: 4,
}
resp, err := descopeClient.Management.Password().ConfigureSettings(ctx, tenantId, policy)
if (err != nil){
fmt.Println("Failed to update password policy: ", err)
} else {
fmt.Println("Successfully updated password policy", resp)
}# settings is a hash storing key value pair for password policy settings for the required tenant ID
settings = {"minLength" => 10}
descope_client.update_password_settings(settings)// Args:
// tenantID (string?): Optional tenant ID. Omit/null uses project‑level settings.
string? tenantID = "tenant-id";
try
{
var currSettings = tenantID != null
? await descopeClient.Mgmt.V1.Password.Settings.GetWithTenantIdAsync(tenantID)
: await descopeClient.Mgmt.V1.Password.Settings.GetForProjectAsync();
currSettings!.Enabled = true;
currSettings.MinLength = 8;
currSettings.Lowercase = true;
currSettings.Uppercase = true;
currSettings.Number = true;
currSettings.NonAlphanumeric = true;
currSettings.Expiration = true;
currSettings.ExpirationWeeks = 3;
currSettings.Reuse = true;
currSettings.ReuseAmount = 3;
currSettings.Lock = true;
currSettings.LockAttempts = 5;
await descopeClient.Mgmt.V1.Password.Settings.PostWithSettingsResponseAsync(currSettings);
}
catch (DescopeException ex)
{
// Handle the error
}Get and Update Tenant Settings
Use the getSettings and configureSettings functions as shown below to access and update settings for your tenant, based on the tenant ID.
You can also configure the tenant's SSO Setup Suite through ssoSetupSuiteSettings.
You can find the full set of configurable disabledFeatures keys like saml, oidc, scim, ssoDomains and others here.
// Args:
// id (String): The ID of the tenant for which you want to access and update settings
const id = "xxxx"
// Load tenant settings by id
const tenantSettings = await descopeClient.management.tenant.getSettings(id);
// Update will override all fields as is. Use carefully.
await descopeClient.management.tenant.configureSettings(id, {
domains: ['domain1.com'],
selfProvisioningDomains: ['domain1.com'],
enabled: true,
refreshTokenExpiration: 12,
refreshTokenExpirationUnit: 'days', // 'minutes' | 'hours' | 'days' | 'weeks'
sessionTokenExpiration: 10,
sessionTokenExpirationUnit: 'minutes', // 'minutes' | 'hours' | 'days' | 'weeks'
enableInactivity: true,
JITDisabled: false,
InactivityTime: 10,
InactivityTimeUnit: 'minutes', // 'minutes' | 'hours' | 'days' | 'weeks'
// Configure the tenant's SSO Setup Suite (requires @descope/node-sdk v2.5.0+)
ssoSetupSuiteSettings: {
enabled: true,
styleId: 'my-style-id',
disabledFeatures: {
scim: true, // hide the SCIM tab in the Setup Suite
groupMapping: false, // legacy combined toggle — disabling this hides BOTH Role Mapping and FGA Mapping
},
},
});from descope.management.common import SSOSetupSuiteSettings, SSOSetupSuiteSettingsDisabledFeatures
# Args:
# id (str): The ID of the tenant for which you want to access and update settings
id = "xxxx"
# Load tenant settings by id
try:
tenant_settings = descope_client.mgmt.tenant.load_settings(id=id)
print("Successfully loaded tenant settings:")
print(json.dumps(tenant_settings, indent=2))
except AuthException as error:
print("Failed to load tenant settings")
print("Status Code: " + str(error.status_code))
print("Error: " + str(error.error_message))
# Update will override all fields as is. Use carefully.
# self_provisioning_domains is required; every other field is optional.
try:
descope_client.mgmt.tenant.update_settings(
id=id,
self_provisioning_domains=["domain1.com"],
session_settings_enabled=True,
refresh_token_expiration=12,
refresh_token_expiration_unit="days", # "minutes" | "hours" | "days" | "weeks"
session_token_expiration=10,
session_token_expiration_unit="minutes", # "minutes" | "hours" | "days" | "weeks"
enable_inactivity=True,
inactivity_time=10,
inactivity_time_unit="minutes", # "minutes" | "hours" | "days" | "weeks"
JITDisabled=False,
# Configure the tenant's SSO Setup Suite
sso_setup_suite_settings=SSOSetupSuiteSettings(
enabled=True,
style_id="my-style-id",
disabled_features=SSOSetupSuiteSettingsDisabledFeatures(
scim=True, # hide the SCIM tab in the Setup Suite
group_mapping=False, # legacy combined toggle — disabling this hides BOTH Role Mapping and FGA Mapping
),
),
)
print("Successfully updated tenant settings.")
except AuthException as error:
print("Failed to update tenant settings")
print("Status Code: " + str(error.status_code))
print("Error: " + str(error.error_message))// Args:
// ctx: context.Context - Application context for the transmission of context capabilities like
// cancellation signals during the function call. In cases where context is absent, the context.Background()
// function serves as a viable alternative.
// Utilizing context within the Descope GO SDK is supported within versions 1.6.0 and higher.
ctx := context.Background()
// id (String): The ID of the tenant for which you want to access and update settings
id := "xxxx"
// Load tenant settings by a tenant id
settings, err := descopeClient.Management.Tenant().GetSettings(ctx)
// Configure desired settings
settingsRequest := &descope.TenantSettings{}
settingsRequest.SelfProvisioningDomains = []string{"domain.com", "company.com"}
settingsRequest.RefreshTokenExpiration = 30
settingsRequest.RefreshTokenExpirationUnit = "days"
settingsRequest.SessionTokenExpiration = 30
settingsRequest.SessionTokenExpirationUnit = "minutes"
settingsRequest.EnableInactivity = true
settingsRequest.InactivityTime = 2
settingsRequest.InactivityTimeUnit = "days"
// Update the tenant settings
err := descopeClient.Management.Tenant().ConfigureSettings(ctx, id, settingsRequest)