Skip to main content
The experiments module assigns users to variants using a deterministic hash. No server call is needed — assignment is instant, works offline, and the same user always gets the same variant.

Get Variant

val variant = AppDNA.experiments.getVariant("paywall-test")

when (variant) {
    "control" -> showStandardPaywall()
    "variant_a" -> showNewPaywall()
    else -> showStandardPaywall() // Always handle the default case
}
Returns the variant string or null if the experiment is not found, not running, or the user is not in the target audience.
Always handle the null / else case. Experiments can be archived or stopped at any time from the Console.

Module Access

val experiments = AppDNA.experiments

Module Methods

MethodSignatureDescription
getVariantgetVariant(experimentId: String, trackExposure: Boolean = true): String?Get the assigned variant
trackExposuretrackExposure(experimentId: String)Manually track an exposure event
setDelegatesetDelegate(delegate: ExperimentDelegate?)Set a delegate for assignment callbacks

Exposure Tracking

Automatic (Default)

The SDK tracks an experiment_exposure event once per session the first time getVariant() is called for a given experiment.

Manual

Disable automatic tracking and track when the UI is actually visible:
val variant = AppDNA.experiments.getVariant("paywall-test", trackExposure = false)

// Later, when the paywall is actually displayed
fun onPaywallVisible() {
    AppDNA.experiments.trackExposure("paywall-test")
}

ExperimentDelegate

Register a delegate to be notified when experiment assignments change:
AppDNA.experiments.delegate = object : ExperimentDelegate {
    override fun onAssignmentChanged(experimentId: String, newVariant: String?) {
        println("Experiment $experimentId now: ${newVariant ?: "none"}")
    }
}
Assignment changes are rare. They occur only when the experiment definition changes on the server, not on every session start.

Experiment Lifecycle

StatusgetVariant() returns
Draftnull — not visible to SDKs
RunningAssigned variant string
CompletedWinning variant for all users
Archivednull — removed from config

Full Example

import ai.appdna.sdk.AppDNA
import ai.appdna.sdk.ExperimentDelegate
import ai.appdna.sdk.PaywallContext

class PaywallExperiment(private val activity: Activity) : ExperimentDelegate {
    init {
        AppDNA.experiments.delegate = this
    }

    fun showPaywall() {
        val variant = AppDNA.experiments.getVariant("paywall_redesign")

        val paywallId = when (variant) {
            "new_design" -> "paywall_v2"
            else -> "paywall_v1"
        }

        AppDNA.paywall.present(
            paywallId, activity,
            context = PaywallContext(
                placement = "settings",
                experiment = "paywall_redesign",
                variant = variant ?: "control"
            )
        )
    }

    override fun onAssignmentChanged(experimentId: String, newVariant: String?) {
        // Assignment changed mid-session (rare)
    }
}
Experiments are created in the Console under Experiments. The SDK uses MurmurHash3 for deterministic assignment — the same user always gets the same variant across sessions, platforms, and even offline.