Descope Flows with SDKs
You can use the Descope management SDKs for common flow management operations like list/search, delete, import, and export. The management SDK requires a management key, which can be generated here.
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);List Flows
Note
You can also use our List/Search Flows API to list or search Flows in your project.
This operation lists flows in the project. Optionally filter by flow IDs, or send an empty request body to list all flows.
// Args:
// None
const resp = await descopeClient.management.flow.list()
if (!resp.ok) {
console.log("Failed to list 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 listed flows.")
console.log(resp.data)
}# Args:
# None
try:
resp = descope_client.mgmt.flow.list_flows()
print("Successfully listed flows.")
print(resp)
except AuthException as error:
print("Failed to list flows.")
print("Status Code: " + str(error.status_code))
print("Error: " + str(error.error_message))// Args:
// ctx: context.Context - Application context for cancellation and deadlines.
ctx := context.Background()
res, err := descopeClient.Management.Flow().ListFlows(ctx)
if err != nil {
fmt.Println("Failed to list flows: ", err)
} else {
fmt.Println("Successfully listed flows.")
fmt.Println(res.Total)
for _, f := range res.Flows {
fmt.Printf("ID: %s, Name: %s\n", f.ID, f.Name)
}
}// Args:
// None
FlowService fs = descopeClient.getManagementServices().getFlowService();
try {
FlowsResponse resp = fs.listFlows();
for (FlowMetadata f : resp.getFlows()) {
// Do something
}
} catch (DescopeException de) {
// Handle the error
}# Args:
# ids (Array<String>): Optional list of flow IDs to filter by. Omit or pass [] to list all flows.
ids = []
# To filter by IDs:
# ids = %w[flow-1 flow-2]
begin
resp = descope_client.list_or_search_flows(ids)
puts 'Successfully listed flows.'
puts resp
rescue Descope::AuthException => e
puts "Failed to list flows. Error: #{e.message}"
end// Args:
// request (SearchFlowsRequest): Optional filter.
// Ids (List<string>?): Optional list of flow IDs to filter by. Omit or leave empty to list all flows.
var request = new SearchFlowsRequest();
// To filter by IDs:
// var request = new SearchFlowsRequest { Ids = new List<string> { "flow-1", "flow-2" } };
try
{
var response = await descopeClient.Mgmt.V1.Flow.List.PostAsync(request);
foreach (var flow in response!.Flows!)
{
// Do something
}
}
catch (DescopeException ex)
{
// Handle the error
}Delete Flows
This operation deletes one or more flows by ID. This action is irreversible.
// Args:
// flowIds (List[str]): The flow IDs to delete.
const flowIds = ["flow-1", "flow-2"];
const resp = await descopeClient.management.flow.delete(flowIds)
if (!resp.ok) {
console.log("Failed to delete 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 deleted flows.")
}# Args:
# flow_ids (List[str]): The flow IDs to delete.
flow_ids = ["flow-1", "flow-2"]
try:
descope_client.mgmt.flow.delete_flows(flow_ids=flow_ids)
print("Successfully deleted flows.")
except AuthException as error:
print("Failed to delete flows.")
print("Status Code: " + str(error.status_code))
print("Error: " + str(error.error_message))// Args:
// ctx: context.Context - Application context for cancellation and deadlines.
ctx := context.Background()
// flowIDs ([]string): The flow IDs to delete.
flowIDs := []string{"flow-1", "flow-2"}
err := descopeClient.Management.Flow().DeleteFlows(ctx, flowIDs)
if err != nil {
fmt.Println("Failed to delete flows: ", err)
} else {
fmt.Println("Successfully deleted flows.")
}// Args:
// flowIds (List<String>): The flow IDs to delete.
List<String> flowIds = Arrays.asList("flow-1", "flow-2");
FlowService fs = descopeClient.getManagementServices().getFlowService();
try {
fs.deleteFlows(flowIds);
} catch (DescopeException de) {
// Handle the error
}// Args:
// request (DeleteFlowsRequest): Request containing the flow IDs to delete.
// Ids (List<string>): The flow IDs to delete.
var request = new DeleteFlowsRequest
{
Ids = new List<string> { "flow-1", "flow-2" }
};
try
{
await descopeClient.Mgmt.V1.Flow.DeletePath.PostAsync(request);
}
catch (DescopeException ex)
{
// Handle the error
}Export Flow
Note
You can also use our Export Flow API to export a Flow.
This operation exports a flow (and its screens) by flow ID.
// 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("Failed 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)
}# 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)
except AuthException as error:
print("Failed to export flow.")
print("Status Code: " + str(error.status_code))
print("Error: " + str(error.error_message))// Args:
// ctx: context.Context - Application context for cancellation and deadlines.
ctx := context.Background()
// flowID (str): The flow ID to export.
flowID := "sign-up-or-in"
res, err := descopeClient.Management.Flow().ExportFlow(ctx, flowID)
if err != nil {
fmt.Println("Failed to export flow: ", err)
} else {
fmt.Println("Successfully exported flow.")
fmt.Println(res)
}// Args:
// flowID (String): The flow ID to export.
String flowID = "sign-up-or-in";
FlowService fs = descopeClient.getManagementServices().getFlowService();
try {
FlowResponse resp = fs.exportFlow(flowID);
Flow flow = resp.getFlow();
List<Screen> screens = resp.getScreens();
} catch (DescopeException de) {
// Handle the error
}# Args:
# flow_id (str): The flow ID to export.
flow_id = 'sign-up-or-in'
begin
resp = descope_client.export_flow(flow_id)
puts 'Successfully exported flow.'
puts resp
rescue Descope::AuthException => e
puts "Failed to export flow. Error: #{e.message}"
end// Args:
// request (ExportFlowRequest): Request containing the flow ID to export.
// FlowId (string): The flow ID to export.
var request = new ExportFlowRequest
{
FlowId = "sign-up-or-in"
};
try
{
var response = await descopeClient.Mgmt.V2.Flow.Export.PostAsync(request);
var exportedFlow = response!.Flow;
}
catch (DescopeException ex)
{
// Handle the error
}Import Flow
Note
You can also use our Import Flow API to import a Flow.
This operation imports a flow. This overrides the existing flow for the given ID.
// Args:
// flowId (str): The flow ID to import as.
// flow (object): The flow definition to import.
// screens (list): Optional screens to import with the flow.
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("Failed 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 as.
# flow (dict): The flow definition to import.
# screens (list): Optional screens to import with the flow.
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:
// ctx: context.Context - Application context for cancellation and deadlines.
ctx := context.Background()
// flowID (str): The flow ID to import as. Overrides whatever is set in the flow data.
flowID := "sign-up-or-in"
// flow (map[string]any): The flow definition to import.
flow := map[string]any{
"name": "Sign Up or In",
"description": "Sign up or in flow",
"disabled": false,
}
err := descopeClient.Management.Flow().ImportFlow(ctx, flowID, flow)
if err != nil {
fmt.Println("Failed to import flow: ", err)
} else {
fmt.Println("Successfully imported flow.")
}// Args:
// flowID (String): The flow ID to import as.
// flow (Flow): The flow definition to import.
// screens (List<Screen>): Optional screens to import with the flow.
String flowID = "sign-up-or-in";
Flow flow = Flow.builder()
.name("Sign Up or In")
.description("Sign up or in flow")
.disabled(false)
.build();
List<Screen> screens = Arrays.asList();
FlowService fs = descopeClient.getManagementServices().getFlowService();
try {
FlowResponse resp = fs.importFlow(flowID, flow, screens);
} catch (DescopeException de) {
// Handle the error
}# Args:
# flow_id (str): The flow ID to import as.
# flow (Hash): The flow definition to import.
# screens (Array): Optional screens to import with the flow.
flow_id = 'sign-up-or-in'
flow = {
'name' => 'Sign Up or In',
'description' => 'Sign up or in flow',
'disabled' => false,
}
screens = []
begin
resp = descope_client.import_flow(
flow_id: flow_id,
flow: flow,
screens: screens,
)
puts 'Successfully imported flow.'
puts resp
rescue Descope::AuthException => e
puts "Failed to import flow. Error: #{e.message}"
end// Args:
// request (ImportFlowRequest): Request containing the exported flow to import.
// Flow (ExportedFlow): Typically the Flow object returned from V2 export.
// Prefer exporting first, then importing the returned ExportedFlow:
var exportRequest = new ExportFlowRequest
{
FlowId = "sign-up-or-in"
};
try
{
var exported = await descopeClient.Mgmt.V2.Flow.Export.PostAsync(exportRequest);
var importRequest = new ImportFlowRequest
{
Flow = exported!.Flow
};
await descopeClient.Mgmt.V2.Flow.Import.PostAsync(importRequest);
}
catch (DescopeException ex)
{
// Handle the error
} Was this helpful?