Skip to main content

Documentation Index

Fetch the complete documentation index at: https://otpless.com/docs/llms.txt

Use this file to discover all available pages before exploring further.

The SDK requires a minimum API level of 26 (Android 8.0 Oreo). Calls on devices below API 26 return silently without an error.

Prerequisites

  • Android API level 26 or higher
  • App ID, Client ID, and Client Secret from the OTPless dashboard

Installation

The SDK is distributed on Maven Central. In your app-level build.gradle, add the dependency:
build.gradle
dependencies {
    implementation 'io.github.otpless-tech:otpless-intelligence-sdk:1.0.6.5'
}
Check Maven Central for the latest version. Sync your project with Gradle files after adding the dependency.

Add permissions

In your AndroidManifest.xml, add the required and optional permissions:
AndroidManifest.xml
<uses-permission android:name="android.permission.INTERNET" />

<!-- Optional: improves accuracy -->
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

<!-- Optional: used to calculate SIM affinity -->
<uses-permission android:name="android.permission.READ_PHONE_STATE" />

Initialize the SDK

Call initialize in the onCreate() method of your Application class. Pass your App ID, Client ID, and Client Secret as a map.
Application.kt
import com.otpless.impl.veritaserum.OtplessDeviceIntelligence

override fun onCreate() {
    super.onCreate()

    val creds = mapOf(
        "appId" to "<OTPLESS_APP_ID>",
        "clientId" to "<OTPLESS_CLIENT_ID>",
        "clientSecret" to "<OTPLESS_CLIENT_SECRET>"
    )

    OtplessDeviceIntelligence.initialize(applicationContext, creds)
}

Integrate with OtplessAuth SDK

If you are already using the OtplessAuth SDK, you can enable device fingerprinting directly on OtplessRequest without calling getIntelligence() manually. Set the deviceFingerprintMode property before calling OtplessSDK.start().
import com.otpless.v2.android.sdk.dto.DeviceFingerprintMode
import com.otpless.v2.android.sdk.dto.OtplessRequest

lifecycleScope.launch(Dispatchers.IO) {
    val otplessRequest = OtplessRequest()
    otplessRequest.setPhoneNumber("PHONE_NUMBER", "COUNTRY_CODE")
    otplessRequest.deviceFingerprintMode = DeviceFingerprintMode.SYNC
    OtplessSDK.start(request = otplessRequest, callback = ::onOtplessResponse)
}

DeviceFingerprintMode values

ValueBehaviour
NONEDevice fingerprinting is disabled. Default value.
ASYNCFingerprint is collected in parallel with the auth request. Does not add latency.
SYNCFingerprint is collected before the auth request is sent. Ensures fingerprint data is always included.

Fetch device intelligence

getIntelligence() is a suspend function. Call it from a coroutine scope and handle the result. It optionally accepts an UpdateInfo object to attach user-level and event-level context.
import com.otpless.impl.veritaserum.OtplessDeviceIntelligence
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch

CoroutineScope(Dispatchers.IO).launch {
    val result = OtplessDeviceIntelligence.getIntelligence()
    result.onSuccess { response ->
        val intelligence = response.intelligenceResponse
        // Act on the result
    }
    result.onFailure { error ->
        // Handle the error
    }
}

Pass additional context (optional)

Pass an UpdateInfo object directly to getIntelligence() to attach user-level and event-level context. This enriches the result and enables more accurate risk scoring.
import com.otpless.impl.veritaserum.OtplessDeviceIntelligence
import com.otpless.impl.veritaserum.core.UpdateInfo
import com.otpless.impl.veritaserum.core.PhoneInputType
import com.otpless.impl.veritaserum.core.OtpInputType
import com.otpless.impl.veritaserum.core.UserEventType
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch

CoroutineScope(Dispatchers.IO).launch {
    val updateInfo = UpdateInfo(
        userId = "user-123",
        phoneNumber = "1234567890",
        phoneInputType = PhoneInputType.MANUAL,
        otpInputType = OtpInputType.AUTO_FILLED,
        userEventType = UserEventType.TRANSACTION,
        merchantId = "merchant-id",
        additionalInput = mapOf(
            "TRANSACTION_ID" to "txn-abc-123",
            "METHOD" to "UPI",
            "AMOUNT" to "500",
            "CURRENCY" to "INR"
        )
    )

    val result = OtplessDeviceIntelligence.getIntelligence(updateInfo = updateInfo)
    result.onSuccess { response ->
        val intelligence = response.intelligenceResponse
        // Act on the result
    }
    result.onFailure { error ->
        // Handle the error
    }
}

UpdateInfo fields

FieldTypeDescription
userIdString?Your internal user identifier. Used to correlate the result with a user account.
phoneNumberString?Customer phone number.
phoneInputTypePhoneInputType?How the phone number was entered: MANUAL, COPY_PASTED, GOOGLE_HINT.
otpInputTypeOtpInputType?How the OTP was entered: MANUAL, COPY_PASTED, AUTO_FILLED.
userEventTypeUserEventType?The action being performed: LOGIN, SIGNUP, TRANSACTION, OTHERS.
merchantIdString?Merchant identifier, if applicable.
additionalInputMap<String, String>?Arbitrary key-value pairs for custom context.

Sample response

Success

{
    "requestId": "403ad427-5018-47b9-b6e8-790e17a78201",
    "sessionId": "233sd769-9367-39h9-b9e8-650eb6e87820",
    "newDevice": false,
    "deviceId": "43fccb70-d64a-4c32-a251-f07c082d7034",
    "vpn": false,
    "proxy": false,
    "emulator": true,
    "cloned": false,
    "geoSpoofed": false,
    "rooted": false,
    "ip": "106.219.161.71",
    "remoteAppProviders": false,
    "remoteAppProvidersCount": 3,
    "mirroredScreen": false,
    "hooking": true,
    "factoryReset": true,
    "appTampering": true,
    "sessionRiskScore": 99.50516,
    "deviceRiskScore": 99.50516,
    "clientUserIds": ["difansd23r32", "2390ksdfaksd"],
    "genuineInstall": false,
    "developerOptionsEnabled": true,
    "usbDebugging": true,
    "wirelessDebugging": false,
    "unsecuredWifi": false,
    "harmfulAppDetected": false,
    "blacklistedDevice": false,
    "keyloggerDetected": false,
    "factoryResetTime": 1743419662000,
    "gpsLocation": {
        "address": "F2620, Block F, Sushant Lok III, Sector 57, Gurugram, Haryana 122011, India",
        "adminArea": "Haryana",
        "countryCode": "IN",
        "countryName": "India",
        "featureName": "F2620",
        "latitude": "28.420385999999997",
        "locality": "Gurugram",
        "longitude": "77.088926",
        "postalCode": "122011",
        "subAdminArea": "Gurgaon Division",
        "subLocality": "Sector 57"
    },
    "ipDetails": {
        "country": "IN",
        "fraudScore": 27.0,
        "city": "New Delhi",
        "isp": null,
        "latitude": 28.60000038,
        "region": "National Capital Territory of Delhi",
        "asn": "",
        "longitude": 77.19999695
    },
    "simInfo": {
        "simIds": [
            { "id": 1, "simSlotIndex": 0, "carrierName": "JIO 4G | Jio", "eSim": false },
            { "id": 3, "simSlotIndex": 1, "carrierName": "airtel", "eSim": true }
        ],
        "totalSimUsed": 10
    },
    "deviceMeta": {
        "cpuType": "Qualcomm Technologies, Inc SM7325",
        "product": "I2126i",
        "androidVersion": "14",
        "storageAvailable": "29340553216",
        "storageTotal": "111156146176",
        "model": "I2126",
        "screenResolution": "1080x2316",
        "brand": "iQOO",
        "totalRAM": "7679795200"
    },
    "appAnalytics": {
        "affinity": {
            "entertainment": 0.5,
            "gaming": 0.6,
            "productivity": 0.8,
            "food_and_drink": 0.4
        }
    },
    "ruleAction": {
        "action": "WARN",
        "name": "VPN enabled",
        "description": "A VPN connection was detected on this device.",
        "message": "For security reasons, please disable your VPN and try again."
    },
    "appliedRules": {
        "rules": {
            "55 : VPN enabled": 0,
            "99 : App is tampered": 50
        },
        "totalScore": 50.0
    },
    "additionalData": {}
}

Error

{
  "requestId": "7e12d131-2d90-4529-a5c7-35f457d86ae6",
  "errorMessage": "OTPless server error"
}

Response fields

FieldTypeDescriptionDefault
requestIdstringUnique identifier for the request.""
sessionIdstringUnique identifier for the current app session.""
newDevicebooleanWhether this is the first time this device has been seen.false
deviceIdstringStable identifier for the device. Persists across reinstalls and factory resets.""
sessionRiskScorefloatRisk score (0–100) based on the current session state.0.0
deviceRiskScorefloatRisk score that also factors in the device’s historical state across past sessions.0.0
vpnbooleanA VPN is active on the device.false
proxybooleanThe device is behind a proxy server.false
emulatorbooleanThe app is running on an emulator rather than physical hardware.false
rootedbooleanThe device has been modified for root access.false
clonedbooleanThe user is running a cloned instance of the app.false
geoSpoofedbooleanThe device’s location is being faked.false
remoteAppProvidersbooleanA remote access application (e.g. AnyDesk, TeamViewer) is installed.false
remoteAppProvidersCountnumberNumber of remote access applications detected.0
mirroredScreenbooleanThe device’s screen is being mirrored.false
hookingbooleanThe app has been altered by a hooking framework.false
factoryResetbooleanA suspicious factory reset has been performed.false
factoryResetTimelongTimestamp of the last factory reset. -1 if not detected.-1
appTamperingbooleanThe app binary has been modified in an unauthorized way.false
genuineInstallbooleanThe app was installed from an official, trusted source.false
developerOptionsEnabledbooleanDeveloper Options are enabled on the device.false
usbDebuggingbooleanUSB debugging is enabled.false
wirelessDebuggingbooleanWireless (ADB over Wi-Fi) debugging is enabled.false
unsecuredWifibooleanThe device is connected to an unsecured Wi-Fi network.false
harmfulAppDetectedbooleanPotentially harmful applications are installed on the device.false
blacklistedDevicebooleanThe device is on the OTPless internal blocklist.false
keyloggerDetectedbooleanKeylogging behavior has been detected on the device.false
ipstringCurrent IP address of the device.""
ipDetailsobjectIP metadata including country, city, ISP, coordinates, and fraud score.{}
gpsLocationobjectGPS location details including latitude, longitude, and address.{}
simInfoobjectSIM card details: current SIMs per slot and total SIMs used over the device’s lifetime.{}
deviceMetaobjectDevice hardware metadata: brand, model, OS version, screen resolution, storage, RAM, CPU.{}
appAnalyticsobjectApp affinity scores (0–1) per category based on installed apps.{}
clientUserIdsarrayAll user IDs associated with this device across its history.[]
ruleActionobjectThe triggered rule and recommended action (ALLOW, WARN, BLOCK) with a user-facing message.{}
appliedRulesobjectFull list of evaluated rules, their scores, and the total rule score.{}
additionalDataobjectReserved for custom fields returned based on your account configuration.{}