descope
The descope Command Line Interface (CLI) helps manage your Descope project by leveraging its management APIs. It enables handling tasks like creating users, managing tenants, generating access keys, and modifying project settings through the command line.
With support for exporting, validating, and importing snapshots, the CLI simplifies project configuration and transfer. Its ability to output JSON makes it ideal for automation in scripts and CI/CD workflows, saving time and reducing errors. To see more about our CI/CD check out our Github CI/CD guide and Github CI/CD Template.
Prerequisites
The repository for the descope CLI can be found here.
-
Install the CLI tool according to your device, instructions can be found in the repository.
-
You will need the Project ID for the project you want to manage, this can be found in Project Settings
-
You will also need to generate a management key within Company Settings.
To set your Project ID and Management Key for the CLI, use the commands below. If you want to update them permanently add them to your terminal profile, such as .zshrc or .bashrc.
export DESCOPE_PROJECT_ID='<Your_Project_ID>'
export DESCOPE_MANAGEMENT_KEY='<Your_Management_Key>'Note
If you need help on any command or sub-command you can put the -h flag at the end of the full command to get more information and flags.
Creating and Managing Project Entities
With the CLI you can create and manage different Descope entities.
You can create: Users, Access Keys, Tenants, and Inbound Applications.
Access-Keys
These are the available commands for creating and managing access keys:
activate Activate an access key
create Create a new access key
deactivate Deactivate an access key
delete Delete an access key
load Load details about an access key
load-all Load all access keysWhen creating an access key there are several attributes you can pass in. You can get these attributes with the -h flag:
descope access-key create -hAll the information about the command is returned:
Usage:
descope access-key create <name> [-d description] [-e time] [-t tenants] [-u userId]
Flags:
-d, --description string an optional description for the access key
-e, --expires int the access key's expiry time (unix time in seconds, default 0 to not expire)
-t, --tenants strings a comma separated list of tenant ids for the access key
-u, --userId string an optional user id to adopt authorizations from
-j, --json use JSON output formatAs an example say we wanted to create an access key that expires Nov 21, 2026 which is 1795345322 Unix Time, is associated with a tenant, and takes all the project and tenant level roles and permissions of one of our users:
descope access-key create exampleKey -e 1795345322 -u 'U2piAnrm6sV1OKyGTUejqddWVSai' -t 'acmecorp' -jThe access key is returned, it is in the cleartext field:
{
"accessKey": {
"boundUserId": "U2piAnrm6sV1OKyGTUejqddWVSai",
"cleartext": "K2pjAnGVR7ez6pVqSI9mCul88IppLc0FpV9WQVnDBwRARNr5BaU56hnN61Gvm5LoWD2YW7S",
"clientId": "UDJsTm50UzhRcDdVOTVOaXVyWUZRaEsxbkRUUjpLMnBqQW5HVlI3ZXo2cFZxU0k5bUN1bDg4SXBw",
"createdBy": "K2pB49mv9n7WCVbbcC7KKkXM5jo4",
"createdTime": 1733269275,
"expireTime": 1795345322,
"id": "K2pjAnGVR7ez6pVqSI9mCul88Ipp",
"keyTenants": [
{
"tenantId": "acmecorp",
"tenantName": "AcmeCorp"
}
],
"name": "exampleKey",
"status": "active"
},
"ok": true
}You can see your newly created access key in the Access Key tab.

To activate or deactivate an access key:
descope access-key activate <id> -j
descope access-key deactivate <id> -jTo load a specific access key:
descope access-key load <id> -jTo load all access keys:
descope access-key load-all -jTo delete an access key:
descope access-key delete <id> -jTenants
These are the available commands for creating and managing tenants:
create Create a new tenant
delete Delete a tenant
load Load details about a tenant
load-all Load all tenantsWhen creating a Tenant we can pass the following flags:
Usage:
descope tenant create <name>
Flags:
-i, --id string an optional custom id for the tenant
-d, --domains strings a comma separated list of self provisioning domains for the tenant
-j, --json use JSON output formatAs an example let's create a tenant with self provisioning domains and a custom tenant id:
descope tenant create 'TestTenant' -i 'testtenant' -d 'example.com','example.org' -jTo load the tenant we just created we can use the load command:
descope tenant load 'testtenant' -jWe can see the name, self-provisioning domains, authentication methods, and created time:
{
"ok": true,
"tenant": {
"id": "testtenant",
"name": "TestTenant",
"selfProvisioningDomains": [
"example.com",
"example.org"
],
"authType": "none",
"createdTime": 1733339035
}
}We can see our tenant and its settings in the Tenants Page.

To load all tenants:
descope tenant load-all -jTo delete a tenant:
descope tenant delete <id> -jUsers
These are the available commands for managing and creating users and test users:
activate Activate a user
create Create a new user
deactivate Deactivate a user
delete Delete a user
load Load details about a user
load-all Load all users
password Commands for managing user passwords
roles Commands for managing user roles
test Commands for creating and managing test usersThe following flags are available for user creation:
Usage:
descope user create <loginId> [-e email] [-p phone] [-n name] [-t tid,...]
Flags:
-e, --email string the user's email address
-p, --phone string the user's phone number
-n, --name string the user's display name
-t, --tenants strings a comma separated list of tenant ids for the user
-j, --json use JSON output formatAs an example let's say we wanted to create a user associated with tenants, we can do the following:
descope user create 'john@example.com' -p '+11234567890' -t 'acmecorp','testtenant' -jThey will be set as invited in the descope console:

Their status can be manually changed from Invited to Active using the activate sub-command.
descope user activate 'john@example.com' -jNow if we load the user we can see their status is set to enabled:
descope user load -l 'john@example.com' -j {
"ok": true,
"user": {
"phone": "+11234567890",
"userId": "U2poJTufi0fAPgCEySTao5qmtk6j",
"loginIds": [
"john@example.com"
],
"verifiedPhone": true,
"userTenants": [
{
"tenantId": "acmecorp",
"tenantName": "AcmeCorp"
},
{
"tenantId": "testtenant",
"tenantName": "TestTenant"
}
],
"status": "enabled",
"createdTime": 1733426505
}
}To load a user by userId instead of loginId:
descope user load -u 'U2poJTufi0fAPgCEySTao5qmtk6j' -jTo load all users with pagination:
descope user load-all -l 50 -p 0 -jFlags:
-l, --limit int the number of results for pagination (max 100)
-p, --page int the number of page for pagination (default 0)To delete a user:
descope user delete -l 'john@example.com' -j
descope user delete -u 'U2poJTufi0fAPgCEySTao5qmtk6j' -jTo deactivate a user:
descope user deactivate 'john@example.com' -jUser Roles
We can manage a user's roles through the roles sub-command. These are the available commands for roles:
add Add roles to a user
remove Remove roles from a user
set Set the roles for a userNote
Adding a role will append to current roles. Setting roles will overwrite any existing roles.
Here is an example of adding a tenant-level role to a user:
descope user roles add john@example.com -t 'acmecorp' -r 'Tenant Admin','acmeRole' -j If we wanted to add project-level roles we can run the command again with no input for tenant.
To set roles (overwrites existing roles):
descope user roles set john@example.com -r 'Admin','User' -j
descope user roles set john@example.com -t 'acmecorp' -r 'Tenant Admin' -jTo remove roles:
descope user roles remove john@example.com -r 'Admin' -j
descope user roles remove john@example.com -t 'acmecorp' -r 'Tenant Admin' -jUser Passwords
We can set active and temporary passwords for a user as well as expire their existing password using the password sub-command:
expire Expire a user's password
set-active Set an active password for a user
set-temporary Set a temporary password for a userWe can set a temporary password which will require a user to change their password on the next authentication:
descope user password set-temporary 'michael.rimboim@descope.com' 'a8 re7f9E' -jThis can be accomplished by having a replace password section of the flow like below, the user will be able to use this temporary password to create a new one:


To set an active password:
descope user password set-active 'john@example.com' 'MySecurePassword123!' -jTo expire a user's password:
descope user password expire 'john@example.com' -jTest Users
Using the CLI we can programmatically create test users and generate logins for these users with the test sub-command:
create Create a new test user
delete-all Delete all existing test users in the project
generate Commands for generating logins for test usersCreating a test user works the same as creating a regular user:
descope user test create test@descope.com -p "+19999999999" -j You can generate a test verification code for a test user. Let's create a SMS OTP we can use and reuse for this test user:
descope user test generate otp sms test@descope.comWe get back the OTP code we can use in place of a real OTP code during verification.
The generate sub-command supports the following methods:
otp Generate an OTP for a test user using email, sms, or voice
magic-link Generate a magic link for a test user using email or sms
enchanted-link Generate an enchanted link and a pendingRef which is used to poll for a valid sessionExamples:
descope user test generate otp email test@descope.com -j
descope user test generate otp sms test@descope.com -j
descope user test generate otp voice test@descope.com -jFor magic link:
descope user test generate magic-link email test@descope.com -j
descope user test generate magic-link sms test@descope.com -j
descope user test generate magic-link email test@descope.com -u 'https://example.com/callback' -jFlags:
-u, --redirect-url string override the redirect URL configured for enchanted link in the project configurationFor enchanted link:
descope user test generate enchanted-link test@descope.com -j
descope user test generate enchanted-link test@descope.com -u 'https://example.com/callback' -jTo delete all test users:
descope user test delete-all -jInbound Applications
These are the available commands for managing inbound apps:
create Create a new inbound app
update Update an existing inbound app
delete Delete an inbound app
load Load details about an inbound app
load-all Load all inbound apps
secret Commands for managing inbound app secretsWhen creating an inbound app, you must provide a flow hosting URL and at least one permission scope (you may provide more than one if needed):
Note
The following example demonstrates how to provide multiple permission scopes using the -p flag. Only one permission scope is required, but you can specify additional scopes as needed.
Usage:
descope apps inbound create <name> [-f flow-hosting-url] [-p permission-scopes]
Flags:
--description string an optional description for the inbound app
-f, --flow-hosting-url string the flow hosting URL for the inbound app
-c, --callback-url strings can be used multiple times to add approved callback URLs. For example:
-c 'https://example.com'
-p, --permission-scope strings can be used multiple times to add permission scopes, where each value
is expected to be a comma separated list with the scope name, description,
and a list of roles separated by colons. For example:
-p 'write,Allow writing files,User|Reader|Writer'
-p 'guest,Guest user with no roles,-'
-a, --attribute-scope strings can be used multiple times to add attribute scopes, where each value
is expected to be a comma separated list with the scope name, description,
and a list of user attributes separated by colons. For example:
-a 'contact,Fetch user contact details,displayName|email|phone'
-j, --json use JSON output formatExample of creating an inbound app:
descope apps inbound create 'MyApp' -f 'https://app.example.com' -p 'read,Read access,User|Reader' -p 'write,Write access,Writer|Admin' -c 'https://app.example.com/callback' -jThe inbound app will be created with the following settings:
{
"app": {
"id": "TPA36iegoe4RLOGDuazm4SPVwZCXN8",
"name": "MyApp",
"description": "",
"logo": "",
"loginPageUrl": "https://app.example.com",
"clientId": "UDM2aWUzUHBVeENrb2ZFUnVPSmhWNXkxODdNZzpUUEEzNmllZ29lNFJMT0dEdWF6bTRTUFZ3WkNYTjg=",
"approvedCallbackUrls": [
"https://app.example.com/callback"
],
"permissionsScopes": [
{
"name": "read",
"description": "Read access",
"values": []
},
{
"name": "write",
"description": "Write access",
"values": []
}
],
"attributesScopes": [],
"jwtBearerSettings": {}
},
"ok": true,
"secret": "PxpQ1gF9pKDfMuFqsVC5HyyxCpI7feWZmH9OFN6ylxn"
}
To update an inbound app:
descope apps inbound update <id> <name> [-f flow-hosting-url] [-p permission-scopes]To load an inbound app:
descope apps inbound load <id> -jTo load all inbound apps:
descope apps inbound load-all -jTo delete an inbound app:
descope apps inbound delete <id> -jInbound App Secrets
The secret sub-command allows you to manage secrets for inbound apps:
load Load the secret for an inbound app
rotate Generates a new secret for an inbound appTo load the secret for an inbound app:
descope apps inbound secret load <id> -jTo rotate the secret for an inbound app:
descope apps inbound secret rotate <id> -jManaging the Project
The descope CLI allows you to manage flows, audits, projects, and themes
Audit
You can use the audit search command to do a fuzzy search of audit logs from the past 30 days:
Here is an example of searching for all audit logs that include the word Mozilla:
descope audit search "Mozilla" -jTo store logs longer than 30 days you must stream them to your own service, see here
Flow
Using the CLI we can programmatically import and export flows:
convert Convert a flow between formats
export Export a flow to a JSON file or standard output
import Import a flow from a JSON file
list Lists all flows in a projectHere is an example of exporting a flow to a JSON file:
descope flow export "sign-up-or-in" > sign-up-or-in.jsonTo export a flow to a specific file:
descope flow export "sign-up-or-in" sign-up-or-in.jsonTo list all flows:
descope flow list -jTo import a flow from a JSON file:
descope flow import "sign-up-or-in" sign-up-or-in.jsonThe convert command allows you to convert flows between different formats:
Usage:
descope flow convert <sourcePath> [targetPath] [-s]
Flags:
-s, --skip skip unsupported file types
-j, --json use JSON output formatThe convert command supports:
- Converting from snapshot format (directory with metadata.json, contents.json, and screen files) to exported format (single JSON file)
- Converting from console format (flow and screens structure) to exported format
- Converting from exported format to snapshot format
Example:
descope flow convert flow-snapshot/ sign-up-or-in.json
descope flow convert sign-up-or-in-console.json sign-up-or-in.json
descope flow convert sign-up-or-in.json flow-snapshot/ -sProject
Using the CLI you can manage the creation of project snapshots and validation. These are the available base commands:
clone Clone an existing project along with all settings and configurations
list Lists all projects in a company
delete Delete an existing project
snapshot Commands for working with project snapshotsThe snapshot subcommand allows you to import and export projects. These commands are useful for CI/CD automation.
export Export a snapshot of all the settings and configurations of a project
import Import a snapshot into a project
validate Validate a snapshot before importing into a projectClone Project
To clone an existing project:
Usage:
descope project clone <existingProjectId> <newProjectName> [-e environment] [--tags tag,...]
Flags:
-e, --environment string an optional environment for the new project, only valid value is production
--tags strings a comma separated list of tags for the new project
-j, --json use JSON output formatExample:
descope project clone P2Z1234567890123456789012345 'My New Project' -e production --tags 'production','backend' -jList Projects
To list all projects in a company:
descope project list -jNote
This command requires a company management key.
Delete Project
To delete a project:
Usage:
descope project delete <projectId> [-f]
Flags:
-f, --force skips the prompt and deletes the project immediately
-j, --json use JSON output formatNote
The --force flag is required when using --json to delete a project.
Example:
descope project delete P2Z1234567890123456789012345 -fProject Snapshots
To export a snapshot:
Usage:
descope project snapshot export <projectId> [-p path]
Flags:
-p, --path string the path to write the snapshot into
--no-assets don't extract assets from snapshot files
-j, --json use JSON output formatIf no path is specified, the snapshot will be exported to a directory named project-<projectId>.
Example:
descope project snapshot export P2Z1234567890123456789012345 -p ./my-snapshotTo import a snapshot:
Usage:
descope project snapshot import <projectId> [-p path]
Flags:
-p, --path string the path to read the snapshot from
--secrets-input string the path to a JSON file with required secrets
-j, --json use JSON output formatIf no path is specified, the snapshot will be read from a directory named project-<projectId>.
Example:
descope project snapshot import P2Z1234567890123456789012345 -p ./my-snapshot --secrets-input secrets.jsonTo validate a snapshot:
Usage:
descope project snapshot validate <projectId> [-p path]
Flags:
-p, --path string the path to read the snapshot from
--secrets-input string the path to a JSON file with required secrets
--secrets-output string the path to a JSON file to write missing secrets in case validation fails
--failures-output string the path to write a list of failures in case validation fails
-j, --json use JSON output formatExample:
descope project snapshot validate P2Z1234567890123456789012345 -p ./my-snapshot --secrets-output missing-secrets.json --failures-output failures.txtIf validation fails, the command will exit with status code 2. The --secrets-output flag can be used to generate a template file with all missing secrets that need to be provided.
Theme
Using the CLI tool you can manage the export and import of the project theme. These are the available commands:
export Export the project theme to a JSON file or standard output
import Import the project theme from a JSON fileExporting the theme gives a JSON file with all the styles that exist in a project.
descope theme export testTheme.jsonTo export to standard output:
descope theme export -jTo import a theme:
descope theme import testTheme.json