Managing Descope Flows
This page is an overview of the helpful items that you may need when working with Descope flows. Details about keyboard shortcuts, importing and exporting flows, creating custom flows, and deleting flows will be covered here.
Flow Shortcuts
The details of available keyboard shortcuts within the flow editor are covered here.
Group Select
To group select items within the flow editor, hold shift and drag your cursor to capture the items you'd like. You can then move the flow items, or delete them by pressing the delete button.
Undo Action
To undo an action within the flow editor, press ctrl/cmd + z.
Redo Action
To redo an action within the flow editor, press ctrl/cmd + shift + z.
Reset Changes
To revert all changes within the flow editor, press ctrl/cmd + shift + l.
Delete Action
To delete a node within the descope flow, click on it, then press the delete key.
Save Changes
To save changes to a flow, press ctrl/cmd + s.
Copy Flow Screens and Actions Between Flows
Descope allows you to copy and paste actions, screens, etc between flows. You can select an item or group select multiple items via ctrl/cmd + c within one flow and then ctrl/cmd + v within another flow on another tab or window.
It is also possible to copy and paste components within your screens by selecting an item and using ctrl/cmd + c within one screen and ctrl/cmd + v within another screen in the same or another tab.
Creating Custom Flows
Descope allows you to create custom flows to meet your needs. You can create flows within the Descope console by clicking the + Flow button at the top right. You will then give the flow a name, and an ID. The ID will be used when referencing the flow from your frontend code.
Duplicating Flows
You can duplicate existing flows within the Descope console by clicking the three dots on the right side of a flow, then selecting Duplicate. This creates a copy of the flow with identical screens, actions, and configurations.
When you duplicate a flow, event triggers are automatically disabled in the new flow. This is a safety measure to prevent unintended automatic executions of the new flow. If your flow uses event triggers (such as ones in Management Flows that are triggered by system events), you will need to manually re-enable them after duplication.
Flow Deletion
Descope allows you to delete flows from your project. This can be done by selecting the flow(s) within the Descope console by the checkboxes on the left then the delete button at the top of the table, or by clicking the three dots on the right then selecting delete.
Disabling and Activating Flows
When you are not actively using a Flow, you can disable it from the Console. This can be done by selecting the flow(s) within the Descope console by the checkboxes on the left, then the Disable button at the top of the table, or by clicking the three dots on the right selecting Disable. The same process applies when you want to re-enable the flows, but select Activate.
Showing Flow Code
Within the Flows page of the Descope Console, you can generate backend and frontend code snippets by clicking the three dots at the right of the flow then selecting Show Code.
You can select between various frontend frameworks and backend SDKs to integrate the selected flow into your app.

Exporting and Importing Flows
Descope allows you to export and import flows between projects. This feature allows you to backup your current flows, or migrate them between your projects.
Export Flow(s) from the Console
Within the Descope console you can export a single flow by selecting the checkboxes on the left then selecting export at the top right of the table, or by clicking the three dots on the right selecting export. The same can also be done for multiple flows when you select multiple checkboxes before clicking export. This will export the flows within a zip file. You can also export a flow when you are in the flow editor by clicking the down arrow on the top right.
Import Flow(s) from the Console
Within the Descope console you can export a single flow by selecting the import button at the top left and selecting the flow's json file to import. You can also import multiple flows by using a zip file containing the flows you would like to upload. Do note that if the IDs are the same as the flows currently in the system, the existing flows will be overridden. You can also import a flow when you are in the flow editor by clicking the up arrow on the top right.
Exporting and Importing Flows from the Management SDK
The Descope SDK allows you to import and export flows individually.
Install SDK
npm i --save @descope/node-sdkpip3 install descopego get github.com/descope/go-sdk// Include the following in your `pom.xml` (for 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 descopeImport and initialize Management SDK
import DescopeClient from '@descope/node-sdk';
const managementKey = "xxxx"
try{
// baseUrl="<URL>" // When initializing the Descope clientyou 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__', managementKey: managementKey });
} 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
)
management_key = "xxxx"
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 a custom domain within your Descope project."
descope_client = DescopeClient(project_id='__ProjectID__', management_key=management_key)
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"
import "fmt"
// 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"
)
managementKey = "xxxx"
// 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__", managementKey:managementKey})
if err != nil {
// handle the error
log.Println("failed to initialize: " + err.Error())
}import com.descope.client;
// Initialized after setting the DESCOPE_PROJECT_ID env var (and optionally DESCOPE_MANAGEMENT_KEY)
var descopeClient = new DescopeClient();
// ** Or directly **
var descopeClient = new DescopeClient(Config.builder()
.projectId("__ProjectID__")
.managementKey("management-key")
.build());require 'descope'
descope_client = Descope::Client.new(
{
project_id: '__ProjectID__',
management_key: 'management_key'
}
)List Flows
Use the code below to load all existing flows within the project:
// Args
// None
const resp = await descopeClient.management.flow.list()
if (!resp.ok) {
console.log(resp)
console.log("Unable to load flows.")
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 flows.")
console.log(resp.data)
}# Args
# None
try:
resp = descope_client.mgmt.flow.list_flows()
print ("Successfully returned flows")
print (resp)
except AuthException as error:
print ("Failed to return flows")
print ("Status Code: " + str(error.status_code))
print ("Error: " + str(error.error_message))// Args
// None
res, err := descopeClient.Management.Flow().ListFlows()
if (err != nil){
fmt.Println("Failed to return flows", err)
} else {
fmt.Println("Successfully returned flows")
for _, f := range res.Flows {
fmt.Printf("ID: %s, Name: %s, Description: %s, Disabled: %t\n", f.ID, f.Name, f.Description, f.Disabled)
}
}Export Flow
Use the code below to export an existing flow by it's flow_id. These examples export to a file:
import * as fs from 'fs';
// Args
// flowId (str): the flow id to export.
const flowId = "sign-up-or-in"
const resp = await descopeClient.management.flow.export(flowId)
if (!resp.ok) {
console.log(resp)
console.log("Unable to export flow.")
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 exported flow.")
console.log(resp.data)
let data = JSON.stringify(resp.data, null, 2);
fs.writeFile('sign-in.json', data, (err) => {
if (err) throw err;
console.log('Flow written to file');
});
}import json
# Args
# flow_id (str): the flow id to export.
flow_id = "sign-up-or-in"
try:
resp = descope_client.mgmt.flow.export_flow(flow_id=flow_id)
print ("Successfully exported flow")
print (resp)
json_object = json.dumps(resp, indent=4)
with open(f"{flow_id}.json", "w") as outfile:
outfile.write(json_object)
except AuthException as error:
print ("Failed to export flow")
print ("Status Code: " + str(error.status_code))
print ("Error: " + str(error.error_message))import (
"encoding/json"
"errors"
"fmt"
"os"
"strings"
)
// Args
// flowID (str): the flow id to export.
flowID := "sign-up-or-in"
res, err := descopeClient.Management.Flow().ExportFlow(flowID)
if err != nil {
fmt.Print("Failed to export flow", err)
} else {
data, err :=json.Marshal(res)
if err == nil {
fileName := fmt.Sprintf("%s.json", flowID)
if err == nil {
err = os.WriteFile(fileName, data, 0644)
fmt.Println("Successfully exported flow")
}
}
}Import Flow
Use the code below to import a flow. These examples import from a file:
// Args
// flowId (str): the flow id to import.
// flow (dict): the flow to import.
// screens (list): the screens to import.
const flowId = "sign-up-or-in"
const flow = {
"name": "Sign Up or In",
"description": "Sign up or in flow",
"disabled": false
}
const screens = []
const resp = await descopeClient.management.flow.import(flowId, flow, screens)
if (!resp.ok) {
console.log(resp)
console.log("Unable to import flow.")
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 imported flow.")
console.log(resp.data)
}# Args
# flow_id (str): the flow id to import.
# flow (dict): the flow to import.
# screens (list): the screens to import.
flow_id = "sign-up-or-in"
flow = {
"name": "Sign Up or In",
"description": "Sign up or in flow",
"disabled": false
}
screens = []
try:
resp = descope_client.mgmt.flow.import_flow(flow_id=flow_id, flow=flow, screens=screens)
print ("Successfully imported flow")
print (resp)
except AuthException as error:
print ("Failed to import flow")
print ("Status Code: " + str(error.status_code))
print ("Error: " + str(error.error_message))// Args
// flow_id (str): the flow id to import.
// flow (map[string]any): the flow to import.
flowID := "sign-up-or-in"
flow := map[string]any{
"name": "Sign Up or In",
"description": "Sign up or in flow",
"disabled": false
}
res, err := descopeClient.Management.Flow().ImportFlow(flowID, flow)
if (err != nil){
fmt.Println("Failed to import flow", err)
} else {
fmt.Println("Successfully imported flow")
}