Android quickstart

  1. 1

    Add the dependency

    kotlin
    // settings.gradle.kts — JitPack is not a default repository
    dependencyResolutionManagement {
        repositories {
            google()
            mavenCentral()
            maven { url = uri("https://jitpack.io") }
        }
    }
    kotlin
    // app/build.gradle.kts
    implementation("com.github.neetixai:liveliness-sdks:0.2.0")
  2. 2

    Get a test key

    bash
    curl -X POST https://liveliness.neetix.in/v1/signup \
      -H 'Content-Type: application/json' \
      -d '{"email":"you@company.com"}'
    Do not ship a key in the APK

    Anything in the APK can be extracted from it — BuildConfig fields included. Use a test key while building; in production mint short-lived keys from your own backend, and use the Play Integrity hook to prove the call came from your real, unmodified app.

  3. 3

    Make the call

    Every method is a suspend function, so call it from a coroutine — never the main thread:

    kotlin
    import `in`.neetix.liveliness.NeetixClient
    
    val nx = NeetixClient(apiKey = "YOUR_KEY")
    
    viewModelScope.launch {
        val res = nx.faceMatch(
            person = selfieBytes,
            card = idBytes,
            clientRefId = "application-4821",
        )
    
        Log.d("kyc", res.verdict)              // "approved" | "review" | "declined"
        Log.d("kyc", "${res.result.isSameFace}")
        Log.d("kyc", res.warnings.joinToString { it.code })
    }

    warnings is a list of ApiWarning(code, severity, description), not of strings — severity is already "decline" or "review", so you rarely need to classify a warning yourself.

    `in` is a Kotlin keyword

    The package is in.neetix.liveliness, and in is reserved — so the import needs backticks: import `in`.neetix.liveliness.NeetixClient. This trips up everyone exactly once.

  4. 4

    Branch on the verdict

    kotlin
    when (res.verdict) {
        "approved" -> continueJourney()
        "review"   -> queueForReview(res.warnings)
        "declined" -> stop(res.warnings)
    }
  5. 5

    Handle 402 explicitly

    kotlin
    import `in`.neetix.liveliness.NeetixApiException
    
    try {
        val res = nx.faceMatch(person = selfieBytes, card = idBytes)
    } catch (e: NeetixApiException) {
        if (e.isInsufficientCredits) {
            // HTTP 402 — the prepaid balance is gone; every call fails until top-up.
            alertOpsAndHold()
        }
        Log.e("kyc", "${e.statusCode} ${e.messageCode} ${e.message}")
        throw e
    }

Guided capture

The CameraX capture view lives in the repo's capture/ module and is not in the published artifact — it is pre-release and uncompiled in CI. Take it as source or add it as an included Gradle module:

bash
git clone https://github.com/neetixai/liveliness-sdks
# then copy packages/android/capture/src/main/kotlin/ into your app,
# with the CameraX + Play Integrity deps from capture/build.gradle.kts

Until then, capture with CameraX yourself and pass the JPEG bytes. Aim for the longest side around 1280 px — larger uploads cost latency without improving the verdict.

Next

  • Get started — verdicts, warnings and credits.
  • REST API — what the client calls underneath.