> ## Documentation Index
> Fetch the complete documentation index at: https://www.dynamic.xyz/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# useStepUpAuthentication

<Card title="Recommended: JavaScript SDK with React Hooks" icon="react" href="/javascript/reference/react-quickstart" color="#4779FE">
  For new React apps, we recommend the JavaScript SDK with React Hooks (`@dynamic-labs-sdk/react-hooks`) instead of the legacy React SDK documented here. The JS SDK comes with many benefits such as a much smaller bundle size and other optimizations. Use the [React quickstart (JavaScript SDK)](/javascript/reference/react-quickstart) to get started.
</Card>

### Summary

Hook for step-up authentication — requiring users to re-verify their identity before sensitive actions. Supports three usage patterns:

* **Automatic prompts** — `promptStepUpAuth` auto-selects MFA or re-auth and shows Dynamic's UI. `promptMfa` and `promptReauthenticate` offer explicit path control.
* **Headless methods** — `sendOtp`, `verifyOtp`, `verifyWallet`, `verifySocial`, `verifyPasskeyMfa`, `verifyTotpMfa`, `verifyRecoveryCode` for building custom UIs.

After successful verification with `requestedScopes`, the elevated access token is stored in SDK state and automatically applied to subsequent API calls that require the scope.

Must be used within a child of [DynamicContextProvider](/react/reference/providers/dynamiccontextprovider).

### Parameters

| Parameter      | Type                | Description                                                                                                                                                                                      |
| -------------- | ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `credentialId` | `string` (optional) | Target a specific credential for OTP verification at hook level. Defaults to the first sign-in enabled email or SMS credential. Can also be passed at call time via `sendOtp({ credentialId })`. |

### Return values

| Property               | Type                                                                 | Description                                                                                                                                                                                                                 |
| ---------------------- | -------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `isStepUpRequired`     | `({ scope: TokenScope }) => Promise<boolean>`                        | Returns `true` if step-up auth is enabled and no valid elevated token exists for the scope                                                                                                                                  |
| `checkStepUpAuth`      | `({ scope: TokenScope }) => Promise<StepUpCheckResponse>`            | **Recommended.** Server-authoritative check that returns `{ isRequired, credentials, defaultCredentialId }`. The `defaultCredentialId` is the recommended credential to authenticate with. Defaults to required on failure. |
| `promptStepUpAuth`     | `(params?) => Promise<string \| undefined>`                          | Auto-routes to MFA or re-auth, shows Dynamic's built-in UI                                                                                                                                                                  |
| `promptMfa`            | `(params?) => Promise<string \| undefined>`                          | Shows Dynamic's MFA UI (passkey or TOTP). Requires user to have registered MFA methods.                                                                                                                                     |
| `promptReauthenticate` | `(params?) => Promise<string \| undefined>`                          | Shows Dynamic's re-auth UI (OTP or wallet). Blocked when user has MFA enabled.                                                                                                                                              |
| `sendOtp`              | `(params?) => Promise<OTPVerification \| null>`                      | Sends OTP to the user's sign-in enabled credential. Accepts optional `{ credentialId }` to target a specific credential at call time. Returns `{ verificationType, credentialId }`.                                         |
| `verifyOtp`            | `(params: VerifyOtpParams) => Promise<void>`                         | Verify an OTP code with requested scopes                                                                                                                                                                                    |
| `verifyWallet`         | `(params: VerifyWalletParams) => Promise<void>`                      | Verify via external wallet signature. Accepts optional `walletId` to target a specific wallet. Defaults to the first connected wallet. Embedded wallets are not supported.                                                  |
| `verifySocial`         | `(params: VerifySocialParams) => Promise<void>`                      | Verify via a linked social account (OAuth popup)                                                                                                                                                                            |
| `verifyPasskeyMfa`     | `(params: VerifyPasskeyMfaParams) => Promise<string \| undefined>`   | Verify via passkey (WebAuthn). Triggers browser passkey prompt.                                                                                                                                                             |
| `verifyTotpMfa`        | `(params: VerifyTotpMfaParams) => Promise<string \| undefined>`      | Verify via TOTP authenticator app code                                                                                                                                                                                      |
| `verifyRecoveryCode`   | `(params: VerifyRecoveryCodeParams) => Promise<string \| undefined>` | Verify via backup recovery code                                                                                                                                                                                             |
| `state`                | `{ isLoading: boolean, error: string \| null }`                      | Loading and error state for headless methods                                                                                                                                                                                |
| `resetState`           | `() => void`                                                         | Reset loading and error state. Call before retrying.                                                                                                                                                                        |

### Prompt parameter types

```typescript theme={"system"}
type PromptStepUpAuthParams = {
  requestedScopes?: TokenScope[];
};

// promptMfa and promptReauthenticate accept the same shape
```

### Headless parameter types

```typescript theme={"system"}
type VerifyOtpParams = {
  verificationToken: string;
  requestedScopes?: TokenScope[];
};

type SendOtpParams = {
  credentialId?: string;
};

type VerifyWalletParams = {
  walletId?: string;
  requestedScopes?: TokenScope[];
};

type VerifySocialParams = {
  provider: ProviderEnum;
  requestedScopes?: TokenScope[];
};

type VerifyPasskeyMfaParams = {
  requestedScopes?: TokenScope[];
};

type VerifyTotpMfaParams = {
  code: string;
  deviceId?: string;
  requestedScopes?: TokenScope[];
};

type VerifyRecoveryCodeParams = {
  code: string;
  requestedScopes?: TokenScope[];
};
```

### Usage: automatic prompt

```tsx theme={"system"}
import { useStepUpAuthentication } from '@dynamic-labs/sdk-react-core';
import { TokenScope } from '@dynamic-labs/sdk-api-core';

const ExportButton = () => {
  const { isStepUpRequired, promptStepUpAuth } = useStepUpAuthentication();

  const handleExport = async () => {
    if (await isStepUpRequired({ scope: TokenScope.Walletexport })) {
      try {
        await promptStepUpAuth({ requestedScopes: [TokenScope.Walletexport] });
      } catch {
        return; // User cancelled
      }
    }
    // Token stored — proceed with the operation
    await exportWallet();
  };

  return <button onClick={handleExport}>Export Wallet</button>;
};
```

### Usage: checkStepUpAuth (recommended)

`checkStepUpAuth` is the recommended way to determine whether step-up is required. It performs a server-authoritative check and returns the available credentials, so you can route the user to the right verification method without extra API calls.

```tsx theme={"system"}
import { useStepUpAuthentication } from '@dynamic-labs/sdk-react-core';
import { TokenScope } from '@dynamic-labs/sdk-api-core';

const SecureAction = () => {
  const { checkStepUpAuth, promptStepUpAuth } = useStepUpAuthentication();

  const handleAction = async () => {
    const { isRequired, credentials, defaultCredentialId } =
      await checkStepUpAuth({ scope: TokenScope.Walletexport });

    if (isRequired) {
      // credentials contains the available verification methods
      // Each credential has: { id, format, type?, alias? }
      //
      // defaultCredentialId is the recommended credential to authenticate with:
      // - For MFA users: the configured default device or most recently added
      // - For re-auth users: the credential used to sign in
      const defaultCred = credentials.find((c) => c.id === defaultCredentialId);

      try {
        await promptStepUpAuth({
          requestedScopes: [TokenScope.Walletexport],
        });
      } catch {
        return; // User cancelled
      }
    }

    await performSecureAction();
  };

  return <button onClick={handleAction}>Secure Action</button>;
};
```

### Usage: headless OTP

```tsx theme={"system"}
import { useState } from 'react';
import { useStepUpAuthentication } from '@dynamic-labs/sdk-react-core';
import { TokenScope } from '@dynamic-labs/sdk-api-core';

const StepUpOtp = ({ onComplete }: { onComplete: () => void }) => {
  const { sendOtp, verifyOtp, state, resetState } = useStepUpAuthentication();
  const [code, setCode] = useState('');

  return (
    <form
      onSubmit={async (e) => {
        e.preventDefault();
        resetState();
        await verifyOtp({
          verificationToken: code,
          requestedScopes: [TokenScope.Credentiallink],
        });
        onComplete();
      }}
    >
      <button type="button" onClick={() => sendOtp()}>Send Code</button>
      <input value={code} onChange={(e) => setCode(e.target.value)} />
      <button type="submit" disabled={state.isLoading}>
        {state.isLoading ? 'Verifying...' : 'Verify'}
      </button>
      {state.error && <p>{state.error}</p>}
    </form>
  );
};
```

### Related

* [Step-Up Authentication guide](/react/authentication-methods/step-up-auth/overview)
* [Step-Up Authentication concepts](/overview/authentication/step-up-auth)
* [usePromptMfaAuth](/react/reference/hooks/login-user-management/usepromptmfa)
