Please review this guide thoroughly to understand the changes required to migrate Auth0.ManagementApi from v8 to v9.
The Auth0 .NET SDK v9 builds on the v8 foundation (OpenAPI-generated via Fern, System.Text.Json, ManagementClient with automatic token management). The client initialization, request/response type naming, pagination model (Pager<T>), and sub-client organization introduced in v8 are unchanged in v9.
v9 focuses on:
- Uniform raw-response access across every operation, including endpoints that return no body
- Richer exception information: structured API errors, rate limit, and quota details parsed from response headers
- New Management API surface: Organization Roles members, Token Vault privileged access grants, and Connection lifecycle event streams
- More precise types: per-attribute Connection identifier types replacing a single shared type
- Surface removals: the Federated Connections Tokens client and related types have been removed, along with the
asnclient session transfer device binding value
Scope: This guide covers
Auth0.ManagementApionly. If you are still on v7, migrate to v8 first using the v7 to v8 Migration Guide.
The package name is unchanged; only the version changes.
v8:
<PackageReference Include="Auth0.ManagementApi" Version="8.x.x" />v9:
<PackageReference Include="Auth0.ManagementApi" Version="9.x.x" />In v8, operations with no response body (deletes, unblocks, and other side-effecting calls) returned a plain Task. In v9 these return the new non-generic WithRawResponseTask, mirroring how body-returning methods return WithRawResponseTask<T>. This gives every operation access to raw HTTP response metadata (status code, URL, headers) via .WithRawResponse().
This change affects approximately 97 methods across the client interfaces (DeleteAsync, UnblockIpAsync, CheckIpAsync, SetAsync, UpdateUniversalLoginAsync, and similar void operations).
v8:
Task DeleteAsync(
string id,
RequestOptions? options = null,
CancellationToken cancellationToken = default);v9:
WithRawResponseTask DeleteAsync(
string id,
RequestOptions? options = null,
CancellationToken cancellationToken = default);What you need to do — usually nothing. WithRawResponseTask is awaitable and completes with no value (void semantics), and it defines an implicit conversion to Task. Existing await call sites continue to compile and behave identically:
// Works in both v8 and v9
await client.Users.DeleteAsync("user_id");You only need to change code that relied on the return type being exactly Task:
// v8 — storing the result as Task
Task deletion = client.Users.DeleteAsync("user_id");
await deletion;
// v9 — either await directly, or convert explicitly
await client.Users.DeleteAsync("user_id");
// or, if you must hold a Task reference:
Task deletion = client.Users.DeleteAsync("user_id"); // implicit conversion applies
await deletion;New capability — you can now read response metadata from these operations:
var raw = await client.Users.DeleteAsync("user_id").WithRawResponse();
Console.WriteLine($"Status: {raw.StatusCode}");
if (raw.Headers.TryGetValue("X-Request-Id", out var requestId))
{
Console.WriteLine($"Request ID: {requestId}");
}Note: Method groups passed where a
Task-returning delegate is expected (e.g.Func<..., Task>) may need an explicit lambda wrapper, since the method now returnsWithRawResponseTaskrather thanTask.
The single shared ConnectionAttributeIdentifier type has been split into three per-attribute types. The Identifier property on each Connection attribute now uses its own type instead of the shared one.
| Attribute type | v8 Identifier type |
v9 Identifier type |
|---|---|---|
EmailAttribute |
ConnectionAttributeIdentifier |
EmailAttributeIdentifier |
PhoneAttribute |
ConnectionAttributeIdentifier |
PhoneAttributeIdentifier |
UsernameAttribute |
ConnectionAttributeIdentifier |
UsernameAttributeIdentifier |
Each new type carries an Active flag and an attribute-specific DefaultMethod enum (for example, EmailAttributeIdentifier.DefaultMethod is a DefaultMethodEmailIdentifierEnum?).
v8:
var email = new EmailAttribute
{
Identifier = new ConnectionAttributeIdentifier { Active = true }
};v9:
var email = new EmailAttribute
{
Identifier = new EmailAttributeIdentifier
{
Active = true,
DefaultMethod = DefaultMethodEmailIdentifierEnum.Email
}
};What you need to do: Replace references to ConnectionAttributeIdentifier with the type matching the attribute you are configuring. Any code that constructed or read ConnectionAttributeIdentifier directly will fail to compile and must be updated.
The Federated Connections Tokens surface has been removed in v9. This affects the Users.FederatedConnectionsTokensets sub-client, its associated types, the federated_connections_access_tokens connection option, and the related OAuth scopes.
Removed members:
| Removed in v9 | Kind |
|---|---|
client.Users.FederatedConnectionsTokensets (ListAsync, DeleteAsync) |
Sub-client |
FederatedConnectionTokenSet |
Type |
ConnectionFederatedConnectionsAccessTokens |
Type |
FederatedConnectionsAccessTokens property on ConnectionPropertiesOptions, UpdateConnectionOptions, ConnectionOptionsAzureAd, ConnectionOptionsCommonOidc, ConnectionOptionsGoogleApps, ConnectionOptionsOidc, ConnectionOptionsOkta |
Property |
OauthScope.ReadFederatedConnectionsTokens (read:federated_connections_tokens) |
Scope constant |
OauthScope.DeleteFederatedConnectionsTokens (delete:federated_connections_tokens) |
Scope constant |
v8:
// Listing / deleting a user's federated connection token sets
var tokenSets = await client.Users.FederatedConnectionsTokensets.ListAsync("user_id");
await client.Users.FederatedConnectionsTokensets.DeleteAsync("user_id");
// Enabling token collection on a connection option
var options = new ConnectionOptionsOidc
{
FederatedConnectionsAccessTokens = new ConnectionFederatedConnectionsAccessTokens
{
Active = true
}
};v9: No replacement. Remove the sub-client calls, the FederatedConnectionsAccessTokens assignments, and any use of the removed scope constants. Any code referencing these members will fail to compile and must be deleted.
What you need to do: Delete all usages of the members listed above. If you were relying on federated connection token collection, coordinate the replacement approach with the Auth0 API rather than the SDK.
The Asn value has been removed from ClientSessionTransferDelegationDeviceBindingEnum. Only Ip remains.
v8:
var binding = ClientSessionTransferDelegationDeviceBindingEnum.Asn;v9:
// Asn is no longer available; only Ip remains
var binding = ClientSessionTransferDelegationDeviceBindingEnum.Ip;What you need to do: Replace any use of ClientSessionTransferDelegationDeviceBindingEnum.Asn (or the string value "asn"). Code referencing the removed value will fail to compile.
dotnet add package Auth0.ManagementApi --version 9.*Or update your .csproj:
<PackageReference Include="Auth0.ManagementApi" Version="9.*" />Most v8 code compiles unchanged. The breaking changes surface as compiler errors:
ConnectionAttributeIdentifiernot found — replace withEmailAttributeIdentifier,PhoneAttributeIdentifier, orUsernameAttributeIdentifieras appropriate (see Connection Attribute Identifier Types).- Cannot implicitly convert
WithRawResponseTasktoTask— only appears where a delete/void method result was stored as an explicitTaskor passed to aTask-typed parameter. Await it directly, or rely on the implicit conversion (see Void-Returning Methods). FederatedConnectionsTokensets/FederatedConnectionTokenSet/ConnectionFederatedConnectionsAccessTokens/FederatedConnectionsAccessTokensnot found — the Federated Connections Tokens surface was removed; delete these usages (see Federated Connections Tokens Removed).ClientSessionTransferDelegationDeviceBindingEnumdoes not contain a definition forAsn— useIp;Asnwas removed (seeAsnDevice Binding Value Removed).
If you handle ManagementApiException (or its subtypes such as TooManyRequestsError), you can now read structured error and rate-limit data. See Enriched Exceptions.
ManagementApiException now exposes structured, lazily-parsed error and rate-limit information. All members are additive — existing StatusCode and Body access is unchanged.
using Auth0.ManagementApi;
try
{
await client.Users.GetAsync("user_id", new GetUserRequestParameters());
}
catch (TooManyRequestsError ex)
{
// Structured error payload parsed from the response body
string? code = ex.ErrorCode; // machine-readable error code
string? description = ex.Description; // human-readable message
ApiError? apiError = ex.ApiError; // full structured error, or null
// Rate limit details parsed from response headers
RateLimit? rl = ex.RateLimit;
long? remaining = rl?.Remaining; // x-ratelimit-remaining
DateTimeOffset? reset = rl?.Reset; // x-ratelimit-reset
TimeSpan? retryAfter = rl?.RetryAfter; // retry-after
// Quota details (when present)
var clientQuota = rl?.ClientQuotaLimit; // Auth0-Client-Quota-Limit
var orgQuota = rl?.OrganizationQuotaLimit; // Auth0-Organization-Quota-Limit
}
catch (ManagementApiException ex)
{
int statusCode = ex.StatusCode;
object body = ex.Body;
string? errorCode = ex.ErrorCode;
string message = ex.Message; // now surfaces the API's error description when available
}Key additions on ManagementApiException:
| Member | Description |
|---|---|
ApiError? ApiError |
Structured error (Error, ErrorCode, Message) parsed from the body, or null |
string? ErrorCode |
Machine-readable error code shortcut |
string? Description |
Human-readable error description shortcut |
RateLimit? RateLimit |
Rate limit + quota info parsed from response headers, or null |
RawResponse? RawResponse |
Raw HTTP response (status, URL, headers) when available |
Note:
Messagenow returns the API's error description when one was parsed, falling back to the SDK's default message otherwise. If you log or assert on exact message text, review those sites.
v9 adds a Members sub-client under Organization Roles, letting you list the organization members assigned a specific role within an organization.
var pager = await client.Organizations.Roles.Members.ListAsync(
id: "org_id",
roleId: "rol_id",
new ListOrganizationRoleMembersRequestParameters());
await foreach (var member in pager)
{
Console.WriteLine(member);
}The result is a Pager<RoleMember>, consistent with the v8 pagination model.
v9 adds the TokenVaultPrivilegedAccessGrant type for granting client credential (M2M) applications privileged access to Token Vault connections and scopes.
var grant = new TokenVaultPrivilegedAccessGrant
{
Connection = "google-oauth2",
Scopes = new[] { "https://www.googleapis.com/auth/calendar" }
};The Event Streams surface now includes Connection lifecycle CloudEvents (for example, EventStreamCloudEventConnectionCreated), enabling event-driven workflows that react to connection changes. Event stream delivery and redelivery clients were extended accordingly, backed by a new server-sent-events (SSE) reconnect helper for resilient streaming.
NetworkAclMatch gains an optional Auth0Managed property (IEnumerable<string>?, JSON auth0_managed), letting you match against Auth0-managed network lists in ACL rules.
var match = new NetworkAclMatch
{
Auth0Managed = new[] { "some-managed-list" }
};v9 introduces typed error body records — NotFoundErrorBody and TooManyRequestsErrorBody (with their nested *Error types) — carrying Message, StatusCode, and a structured Error. These complement the enriched exception members above when you need to deserialize an error payload into a strong type.
- No client initialization changes:
ManagementClient,ManagementClientOptions,ITokenProvider, and the token provider implementations are unchanged from v8. - No pagination changes: List operations continue to return
Pager<T>withIAsyncEnumerable<T>iteration,AsPagesAsync(), andGetNextPageAsync(). Optional<T>for PATCH semantics are unchanged from v8.- Uniform raw-response access: every operation — including void operations — now supports
.WithRawResponse()for status code, URL, and header inspection.
The type or namespace name 'ConnectionAttributeIdentifier' could not be found: Replace withEmailAttributeIdentifier,PhoneAttributeIdentifier, orUsernameAttributeIdentifiermatching the attribute.Cannot implicitly convert type 'WithRawResponseTask' to 'System.Threading.Tasks.Task': Await the call directly instead of assigning to aTaskvariable, or rely on the implicit conversion. Wrap in a lambda if passing as aFunc<..., Task>delegate.- Unexpected exception message text:
ManagementApiException.Messagenow surfaces the parsed API error description when available — update log assertions if needed. 'IUsersClient' does not contain a definition for 'FederatedConnectionsTokensets'(or missingFederatedConnectionTokenSet/ConnectionFederatedConnectionsAccessTokens/FederatedConnectionsAccessTokens): the Federated Connections Tokens surface was removed in v9 — delete these usages.'ClientSessionTransferDelegationDeviceBindingEnum' does not contain a definition for 'Asn': theAsnvalue was removed — useIp.
- Check the API Reference Documentation
- Review the Examples in the repository
- Open an issue on GitHub for specific migration problems
This migration guide covers the changes needed to upgrade Auth0.ManagementApi from v8 to v9. The breaking-change surface is small — most v8 code compiles unchanged — while v9 adds richer exceptions, uniform raw-response access, and new Management API capabilities.