# Fraud Level Analysis

div
div
Client SDK
div
Mobile approve
div
SSO
div
Sub-journey
> Branches the journey according to risk recommendation obtained from Fraud Prevention


## Description

This step is used to obtain risk recommendations so you can detect and respond to real-time risk. For example, this allows you to request additional verification when bots are detected during account opening or to step up authentication when a user is trying to login from a suspicious device or location.

Use this step before the user performs a sensitive action in order to detect risk and help you decide how to respond. The journey automatically evaluates the risk and proceeds to the appropriate branch based on the recommendation (either trust, allow, challenge, or deny). If defined, an output variable will store the risk recommendation result. In addition to a recommendation itself (allow, trust, deny, or challenge), the result includes more details such as risk score, reasons, and device details. This data can be used in subsequent journey steps in the expression fields (e.g., `risk_recommendation.recommendation`) or as a part of an interpolated string (e.g., `You're using ${risk_recommendation.context.browser_name}`).

Risk recommendations are provided by Mosaic's [Fraud Prevention](/guides/risk/overview) based on telemetry streamed by the client. It includes device, network, and other context data used to continuously assess risk. For Web, Fraud Prevention functionality is bundled with Journeys in the same [SDK](/sdk-ref/platform/introduction). For mobile apps, use a dedicated SDK: [Fraud Prevention SDK (iOS)](https://transmitsecurity.github.io/accountprotection-ios-sdk-docs/documentation/accountprotection/) or [Fraud Prevention SDK (Android)](https://transmitsecurity.github.io/accountprotection-android-sdk/).

Note
* Make sure Fraud Prevention is configured to work in the same region as other Mosaic services.
* For details on how to set up and initialize the Fraud Prevention SDK for mobile apps, see Steps 2 & 3 of [Android quickstart](/guides/risk/quick_start_android) or [iOS quickstart](/guides/risk/quick_start_ios). If the Fraud Prevention SDK is not initialized, the step fails with an `sdk_not_initialized` error.


## Configuration

div
| **Field** | **Description** |
|  --- | --- |
| **User auth state** | Indicates if the user has authenticated in this journey. Select **Authenticated user** (default) if the user context is provided implicitly by the journey. Select **Unauthenticated user** if the user hasn't been authenticated yet. |
| **Claimed User ID** | Yields the user identifier of the not yet authenticated user, used to enhance risk and trust assessments. Only relevant when **User auth state** is set to **Unauthenticated user**. |
| **Claimed User ID Type** | Specifies the type of value provided in the Claimed User ID field. This is especially important when the Claimed User ID contains a hashed value, as it clarifies the original data type used. Only relevant when **User auth state** is set to **Unauthenticated user**. |
| **Action Type** | Specifies the action being evaluated for risk, such as `login`, `transaction`, or `password_reset`. A full list is available [here](/guides/risk/recommendations/#action-types). |
| **Transaction Data** | Transaction-related data to include with the risk assessment request. |
| **Custom Attributes** | [Custom attributes](/guides/risk/action-attributes) to include with the risk assessment request. |
| **Output Variable** | Name of the variable used to store the result data from the completed step, which can be used in subsequent journey steps. Default is **risk_recommendation**. The object has the structure that's described [here](/openapi/risk/recommendations.openapi/other/getriskrecommendation#other/getriskrecommendation/response&c=200). In addition to a recommendation itself (allow, trust, deny, or challenge), it includes more details such as risk score, reasons, and device details. |
| **Custom Branches** | Custom branches that can be configured for the step. |
| **Error Behavior** | Determines the behavior in case an unexpected error occurs during the process. You can choose to either abort the journey (default) or handle errors using a dedicated error branch. |


## Example

In our example, the user attempts to login with their credentials. This step performs a fraud level analysis for the login event and defines how to proceed with the journey. For example:

- **Trust**/**Allow**: Proceed to a simple login and if the login is successful, and the journey proceeds to the Complete Journey step.
- **Challenge**: The user must complete an additional authentication step (e.g., an Email OTP Authentication).
- **Deny**: The login attempt is rejected, and the journey moves to the Reject Access step.


figure
a
img
figcaption
Click to open the image in a dedicated tab.
br
When executed, this step sends a callback to the client with the IDO service response object. It will have the `journeyStepId` set to `drsTriggerAction` and the `data` will include the `action_type` set to `login`. The client uses the data received from the Orchestration SDK as an input for Fraud Prevention SDK and triggers an action with the Fraud Prevention SDK. Having received the action token from the Fraud Prevention SDK, the client submits it to the journey using the Orchestration SDK call in order for the journey to fetch a recommendation and proceed accordingly.

Once the user is fully-authenticated, it is recommended to report the action result and set the user for all subsequent events in the device session. This is done by adding "Client Actions: Report action result API" step after the "Fraud Level Analysis" and submitting the `action_token` and `user_id`.

JavaScript

```js
async function handleRiskRecommendations(idoResponse) {
  const correlationId = idoResponse.data.correlation_id;
  const claimedUserId = idoResponse.data.claimed_user_id;
  const claimedUserIdType = idoResponse.data.claimed_user_id_type;
  const actionType = idoResponse.data.action_type;

  // Triggers an action event using the SDK
  // If SDK was loaded via script tag, invoke functions inside 'window.tsPlatform'
  const { actionToken } = await drs.triggerActionEvent(actionType, {
    correlationId,
    claimedUserId,
    claimedUserIdType,
  });

  const data = { action_token: actionToken };

  // Submits an action token to the journey using the Orchestration SDK
  // If SDK was loaded via script tag, invoke functions inside 'window.tsPlatform'
  await ido.submitClientResponse(ClientResponseOptionType.ClientInput, data);
}
```

Swift

```swift
do {
    // Initializes the Fraud Prevention SDK
    try TSAccountProtection.initializeSDK { result in
        switch result {
        case .success:
            guard let actionType = idoResponse.data["action_type"] as? String else { return }
            let correlationId = idoResponse.data["correlation_id"] as? String
            let claimedUserId = idoResponse.data["claimed_user_id"] as? String

            // Triggers an action event using the Fraud Prevention SDK
            TSAccountProtection.triggerAction(actionType) { result in
                switch result {
                case .success(let response):
                    debugPrint("[DEBUG] Fraud Prevention access token: \(response.actionToken)")

                    // Submits an action token to the journey using the Orchestration SDK
                    do {
                        try TSIdo.submitClientResponse(clientResponseOptionId: .clientInput,
                                                       data: ["action_token": response.actionToken])
                    } catch {
                        debugPrint("[DEBUG] Failed to submit action token: \(error)")
                    }
                case .failure(let error):
                    debugPrint("[DEBUG] Trigger action error: \(error)")
                    do {
                        try TSIdo.submitClientResponse(clientResponseOptionId: .fail)
                    } catch {
                        debugPrint("[DEBUG] Failed to submit failure response: \(error)")
                    }
                }
            }
        case .failure(let error):
            debugPrint("[DEBUG] Initialize Fraud Prevention SDK error: \(error)")
        }
    }
} catch {
    debugPrint("[DEBUG] SDK Initialization error: \(error)")
}
```

Kotlin

```kotlin
data class DrsActionToken(val action_token: String)
...
private fun triggerActionAndSubmit(serviceResponse: TSIdoServiceResponse) {
    val actionType = (serviceResponse.data as JSONObject).optString(“action_type”)
    if (!action.isNullOrEmpty()) {
           // Triggers an action event using the Fraud Prevention SDK
           TSAccountProtection.triggerAction(actionType, object :
               ITransmitSecurityTriggerActionEventCallback {
               override fun onResponse(transmitSecurityTriggerActionResponse: TransmitSecurityTriggerActionResponse) {
                   val token= transmitSecurityTriggerActionResponse.token();
                   // Submits an action token to the journey using the Orchestration SDK
                   TSIdo.submitClientResponse(TSIdoClientResponseOptionType.ClientInput.type, DrsActionToken(token), callback)
               }
               override fun onFailed(error: TransmitSecurityAccountProtectionError) {
                   //TODO: Handle error
               }
           })
    }
}
```

The risk recommendation is stored in the output variable (default: `risk_recommendation`) and can be used in subsequent steps to determine security policies dynamically.