Management Flows with SDKs

You can use the Descope management SDK to run Management Flows and retrieve their outputs. The management SDK requires a management key, which can be generated here.

For an overview of Management Flows, see Management Flows.

Backend SDK

Install SDK

Terminal
npm i --save @descope/node-sdk
Terminal
pip3 install descope
Terminal
go 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>
Terminal
gem install descope
Terminal
composer require descope/descope-php
Terminal
dotnet add package Descope

Import 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);

Run Management Flow

Note

You can also use our Run Management Flow API to run a Management Flow.

This operation runs a Management Flow by its flow ID. Outputs configured on the flow End action are returned in the response.

The flow must be a Management Flow, not an interactive flow.

// Args:
//   flowId (str): The Management Flow ID to run.
const flowId = "my-management-flow";
//   options (object): Optional run options.
//     input (object): Optional key/value input available in the flow as client.<key>.
const options = {
  input: {
    email: "user@example.com",
  },
};

const resp = await descopeClient.management.flow.run(flowId, options);
if (!resp.ok) {
  console.log("Failed to run management 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 ran management flow.")
  console.log(resp.data)
}
# Args:
#   flow_id (str): The Management Flow ID to run.
flow_id = "my-management-flow"
#   options (FlowRunOptions | dict): Optional run options.
#     input (dict): Optional key/value input available in the flow as client.<key>.
#     preview (bool): Optional preview flag.
#     tenant (str): Optional tenant ID.
from descope import FlowRunOptions

options = FlowRunOptions(
    input={"email": "user@example.com"},
)

try:
  resp = descope_client.mgmt.flow.run_flow(
      flow_id=flow_id,
      options=options,
  )
  print("Successfully ran management flow.")
  print(resp)
except AuthException as error:
  print("Failed to run management flow.")
  print("Status Code: " + str(error.status_code))
  print("Error: " + str(error.error_message))
// Args:
//   ctx: context.Context - Application context for cancellation and deadlines.
//        In cases where context is absent, context.Background() is a viable alternative.
//        Utilizing context within the Descope GO SDK is supported within versions 1.6.0 and higher.
ctx := context.Background()
//   flowID (str): The Management Flow ID to run.
flowID := "my-management-flow"
//   options (*descope.MgmtFlowOptions): Optional run options.
//     Input (map[string]any): Optional key/value input available in the flow as client.<key>.
options := &descope.MgmtFlowOptions{
  Input: map[string]any{
    "email": "user@example.com",
  },
}

res, err := descopeClient.Management.Flow().RunManagementFlow(ctx, flowID, options)
if err != nil {
  fmt.Println("Failed to run management flow: ", err)
} else {
  fmt.Println("Successfully ran management flow.")
  fmt.Println(res)
}
// Args:
//   request (RunManagementFlowRequest): Request containing the flow ID and optional options.
//     FlowId (string): The Management Flow ID to run.
//     Options (ManagementFlowOptions?): Optional run options.
//       Input (ManagementFlowOptions_input?): Optional input; keys go in AdditionalData and are available as client.<key>.
//       Preview (bool?): Optional preview flag.
//       Tenant (string?): Optional tenant ID.
var request = new RunManagementFlowRequest
{
    FlowId = "my-management-flow",
    Options = new ManagementFlowOptions
    {
        Input = new ManagementFlowOptions_input
        {
            AdditionalData = new Dictionary<string, object>
            {
                { "email", "user@example.com" }
            }
        }
    }
};

try
{
    var response = await descopeClient.Mgmt.V1.Flow.Run.PostWithJsonOutputAsync(request);
    
    // Access JSON properties directly using JsonElement
    var root = response.OutputJson!.Value;
    var email = root.GetProperty("email").GetString();

    // Access nested objects using standard JsonElement methods
    var count = root.GetProperty("obj").GetProperty("count").GetInt32();
    var enabled = root.GetProperty("obj").GetProperty("enabled").GetBoolean();
}
catch (DescopeException ex)
{
    // Handle the error
}

Run Management Flow Asynchronously

Note

You can also use our Run Management Flow Async API to run a Management Flow asynchronously.

For long-running Management Flows, start an asynchronous run to receive an execution ID immediately. Use Get Management Flow Async Result with that ID to retrieve the output when the flow completes.

# Args:
#   flow_id (str): The Management Flow ID to run.
flow_id = "my-management-flow"
#   options (FlowRunOptions | dict): Optional run options.
#     input (dict): Optional key/value input available in the flow as client.<key>.
from descope import FlowRunOptions

options = FlowRunOptions(
    input={"email": "user@example.com"},
)

try:
  # Returns immediately with an execution ID
  async_result = descope_client.mgmt.flow.run_flow_async(
      flow_id=flow_id,
      options=options,
  )
  execution_id = async_result["executionId"]
  print("Successfully started async management flow.")
  print(execution_id)
except AuthException as error:
  print("Failed to run management flow asynchronously.")
  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 Management Flow ID to run.
flowID := "my-management-flow"
//   options (*descope.MgmtFlowOptions): Optional run options.
options := &descope.MgmtFlowOptions{
  Input: map[string]any{
    "email": "user@example.com",
  },
}

executionID, err := descopeClient.Management.Flow().RunManagementFlowAsync(ctx, flowID, options)
if err != nil {
  fmt.Println("Failed to start async management flow: ", err)
} else {
  fmt.Println("Successfully started async management flow.")
  fmt.Println(executionID)
}
// Args:
//   request (RunManagementFlowRequest): Same request shape as the synchronous run.
var request = new RunManagementFlowRequest
{
    FlowId = "my-management-flow",
    Options = new ManagementFlowOptions
    {
        Input = new ManagementFlowOptions_input
        {
            AdditionalData = new Dictionary<string, object>
            {
                { "email", "user@example.com" }
            }
        }
    }
};

try
{
    // Returns immediately with an execution ID
    var asyncResponse = await descopeClient.Mgmt.V1.Flow.Async.Run.PostAsync(request);
    var executionId = asyncResponse!.ExecutionId;
}
catch (DescopeException ex)
{
    // Handle the error
}

Get Management Flow Async Result

Note

You can also use our Get Management Flow Async Result API to get the result of an asynchronous Management Flow.

This operation fetches the result of an asynchronous Management Flow run using the execution ID returned by Run Management Flow Asynchronously. Poll this endpoint until the flow completes.

# Args:
#   execution_id (str): The execution ID returned by run_flow_async.
execution_id = "execution-id-from-async-run"

try:
  resp = descope_client.mgmt.flow.get_flow_async_result(
      execution_id=execution_id,
  )
  print("Successfully retrieved async management flow result.")
  print(resp)
except AuthException as error:
  print("Failed to get async management flow result.")
  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()
//   executionID (str): The execution ID returned by RunManagementFlowAsync.
executionID := "execution-id-from-async-run"

res, err := descopeClient.Management.Flow().GetManagementFlowAsyncResult(ctx, executionID)
if err != nil {
  fmt.Println("Failed to get async management flow result: ", err)
} else {
  fmt.Println("Successfully retrieved async management flow result.")
  fmt.Println(res)
}
// Args:
//   resultRequest (GetManagementFlowAsyncResultRequest): Request containing the execution ID.
//     ExecutionId (string): The execution ID returned by the async run.
var resultRequest = new GetManagementFlowAsyncResultRequest
{
    ExecutionId = "execution-id-from-async-run"
};

try
{
    var result = await descopeClient.Mgmt.V1.Flow.Async.Result.PostAsync(resultRequest);
}
catch (DescopeException ex)
{
    // Handle the error
}
Was this helpful?

On this page