> ## 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 authentication flow — add the dependency, initialize, start with a requestId, and handle callbacks.

This page covers the integration of the OTPless Headless SDK on Android. The SDK accepts the `requestId` generated by the [Create API](/docs/server-initiated-auth/create-api), performs the authentication, and reports progress through callbacks. Your backend confirms the final result via the [Status Check API](/docs/server-initiated-auth/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>

<Warning>
  Make sure your authentication channel is enabled on the [OTPLESS dashboard](https://otpless.com/dashboard/customer/channels).
</Warning>

## Step 2: 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 3: Start authentication with the requestId

Pass the `requestId` returned by the [Create API](/docs/server-initiated-auth/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](/docs/server-initiated-auth/status-check-api) from your backend immediately after calling `start()`. The SDK callback and the server status run in parallel.
</Note>

## Step 4: 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 {
                // Authentication is in progress — show a loading state.
            }
        }
        ResponseTypes.ONETAP -> {
            // Final success response
        }
        ResponseTypes.AUTH_TERMINATED -> {
            // Auth could not complete. Emitted when pre-checks fail,
            // or when authentication 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 2).

| 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 3).

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

<Warning>
  `AUTH_TERMINATED` is a terminal failure. Always treat the [Status Check API](/docs/server-initiated-auth/status-check-api) result as authoritative.
</Warning>

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

## Next step

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


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.