A .NET SDK for integrating with the Descope authentication and user management platform.
dotnet add package Descope
Configure the Descope client using DescopeClientOptions:
var options = new DescopeClientOptions { ProjectId = "your-project-id", // Required ManagementKey = "your-management-key", // Optional, for management APIs AuthManagementKey = "your-auth-key", // Optional, for accessing disabled auth APIs BaseUrl = "https://api.descope.com", // Optional, auto-detected from project ID FgaCacheUrl = "https://fga.example.com", // Optional, if using the Descope FGA Cache Docker Container IsUnsafe = false // Optional, for dev/test only };
services.AddDescopeClient(new DescopeClientOptions { ProjectId = "your-project-id", ManagementKey = "your-management-key" }); // Inject IDescopeClient in your services public class MyService { private readonly IDescopeClient _client; public MyService(IDescopeClient client) { _client = client; } }
var client = DescopeManagementClientFactory.Create(new DescopeClientOptions { ProjectId = "your-project-id", ManagementKey = "your-management-key" });
// Verify a magic link token var response = await client.Auth.V1.Magiclink.Verify.PostAsync( new VerifyMagicLinkRequest { Token = "magic-link-token" });
// Create a test user var user = await client.Mgmt.V1.User.Create.Test.PostAsync( new CreateUserRequest { Identifier = "user@example.com", Email = "user@example.com", VerifiedEmail = true });
// Search users var searchResponse = await client.Mgmt.V2.User.Search.PostAsync( new SearchUsersRequest { Limit = 10 });
Management flows allow you to run server-side flows with custom input and receive dynamic output. The SDK provides a convenient extension method that deserializes the output as JSON for easy access.
// Run a management flow with custom input var request = new RunManagementFlowRequest { FlowId = "my-management-flow", Options = new ManagementFlowOptions { Input = new ManagementFlowOptions_input { AdditionalData = new Dictionary<string, object> { { "email", "user@example.com" }, { "customParam", "customValue" } } } } }; var response = await client.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 greeting = root.GetProperty("obj").GetProperty("greeting").GetString(); var count = root.GetProperty("obj").GetProperty("count").GetInt32(); var enabled = root.GetProperty("obj").GetProperty("enabled").GetBoolean();
The SDK provides three methods for working with session tokens:
Validates a session JWT locally using cached public keys. The public key is fetched from the server only once and then cached for subsequent validations.
var token = await client.Auth.ValidateSessionAsync(sessionJwt); // Returns Token with claims, subject, expiration, etc.
Refreshes an expired session using a refresh JWT. This method makes a remote API call to generate a new session token.
var newToken = await client.Auth.RefreshSessionAsync(refreshJwt); // Returns a new session Token with updated expiration
Attempts to validate the session JWT first (locally), and if that fails or the session is empty, falls back to refreshing using the refresh JWT (remote call).
var token = await client.Auth.ValidateAndRefreshSession(sessionJwt, refreshJwt); // Returns valid Token, using local validation when possible
Performance Note: Validation calls (ValidateSessionAsync, ValidateAndRefreshSession) are highly efficient as they use locally cached public keys. Only RefreshSessionAsync and the refresh fallback in ValidateAndRefreshSession make remote API calls.
Some authentication operations require an authenticated user context and must be called with a refresh JWT. For these operations, use the PostWithJwt extension methods that explicitly require the refresh token.
// Update user email using magic link (requires refresh JWT) var response = await client.Auth.V1.Magiclink.Update.Email.PostWithJwtAsync( new UpdateUserEmailMagicLinkRequest { Email = "newemail@example.com", RedirectUrl = "https://myapp.com/verify" }, refreshJwt);
Other operations requiring PostWithJwt include, among others: updating phone numbers, passwords, TOTP settings, WebAuthn devices, and getting user details via the /me endpoint.
For ASP.NET Core applications, use the AddDescopeOidcAuthentication extension method to integrate Descope as your Identity Provider (IdP) using OpenID Connect (OIDC):
builder.Services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme) .AddDescopeOidcAuthentication(options => { options.ProjectId = "your-project-id"; });
See the OIDC Demo Application for a complete working example with additional customization options.
If you're maintaining or contributing to this SDK, see the Maintainer Guide for detailed information about code generation, extension methods, testing, and development workflows.