> ## 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.

# Step-up authentication

> Require users to re-verify their identity before sensitive actions using elevated access tokens in the React Native SDK.

The React Native SDK provides step-up authentication through the `client.stepUpAuth` module. You can check requirements, prompt built-in UI flows, or call individual verification methods for a fully custom experience.

After verification, the elevated access token is automatically stored and applied to subsequent API calls. You never need to manually handle the token.

For concepts, scopes, and token lifecycle, see [Step-up authentication overview](/overview/authentication/step-up-auth).

## Prerequisites

* Dynamic React Native SDK initialized with your environment ID
* At least one verification method enabled in your [dashboard security settings](https://app.dynamic.xyz/dashboard/security)
* Step-up authentication enabled for your environment

## Quick start

The pattern is: **check → verify → proceed**.

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

const exportPrivateKey = async () => {
  // 1. Check if step-up is required
  const isRequired = await client.stepUpAuth.isStepUpRequired({
    scope: TokenScope.Walletexport,
  });

  if (isRequired) {
    // 2. Prompt the user — auto-routes to MFA or re-auth
    await client.stepUpAuth.promptStepUpAuth({
      requestedScopes: [TokenScope.Walletexport],
    });
  }

  // 3. Proceed — token is attached automatically
  await performExport();
};
```

## Checking step-up requirements

Use `isStepUpRequired` to check whether the user needs to re-verify for a given scope:

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

const isRequired = await client.stepUpAuth.isStepUpRequired({
  scope: TokenScope.Walletexport,
});

if (isRequired) {
  // Trigger verification
}
```

## Prompt methods (built-in UI)

These methods show Dynamic's built-in UI for step-up authentication. The SDK handles method selection and user interaction.

### promptStepUpAuth

Automatically chooses between MFA and re-authentication based on the user's configuration. This is the recommended approach.

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

const token = await client.stepUpAuth.promptStepUpAuth({
  requestedScopes: [TokenScope.Walletexport],
});
```

### promptMfa

Explicitly prompts the user with MFA methods (passkey or TOTP). Use this when you know the user has MFA configured.

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

const token = await client.stepUpAuth.promptMfa({
  requestedScopes: [TokenScope.Walletexport],
});
```

### promptReauthenticate

Explicitly prompts the user to re-authenticate using a non-MFA method (email OTP, SMS OTP, or external wallet signature).

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

const token = await client.stepUpAuth.promptReauthenticate({
  requestedScopes: [TokenScope.Walletexport],
});
```

## Full example

Here's a complete example screen that checks step-up requirements and prompts the user:

```typescript theme={"system"}
import React, { useState } from 'react';
import { Alert, Button, ScrollView, Text, View } from 'react-native';
import { TokenScope } from '@dynamic-labs/sdk-api-core';
import { useDynamicClient } from '../store/client';

export default function StepUpAuthScreen() {
  const client = useDynamicClient();
  const [isLoading, setIsLoading] = useState(false);
  const [result, setResult] = useState<string | null>(null);

  const handleCheckRequired = async () => {
    try {
      const required = await client.stepUpAuth.isStepUpRequired({
        scope: TokenScope.Walletexport,
      });
      Alert.alert(
        'Result',
        required
          ? 'Step-up authentication IS required'
          : 'Step-up authentication is NOT required',
      );
    } catch (error) {
      Alert.alert('Error', `Failed to check: ${error}`);
    }
  };

  const handleExportWallet = async () => {
    setIsLoading(true);
    setResult(null);
    try {
      const required = await client.stepUpAuth.isStepUpRequired({
        scope: TokenScope.Walletexport,
      });

      if (required) {
        await client.stepUpAuth.promptStepUpAuth({
          requestedScopes: [TokenScope.Walletexport],
        });
      }

      // Token is now stored — proceed with export
      // await performExport();
      setResult('Export completed');
    } catch (error) {
      Alert.alert('Error', `Step-up auth failed: ${error}`);
    } finally {
      setIsLoading(false);
    }
  };

  const handlePromptMfa = async () => {
    setIsLoading(true);
    try {
      const token = await client.stepUpAuth.promptMfa({
        requestedScopes: [TokenScope.Walletexport],
      });
      setResult(token ?? 'Completed (no token returned)');
    } catch (error) {
      Alert.alert('Error', `MFA prompt failed: ${error}`);
    } finally {
      setIsLoading(false);
    }
  };

  const handlePromptReauth = async () => {
    setIsLoading(true);
    try {
      const token = await client.stepUpAuth.promptReauthenticate({
        requestedScopes: [TokenScope.Walletexport],
      });
      setResult(token ?? 'Completed (no token returned)');
    } catch (error) {
      Alert.alert('Error', `Reauthentication failed: ${error}`);
    } finally {
      setIsLoading(false);
    }
  };

  return (
    <ScrollView>
      <View>
        <Button
          title="Is Step-Up Required?"
          onPress={handleCheckRequired}
        />
        <Button
          title={isLoading ? 'Authenticating...' : 'Export Wallet'}
          onPress={handleExportWallet}
          disabled={isLoading}
        />
        <Button
          title="Prompt MFA"
          onPress={handlePromptMfa}
          disabled={isLoading}
        />
        <Button
          title="Prompt Reauthenticate"
          onPress={handlePromptReauth}
          disabled={isLoading}
        />
        {result && <Text>{result}</Text>}
      </View>
    </ScrollView>
  );
}
```

## Error handling

Wrap verification calls in try-catch blocks to handle user cancellations and verification failures:

```typescript theme={"system"}
try {
  await client.stepUpAuth.promptStepUpAuth({
    requestedScopes: [TokenScope.Walletexport],
  });
} catch (error) {
  // User cancelled or verification failed
  console.error('Step-up auth failed:', error);
}
```

## API reference

### client.stepUpAuth

| Method                                      | Description                              |
| ------------------------------------------- | ---------------------------------------- |
| `isStepUpRequired({ scope })`               | Check if step-up is required for a scope |
| `promptStepUpAuth({ requestedScopes })`     | Auto-route to MFA or re-auth UI          |
| `promptMfa({ requestedScopes })`            | Show MFA verification UI                 |
| `promptReauthenticate({ requestedScopes })` | Show re-authentication UI                |
| `resetState()`                              | Reset step-up auth state                 |

### Parameters

All prompt methods accept an optional object with:

| Parameter         | Type           | Description                                                                                                          |
| ----------------- | -------------- | -------------------------------------------------------------------------------------------------------------------- |
| `requestedScopes` | `TokenScope[]` | Scopes to request for the elevated access token                                                                      |
| `createMfaToken`  | `boolean`      | Deprecated. Use `requestedScopes` instead. See [migration guide](/overview/migrations/api/2026_04_01-mfa-migration). |

## Available scopes

See the [complete scopes reference](/overview/authentication/step-up-auth#scopes) for all supported values.

## Related

* [Step-up authentication overview](/overview/authentication/step-up-auth) — Concepts, scopes, token lifecycle
* [MFA overview](/react-native/authentication-methods/mfa/overview) — React Native MFA guide
* [Action-based MFA](/react-native/authentication-methods/mfa/action-based) — Action-based MFA in React Native
