Documentation Index
Fetch the complete documentation index at: https://docs.dynamic.xyz/docs/llms.txt
Use this file to discover all available pages before exploring further.
This guide is only relevant if you previously used action-based MFA to protect sensitive wallet operations. If you didn’t, you can skip it.
If you previously used action-based MFA to protect sensitive wallet operations, step-up authentication replaces and extends that functionality. The core concept is the same — require users to re-verify before sensitive actions — but step-up auth adds scoped elevated access tokens, re-authentication methods for non-MFA users, and automatic token handling by the SDK.
What changed
| Action-based MFA (before) | Step-up authentication (after) |
|---|
| Hook | useMfa / useAuthenticatePasskeyMFA | useStepUpAuthentication |
| Token type | Unscoped MFA token (createMfaToken) | Scoped elevated access token (requestedScopes) |
| Token handling | SDK-managed MFA token | SDK-managed elevated access token (scoped JWT) |
| Who can verify | Only users with MFA methods (TOTP/Passkey) | All users — MFA methods, email OTP, SMS OTP, wallet signature, or social OAuth |
| Scope | None — token accepted for any action | Bound to specific scopes (wallet:export, wallet:sign, credential:link, credential:unlink) |
| Expiration | Single-use, no time limit | Time-limited (5 min single-use, 10 min multi-use) |
Dashboard changes
No dashboard changes are required — your existing action-based MFA event
configuration (WaaS Export, WaaS Refresh, WaaS Sign, WaaS Reshare) carries over.
Make sure your code is fully updated before accepting the minimum API version at Dashboard > Developers > API & SDK Keys. Once set to 2026_04_01, the backend enforces step-up authentication immediately.
AI-assisted upgrade prompts
These prompts are designed for AI coding agents (Cursor, Claude Code, Copilot). Always review generated code before committing — agents can misread your project structure.For best results, install the Dynamic MCP in your agent so it can reference live documentation automatically. If you don’t have it installed, the prompts fall back to https://www.dynamic.xyz/docs/llms.txt.
Copy the prompt for your SDK and run it in your agent.
React
JavaScript
React Native
Flutter
Kotlin
Swift
I'm migrating my Dynamic SDK headless integration from action-based MFA to step-up authentication as part of the 2026_04_01 API upgrade.
If you have the Dynamic MCP installed, use it to reference the latest API.
Otherwise reference: https://www.dynamic.xyz/docs/llms.txt
In my codebase:
1. Find all usages of `useMfa`, `useAuthenticatePasskeyMFA`, and `usePromptMfaAuth`
2. Replace them with `useStepUpAuthentication` from `@dynamic-labs/sdk-react-core`
3. Replace all `createMfaToken` options with `requestedScopes` using the
appropriate `TokenScope` from `@dynamic-labs/sdk-api-core`
4. Replace all `useIsMfaRequiredForAction` calls with `isStepUpRequired`
5. Do not modify any files outside of the auth flow
After making changes, summarize what was updated and flag anything that
needs manual review.
I'm migrating my Dynamic SDK headless integration from action-based MFA
to step-up authentication as part of the 2026_04_01 API upgrade.
If you have the Dynamic MCP installed, use it to reference the latest API.
Otherwise reference: https://www.dynamic.xyz/docs/llms.txt
In my codebase:
1. Find all usages of `isMfaRequiredForAction` from `@dynamic-labs-sdk/client`
2. Replace them with `checkStepUpAuth`
3. Replace all `createMfaToken` and `createMfaTokenOptions` with `requestedScopes`
using the appropriate `TokenScope` from `@dynamic-labs/sdk-api-core`
on both `authenticateTotpMfaDevice` and `authenticatePasskeyMFA`
4. Do not modify any files outside of the auth flow
After making changes, summarize what was updated and flag anything that
needs manual review.
I'm migrating my Dynamic SDK headless integration from action-based MFA
to step-up authentication as part of the 2026_04_01 API upgrade.
If you have the Dynamic MCP installed, use it to reference the latest API.
Otherwise reference: https://www.dynamic.xyz/docs/llms.txt
In my codebase:
1. Find all usages of `client.mfa.isRequiredForAction` and replace with
`client.stepUpAuth.isStepUpRequired`
2. Find all usages of `client.mfa.authenticateDevice` and replace with
`client.stepUpAuth.verifyTotpMfa`
3. Find all usages of `client.passkeys.authenticateMFA` and replace with
`client.stepUpAuth.verifyPasskeyMfa`
4. Find all usages of `client.ui.mfa.show` and replace with
`client.stepUpAuth.promptStepUpAuth`
5. Replace all `createMfaToken` options with `requestedScopes` using
the appropriate `TokenScope`
6. Do not modify any files outside of the auth flow
After making changes, summarize what was updated and flag anything that
needs manual review.
I'm migrating my Dynamic SDK headless integration from action-based MFA
to step-up authentication as part of the 2026_04_01 API upgrade.
If you have the Dynamic MCP installed, use it to reference the latest API.
Otherwise reference: https://www.dynamic.xyz/docs/llms.txt
In my codebase:
1. Find all usages of DynamicSDK.instance.mfa related to action-based MFA checks
2. Replace them with DynamicSDK.instance.stepUpAuth.isStepUpRequired
3. Replace verification calls with the appropriate method:
- TOTP: DynamicSDK.instance.stepUpAuth.verifyTotpMfa
- Passkey: DynamicSDK.instance.stepUpAuth.verifyPasskeyMfa
- Prompt: DynamicSDK.instance.stepUpAuth.promptStepUpAuth
4. Replace all scope arguments with the string equivalents:
'wallet:export', 'wallet:sign', 'credential:link', 'credential:unlink'
5. Do not modify any files outside of the auth flow
After making changes, summarize what was updated and flag anything that
needs manual review.
I'm migrating my Dynamic SDK headless integration from action-based MFA
to step-up authentication as part of the 2026_04_01 API upgrade.
If you have the Dynamic MCP installed, use it to reference the latest API.
Otherwise reference: https://www.dynamic.xyz/docs/llms.txt
In my codebase:
1. Find all usages of action-based MFA checks in my Kotlin integration
2. Replace them with sdk.stepUpAuth.isStepUpRequired(scope)
3. Replace verification calls with the appropriate method:
- TOTP: sdk.stepUpAuth.verifyTotpMfa(code, deviceId, requestedScopes)
- Passkey: sdk.stepUpAuth.verifyPasskeyMfa(requestedScopes)
- OTP: sdk.stepUpAuth.verifyOtp(verificationToken, requestedScopes)
- Or let the SDK decide: sdk.stepUpAuth.promptStepUpAuth(requestedScopes)
4. Replace all scope arguments with the appropriate string equivalents:
'wallet:export', 'wallet:sign', 'credential:link', 'credential:unlink'
5. Do not modify any files outside of the auth flow
After making changes, summarize what was updated and flag anything that
needs manual review.
I'm migrating my Dynamic SDK headless integration from action-based MFA
to step-up authentication as part of the 2026_04_01 API upgrade.
If you have the Dynamic MCP installed, use it to reference the latest API.
Otherwise reference: https://www.dynamic.xyz/docs/llms.txt
In my codebase:
1. Find all usages of action-based MFA checks in my Swift integration
2. Replace them with sdk.stepUpAuth.isStepUpRequired(scope:)
3. Replace verification calls with the appropriate method:
- TOTP: sdk.stepUpAuth.verifyTotpMfa(code:deviceId:requestedScopes:)
- Passkey: sdk.stepUpAuth.verifyPasskeyMfa(requestedScopes:)
- OTP: sdk.stepUpAuth.verifyOtp(verificationToken:requestedScopes:)
- Or let the SDK decide: sdk.stepUpAuth.promptStepUpAuth(requestedScopes:)
4. Replace all scope arguments with the appropriate string equivalents:
'wallet:export', 'wallet:sign', 'credential:link', 'credential:unlink'
5. Do not modify any files outside of the auth flow
After making changes, summarize what was updated and flag anything that
needs manual review.
Code migration: before and after
The After examples include an else branch that falls through to legacy action-based MFA. It is only needed if some of your users already have legacy MFA enabled and you’re deploying the updated SDK before the 2026_04_01 API version is confirmed. Once both the SDK and the minimum API version are upgraded, the transitional else branches can be removed since they are no longer needed.
Using Dynamic’s built-in UI
React
React Native
Flutter (no built-in UI)
Before — usePromptMfaAuth with createMfaToken: import { usePromptMfaAuth, useIsMfaRequiredForAction } from "@dynamic-labs/sdk-react-core";
import { MFAAction } from '@dynamic-labs/sdk-api-core';
const isMfaRequiredForAction = useIsMfaRequiredForAction();
const promptMfaAuth = usePromptMfaAuth();
const isMfaRequired = await isMfaRequiredForAction({
mfaAction: MFAAction.WalletWaasExport,
});
if (isMfaRequired) {
await promptMfaAuth({ createMfaToken: true });
}
await primaryWallet.exportWaasPrivateKey();
After — useStepUpAuthentication with requestedScopes. The else branch is only needed if some of your users already have legacy MFA enabled — it handles the window when the frontend is deployed before the 2026_04_01 API version is confirmed. Remove it once both the SDK and the minimum API version are upgraded: import {
useStepUpAuthentication,
usePromptMfaAuth,
useIsMfaRequiredForAction,
} from '@dynamic-labs/sdk-react-core';
import { TokenScope, MFAAction } from '@dynamic-labs/sdk-api-core';
const { isStepUpRequired, promptStepUpAuth } = useStepUpAuthentication();
const promptMfaAuth = usePromptMfaAuth();
const isMfaRequiredForAction = useIsMfaRequiredForAction();
if (await isStepUpRequired({ scope: TokenScope.Walletexport })) {
await promptStepUpAuth({
requestedScopes: [TokenScope.Walletexport],
});
} else {
// Transitional: 2026_04_01 API version not yet confirmed.
// Legacy MFA prompt for users with an existing passkey / TOTP / device.
const isMfaRequired = await isMfaRequiredForAction({
mfaAction: MFAAction.WalletWaasExport,
});
if (isMfaRequired) {
await promptMfaAuth({ createMfaToken: true });
}
}
// Token is stored — SDK attaches it automatically
await primaryWallet.exportWaasPrivateKey();
Before — client.ui.mfa.show with createMfaToken: import { MFAAction } from '@dynamic-labs/sdk-api-core';
const isMfaRequired = await client.mfa.isRequiredForAction({
mfaAction: MFAAction.WalletWaasExport,
});
if (isMfaRequired) {
await client.ui.mfa.show({ createMfaToken: true });
}
await primaryWallet.exportWaasPrivateKey();
After — client.stepUpAuth.promptStepUpAuth with requestedScopes. The else branch is only needed if some of your users already have legacy MFA enabled — it handles the window when the frontend is deployed before the 2026_04_01 API version is confirmed. Remove it once both the SDK and the minimum API version are upgraded: import { TokenScope, MFAAction } from '@dynamic-labs/sdk-api-core';
const isRequired = await client.stepUpAuth.isStepUpRequired({
scope: TokenScope.Walletexport,
});
if (isRequired) {
await client.stepUpAuth.promptStepUpAuth({
requestedScopes: [TokenScope.Walletexport],
});
} else {
// Transitional: 2026_04_01 API version not yet confirmed.
// Legacy MFA prompt for users with an existing passkey / TOTP / device.
const mfaRequired = await client.mfa.isRequiredForAction({
mfaAction: MFAAction.WalletWaasExport,
});
if (mfaRequired) {
await client.ui.mfa.show({ createMfaToken: true });
}
}
// Token is stored — SDK attaches it automatically
await primaryWallet.exportWaasPrivateKey();
Flutter did not have a built-in action-based MFA UI. Use promptStepUpAuth to add step-up verification: import 'package:dynamic_sdk/dynamic_sdk.dart';
final isRequired = await DynamicSDK.instance.stepUpAuth
.isStepUpRequired('wallet:export');
if (isRequired) {
await DynamicSDK.instance.stepUpAuth.promptStepUpAuth(
requestedScopes: ['wallet:export'],
);
}
// Token is stored — SDK attaches it automatically
await performExport();
Headless TOTP
React
JavaScript
React Native
Flutter
Before — useMfa with authenticateDevice and createMfaToken: import { useMfa, useIsMfaRequiredForAction } from "@dynamic-labs/sdk-react-core";
import { MFAAction } from '@dynamic-labs/sdk-api-core';
const { authenticateDevice } = useMfa();
const isMfaRequiredForAction = useIsMfaRequiredForAction();
const requires = await isMfaRequiredForAction({
mfaAction: MFAAction.WalletWaasExport,
});
if (requires) {
await authenticateDevice({
code: totpCode,
createMfaToken: { singleUse: true },
});
}
After — useStepUpAuthentication with verifyTotpMfa. The else branch is only needed if some of your users already have legacy MFA enabled — it handles the window before the 2026_04_01 API version is confirmed. Remove it once both the SDK and the minimum API version are upgraded: import {
useStepUpAuthentication,
useMfa,
useIsMfaRequiredForAction,
} from '@dynamic-labs/sdk-react-core';
import { TokenScope, MFAAction } from '@dynamic-labs/sdk-api-core';
const { isStepUpRequired, verifyTotpMfa } = useStepUpAuthentication();
const { authenticateDevice } = useMfa();
const isMfaRequiredForAction = useIsMfaRequiredForAction();
if (await isStepUpRequired({ scope: TokenScope.Walletexport })) {
await verifyTotpMfa({
code: totpCode,
requestedScopes: [TokenScope.Walletexport],
});
} else {
// Transitional: 2026_04_01 API version not yet confirmed.
// Legacy TOTP verification for users with an existing MFA device.
const requires = await isMfaRequiredForAction({
mfaAction: MFAAction.WalletWaasExport,
});
if (requires) {
await authenticateDevice({
code: totpCode,
createMfaToken: { singleUse: true },
});
}
}
Before — authenticateTotpMfaDevice with createMfaTokenOptions: import { isMfaRequiredForAction, authenticateTotpMfaDevice, MFAAction } from '@dynamic-labs-sdk/client';
const required = await isMfaRequiredForAction({ mfaAction: MFAAction.WalletWaasExport });
if (required) {
await authenticateTotpMfaDevice({
code: '123456',
createMfaTokenOptions: { singleUse: true },
});
}
After — same function with requestedScopes. The else branch is only needed if some of your users already have legacy MFA enabled — it handles the window before the 2026_04_01 API version is confirmed. Remove it once both the SDK and the minimum API version are upgraded: import {
checkStepUpAuth,
authenticateTotpMfaDevice,
isMfaRequiredForAction,
MFAAction,
} from '@dynamic-labs-sdk/client';
import { TokenScope } from '@dynamic-labs/sdk-api-core';
const { isRequired } = await checkStepUpAuth({ scope: TokenScope.Walletexport });
if (isRequired) {
await authenticateTotpMfaDevice({
code: '123456',
requestedScopes: [TokenScope.Walletexport],
});
} else {
// Transitional: 2026_04_01 API version not yet confirmed.
// Legacy TOTP verification for users with an existing MFA device.
const required = await isMfaRequiredForAction({ mfaAction: MFAAction.WalletWaasExport });
if (required) {
await authenticateTotpMfaDevice({
code: '123456',
createMfaTokenOptions: { singleUse: true },
});
}
}
Before — client.mfa.authenticateDevice with createMfaToken: import { MFAAction } from '@dynamic-labs/sdk-api-core';
const requires = await client.mfa.isRequiredForAction({
mfaAction: MFAAction.WalletWaasExport,
});
if (requires) {
await client.mfa.authenticateDevice({
code: totpCode,
createMfaToken: { singleUse: true },
});
}
After — client.stepUpAuth.verifyTotpMfa with requestedScopes. The else branch is only needed if some of your users already have legacy MFA enabled — it handles the window before the 2026_04_01 API version is confirmed. Remove it once both the SDK and the minimum API version are upgraded: import { TokenScope, MFAAction } from '@dynamic-labs/sdk-api-core';
const isRequired = await client.stepUpAuth.isStepUpRequired({
scope: TokenScope.Walletexport,
});
if (isRequired) {
await client.stepUpAuth.verifyTotpMfa({
code: totpCode,
requestedScopes: [TokenScope.Walletexport],
});
} else {
// Transitional: 2026_04_01 API version not yet confirmed.
// Legacy TOTP verification for users with an existing MFA device.
const requires = await client.mfa.isRequiredForAction({
mfaAction: MFAAction.WalletWaasExport,
});
if (requires) {
await client.mfa.authenticateDevice({
code: totpCode,
createMfaToken: { singleUse: true },
});
}
}
import 'package:dynamic_sdk/dynamic_sdk.dart';
final isRequired = await DynamicSDK.instance.stepUpAuth
.isStepUpRequired('wallet:export');
if (isRequired) {
await DynamicSDK.instance.stepUpAuth.verifyTotpMfa(
code: totpCode,
requestedScopes: ['wallet:export'],
);
}
Headless Passkey
React
JavaScript
React Native
Flutter
Before — useAuthenticatePasskeyMFA with createMfaToken: import {
useAuthenticatePasskeyMFA,
useGetPasskeys,
useIsMfaRequiredForAction,
useRegisterPasskey,
} from "@dynamic-labs/sdk-react-core";
import { MFAAction } from '@dynamic-labs/sdk-api-core';
const authenticatePasskeyMFA = useAuthenticatePasskeyMFA();
const getPasskeys = useGetPasskeys();
const registerPasskey = useRegisterPasskey();
const isMfaRequiredForAction = useIsMfaRequiredForAction();
const requires = await isMfaRequiredForAction({
mfaAction: MFAAction.WalletWaasExport,
});
if (requires) {
const passkeys = await getPasskeys();
if (passkeys.length === 0) {
await registerPasskey();
}
await authenticatePasskeyMFA({
createMfaToken: { singleUse: false },
});
}
After — useStepUpAuthentication with verifyPasskeyMfa. The else branch is only needed if some of your users already have legacy MFA enabled — it handles the window before the 2026_04_01 API version is confirmed. Remove it once both the SDK and the minimum API version are upgraded: import {
useStepUpAuthentication,
useAuthenticatePasskeyMFA,
useGetPasskeys,
useRegisterPasskey,
useIsMfaRequiredForAction,
} from '@dynamic-labs/sdk-react-core';
import { TokenScope, MFAAction } from '@dynamic-labs/sdk-api-core';
const { isStepUpRequired, verifyPasskeyMfa } = useStepUpAuthentication();
const authenticatePasskeyMFA = useAuthenticatePasskeyMFA();
const getPasskeys = useGetPasskeys();
const registerPasskey = useRegisterPasskey();
const isMfaRequiredForAction = useIsMfaRequiredForAction();
if (await isStepUpRequired({ scope: TokenScope.Walletexport })) {
await verifyPasskeyMfa({
requestedScopes: [TokenScope.Walletexport],
});
} else {
// Transitional: 2026_04_01 API version not yet confirmed.
// Legacy passkey MFA for users with an existing registered passkey.
const requires = await isMfaRequiredForAction({
mfaAction: MFAAction.WalletWaasExport,
});
if (requires) {
const passkeys = await getPasskeys();
if (passkeys.length === 0) {
await registerPasskey();
}
await authenticatePasskeyMFA({
createMfaToken: { singleUse: false },
});
}
}
Before — authenticatePasskeyMFA with createMfaToken: import { isMfaRequiredForAction, authenticatePasskeyMFA, MFAAction } from '@dynamic-labs-sdk/client';
const required = await isMfaRequiredForAction({ mfaAction: MFAAction.WalletWaasExport });
if (required) {
await authenticatePasskeyMFA({
createMfaToken: { singleUse: true },
});
}
After — same function with requestedScopes. The else branch is only needed if some of your users already have legacy MFA enabled — it handles the window before the 2026_04_01 API version is confirmed. Remove it once both the SDK and the minimum API version are upgraded: import {
checkStepUpAuth,
authenticatePasskeyMFA,
isMfaRequiredForAction,
MFAAction,
} from '@dynamic-labs-sdk/client';
import { TokenScope } from '@dynamic-labs/sdk-api-core';
const { isRequired } = await checkStepUpAuth({ scope: TokenScope.Walletexport });
if (isRequired) {
await authenticatePasskeyMFA({
requestedScopes: [TokenScope.Walletexport],
});
} else {
// Transitional: 2026_04_01 API version not yet confirmed.
// Legacy passkey MFA for users with an existing registered passkey.
const required = await isMfaRequiredForAction({ mfaAction: MFAAction.WalletWaasExport });
if (required) {
await authenticatePasskeyMFA({
createMfaToken: { singleUse: true },
});
}
}
Before — client.passkeys.authenticateMFA with createMfaToken: import { MFAAction } from '@dynamic-labs/sdk-api-core';
const requires = await client.mfa.isRequiredForAction({
mfaAction: MFAAction.WalletWaasExport,
});
if (requires) {
const passkeys = await client.passkeys.get();
if (passkeys.length === 0) {
await client.passkeys.register();
}
await client.passkeys.authenticateMFA({
createMfaToken: { singleUse: false },
});
}
After — client.stepUpAuth.verifyPasskeyMfa with requestedScopes. The else branch is only needed if some of your users already have legacy MFA enabled — it handles the window before the 2026_04_01 API version is confirmed. Remove it once both the SDK and the minimum API version are upgraded: import { TokenScope, MFAAction } from '@dynamic-labs/sdk-api-core';
const isRequired = await client.stepUpAuth.isStepUpRequired({
scope: TokenScope.Walletexport,
});
if (isRequired) {
await client.stepUpAuth.verifyPasskeyMfa({
requestedScopes: [TokenScope.Walletexport],
});
} else {
// Transitional: 2026_04_01 API version not yet confirmed.
// Legacy passkey MFA for users with an existing registered passkey.
const requires = await client.mfa.isRequiredForAction({
mfaAction: MFAAction.WalletWaasExport,
});
if (requires) {
const passkeys = await client.passkeys.get();
if (passkeys.length === 0) {
await client.passkeys.register();
}
await client.passkeys.authenticateMFA({
createMfaToken: { singleUse: false },
});
}
}
import 'package:dynamic_sdk/dynamic_sdk.dart';
final isRequired = await DynamicSDK.instance.stepUpAuth
.isStepUpRequired('wallet:export');
if (isRequired) {
await DynamicSDK.instance.stepUpAuth.verifyPasskeyMfa(
requestedScopes: ['wallet:export'],
);
}
Migration checklist
React
JavaScript
React Native
Flutter
- Upgrade to React SDK
4.76.0 or later
- Replace
useMfa / useAuthenticatePasskeyMFA / usePromptMfaAuth with useStepUpAuthentication
- Replace
createMfaToken with requestedScopes using the appropriate TokenScope
- Replace
useIsMfaRequiredForAction with isStepUpRequired
- If you have existing legacy MFA users and you’re deploying the SDK update before accepting the new API version, keep the transitional
else branch shown in each After example so those users still get prompted
- Test the step-up flow end-to-end for each protected action
- Accept the minimum API version
2026_04_01 in your dashboard
- Remove the transitional
else branches
For the full step-up authentication reference (all verification methods, scopes, token lifecycle), see Step-up authentication.
- Upgrade to JavaScript SDK
0.24.1 or later
- Replace
isMfaRequiredForAction with checkStepUpAuth
- Replace
createMfaToken / createMfaTokenOptions with requestedScopes on authenticateTotpMfaDevice and authenticatePasskeyMFA
- If you have existing legacy MFA users and you’re deploying the SDK update before accepting the new API version, keep the transitional
else branch shown in each After example so those users still get prompted
- Test the step-up flow end-to-end for each protected action
- Accept the minimum API version
2026_04_01 in your dashboard
- Remove the transitional
else branches
For the full step-up authentication reference (all verification methods, scopes, token lifecycle), see Step-up authentication.
- Upgrade to React Native SDK
4.76.0 or later
- Replace
client.mfa.isRequiredForAction with client.stepUpAuth.isStepUpRequired
- Replace
client.mfa.authenticateDevice with client.stepUpAuth.verifyTotpMfa
- Replace
client.passkeys.authenticateMFA with client.stepUpAuth.verifyPasskeyMfa
- Replace
client.ui.mfa.show with client.stepUpAuth.promptStepUpAuth
- If you have existing legacy MFA users and you’re deploying the SDK update before accepting the new API version, keep the transitional
else branch shown in each After example so those users still get prompted
- Test the step-up flow end-to-end for each protected action
- Accept the minimum API version
2026_04_01 in your dashboard
- Remove the transitional
else branches
For the full step-up authentication reference (all verification methods, scopes, token lifecycle), see Step-up authentication.
- Upgrade to Flutter SDK
1.2.10 or later
- Implement step-up checks with
DynamicSDK.instance.stepUpAuth.isStepUpRequired
- Add verification flows using
promptStepUpAuth, verifyTotpMfa, or verifyPasskeyMfa
- Test the step-up flow end-to-end for each protected action
- Accept the minimum API version
2026_04_01 in your dashboard
For the full step-up authentication reference (all verification methods, scopes, token lifecycle), see Step-up authentication.