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

# Android SDK

> Integrate the OTPless Headless SDK on Android for the SNA-only flow — add the dependency, configure SNA, initialize, start with a requestId, and handle callbacks.

This page covers the **SNA-only** integration of the OTPless Headless SDK on Android. The SDK accepts the `requestId` generated by the [Create API](/sna/create-api), performs the silent network handshake, and reports progress through callbacks. Your backend confirms the final result via the [Status Check API](/sna/status-check-api).

## Requirements

| Requirement  | Version |
| ------------ | ------- |
| `compileSdk` | 35      |
| Minimum SDK  | 21      |
| Kotlin       | 1.9.0+  |
| Gradle       | 8.3.1+  |

## Step 1: Add SDK dependency

Add the OTPLESS SDK to your app's `build.gradle`:

```groovy theme={null}
implementation ("io.github.otpless-tech:otpless-headless-lite:latest_version")
```

<Note>
  Check the latest version of the [SDK here](https://central.sonatype.com/artifact/io.github.otpless-tech/otpless-headless-lite). Make sure to **synchronize** your Gradle project to fetch the dependency.
</Note>

## Step 2: Smart Authentication (SNA) setup

<Warning>
  Make sure **Silent Network Authentication** is enabled on the [OTPLESS dashboard](https://otpless.com/dashboard/customer/channels). For an SNA-only configuration, SNA must be the only channel enabled.
</Warning>

Once the SDK is integrated, add the following line in your app's `AndroidManifest.xml` inside the `<application>` tag:

```xml AndroidManifest.xml theme={null}
android:networkSecurityConfig="@xml/otpless_network_security_config"
```

## Step 3: Initialize the SDK

Import `OtplessSDK` in your `LoginActivity.kt`:

```kotlin theme={null}
import com.otpless.v2.android.sdk.main.OtplessSDK
```

Initialize the SDK depending on your app architecture:

* **`LoginActivity`** — initialize in `onCreate()`
* **`LoginFragment`** — initialize in `onViewCreated()`

<CodeGroup>
  ```kotlin Kotlin theme={null}
  lifecycleScope.launch(Dispatchers.IO) {
      OtplessSDK.initialize(
          APP_ID,
          this@LoginActivity,
          callback = this@LoginActivity::onOtplessResponse
      )
  }
  ```

  ```java Java theme={null}
  OtplessSDK.initialize(APP_ID, this, this::onOtplessResponse);
  ```
</CodeGroup>

<Note>
  Replace `APP_ID` with your actual App ID from the [OTPLESS dashboard](https://dashboard.otpless.com/login).
</Note>

## Step 4: Start SNA with the requestId

Pass the `requestId` returned by the [Create API](/sna/create-api) to `start()`:

```kotlin theme={null}
val otplessRequest = OtplessRequest()
otplessRequest.requestId = "REQUEST_ID_FROM_API"

lifecycleScope.launch {
    OtplessSDK.start(request = otplessRequest, callback = ::onOtplessResponse)
}
```

<Note>
  Start polling the [Status Check API](/sna/status-check-api) from your backend immediately after calling `start()`. The SDK callback and the server status run in parallel.
</Note>

## Step 5: Handle callbacks

```kotlin theme={null}
private fun onOtplessResponse(response: OtplessResponse) {
    OtplessSDK.commit(response)
    when (response.responseType) {
        ResponseTypes.SDK_READY -> {
            // SDK initialized successfully — enable your continue button
            // or proceed with user authentication.
        }
        ResponseTypes.FAILED -> {
            // SDK initialization failed
            if (response.statusCode == 5003) {
                // Please try to initialize the SDK again.
            }
        }
        ResponseTypes.INITIATE -> {
            // Authentication has been initiated
            if (response.statusCode != 200) {
                handleInitiateError(response)
            } else {
                val authType = response.response
                    ?.optString("authType")
                if (authType == "SILENT_AUTH") {
                    // SNA is being attempted — show a loading state.
                }
            }
        }
        ResponseTypes.ONETAP -> {
            // Final success response
        }
        ResponseTypes.AUTH_TERMINATED -> {
            // SNA-only configuration: auth could not complete.
            // Emitted when pre-checks fail, or when SNA was attempted
            // and then failed/expired. Treat as a terminal failure and
            // rely on the Status Check API for the exact error.
        }
    }
}
```

## Callback reference

The SDK works in two steps — initialization and `start()` — and each step has its own set of callbacks.

#### Step 1: Initialization callbacks

Emitted when you initialize the SDK (Step 3).

| Callback    | Meaning                                            |
| ----------- | -------------------------------------------------- |
| `SDK_READY` | SDK initialization completed.                      |
| `FAILED`    | SDK failed to initialize (e.g. `statusCode 5003`). |

#### Step 2: Start callbacks

Emitted after you invoke `start()` (Step 4).

| Callback          | State                  | Meaning                                                                                                           |
| ----------------- | ---------------------- | ----------------------------------------------------------------------------------------------------------------- |
| `INITIATE`        | Non-terminal           | SNA is being attempted after pre-checks pass. `authType` is `SILENT_AUTH`.                                        |
| `ONETAP`          | **Success — terminal** | SNA completed successfully (Silent Mobile Verification). Returns `token` / `idToken`.                             |
| `AUTH_TERMINATED` | **Failed — terminal**  | Emitted in two cases: (1) pre-checks failed → terminated directly; (2) SNA was initiated and then failed/expired. |

<Warning>
  In the SNA-only configuration `AUTH_TERMINATED` is a terminal failure with no fallback. Always treat the [Status Check API](/sna/status-check-api) result as authoritative. See [Handling the AUTH\_TERMINATED callback](/knowledge-base/sna/auth-terminated-callback).
</Warning>

<Note>
  For the `errorCode` / `statusCode` values surfaced in SDK callbacks, see [SDK Error Codes](/sna/sdk-error-codes).
</Note>

## Next step

<Card title="Status Check API" icon="circle-check" href="/sna/status-check-api">
  Confirm the authoritative auth status from your server.
</Card>
