---
title: Instrument and configure the Unified SDK for Android
description: "Configure each product, read Feature Experiment variants, control Session Replay, share identity across products, and migrate from separate SDKs with the Amplitude Unified SDK for Android."
product: analytics
lang: en
last_updated: 2026-11-04
token_estimate: 2505
---
# Instrument and configure the Unified SDK for Android

This guide covers the work specific to the Unified SDK for Android after [Get started](https://amplitude.com/docs/sdks/analytics/android/unified-sdk/get-started): configuring each product, using Feature Experiment and Session Replay, sharing identity, and migrating from separate SDKs. For tracking events, identity, sessions, autocapture, and data delivery, use the [Instrument and configure the Android-Kotlin SDK](https://amplitude.com/docs/sdks/analytics/android/android-kotlin-sdk/instrument-and-configure). `AmplitudeUnified` has every method that guide describes. For signatures and defaults, go to the [Reference](https://amplitude.com/docs/sdks/analytics/android/unified-sdk/reference). For changes between versions, go to the [Unified SDK changelog](https://github.com/amplitude/Amplitude-Kotlin/blob/main/unified/CHANGELOG.md).

> For AI agents: a documentation index is available at [/docs/llms.txt](/docs/llms.txt). Append `.md` to any page URL for markdown, or send `Accept: text/markdown`.

## Configure each product

### How the Unified SDK sets up each product

When you construct `AmplitudeUnified`, the SDK:

1. Builds Analytics from the `analytics` options, exactly as the Android-Kotlin SDK's `Amplitude` constructor does.
2. Installs Session Replay as a plugin, unless `sessionReplay.enabled` is `false`. Session Replay records against the Analytics API key, server zone, device ID, and session ID.
3. Installs Experiment as a plugin, unless `experiment.enabled` is `false`. Experiment takes its instance name, server zone, user, and exposure tracking from Analytics, and uses the Analytics API key unless you set `deploymentKey`.
4. Adds `amplitude-android-unified/<version>` to the front of each event's `library` value.

If Session Replay or Experiment throws during setup, the SDK logs `Failed to install plugin "<name>": <exception>` and keeps the rest running.

### Pass options to each product

Each product has its own block. The `analytics` block is the Android-Kotlin SDK's `ConfigurationBuilder`, so it takes every [Android-Kotlin SDK configuration option](https://amplitude.com/docs/sdks/analytics/android/android-kotlin-sdk/reference#configuration-options).

#### Kotlin

```kotlin
import com.amplitude.core.ServerZone
import com.amplitude.unified.AmplitudeUnified

val amplitude = AmplitudeUnified("YOUR_API_KEY", applicationContext) {
    analytics {
        serverZone = ServerZone.EU
        flushQueueSize = 20
        minTimeBetweenSessionsMillis = 300_000
    }
    sessionReplay {
        sampleRate = 0.1
    }
    experiment {
        deploymentKey = "YOUR_DEPLOYMENT_KEY"
    }
}
```

#### Java

```java
UnifiedConfigurationBuilder builder =
    new UnifiedConfigurationBuilder("YOUR_API_KEY", getApplicationContext());
builder.getAnalytics().setServerZone(ServerZone.EU);
builder.getAnalytics().setFlushQueueSize(20);
builder.getAnalytics().setMinTimeBetweenSessionsMillis(300000);
builder.getSessionReplay().setSampleRate(0.1);
builder.getExperiment().setDeploymentKey("YOUR_DEPLOYMENT_KEY");

AmplitudeUnified amplitude = builder.build();
```

Set `serverZone` in `analytics`. Session Replay and Experiment read it from Analytics, so you set it once.

### Turn off a product

Set `enabled = false` in the product's block. The SDK doesn't install that product, and its accessor returns `null`.

```kotlin
val amplitude = AmplitudeUnified("YOUR_API_KEY", applicationContext) {
    sessionReplay { enabled = false }
}
```

## Use Feature Experiment

### Fetch flags and read a variant

Read the client from `amplitude.experiment`. You don't need to call `start()`. The SDK starts the client as soon as three conditions are true: Analytics has a device ID, Analytics has a session ID, and the user isn't opted out. Because `fetchOnStart` defaults to `true`, the client fetches flags when it starts.

#### Kotlin

```kotlin
val experiment = amplitude.experiment ?: return

val variant = experiment.variant("checkout-redesign")
if (variant.value == "treatment") {
    // Show the new checkout.
}
```

#### Java

```java
ExperimentClient experiment = amplitude.getExperiment();
if (experiment == null) return;

Variant variant = experiment.variant("checkout-redesign");
if ("treatment".equals(variant.value)) {
    // Show the new checkout.
}
```

`variant()` reads cached variants, so a call made before the first fetch finishes returns the fallback. To wait for fresh variants, for example right after sign-in, call `fetch()` and wait for its `Future`. Call `get()` off the main thread:

```kotlin
experiment.fetch().get()
```

Exposures go through Analytics as `$exposure` events, so they use the same identity, queue, and upload settings as your other events.

The Unified SDK keeps Experiment in step with Analytics:

- **Identity changes**: The SDK updates the Experiment user when the user ID, device ID, or user properties change. The SDK refetches flags only when you build the config with `.automaticFetchOnAmplitudeIdentityChange(true)` (default `false`).
- **Opt-out**: When you set `optOut = true`, the SDK stops flag polling. `variant()` still returns cached variants. When you opt back in, the SDK restarts the client.
- **Reset**: `reset()` clears cached variants.

### Set the deployment key

Experiment uses your Analytics API key unless you set a deployment key. Set one when your flags belong to a deployment with its own key:

```kotlin
val amplitude = AmplitudeUnified("YOUR_API_KEY", applicationContext) {
    experiment {
        deploymentKey = "YOUR_DEPLOYMENT_KEY"
    }
}
```

For other Experiment options, build a config with `ExperimentConfig.builder()` and set `experiment { config = ... }`. The SDK replaces `instanceName` and `serverZone` in that config with the Analytics values. Go to the [Experiment Android SDK](https://amplitude.com/docs/sdks/experiment-sdks/experiment-android).

## Use Session Replay

### Choose a sample rate

`sampleRate` defaults to `0.0`, which records nothing. Set it to the fraction of sessions to record, from `0.0` to `1.0`. Use `1.0` while you test, then lower it.

### Control recording from code

Read the client from `amplitude.sessionReplay`. Call `stop()` to pause capture, for example on a screen that shows sensitive data, and `start()` to resume.

#### Kotlin

```kotlin
amplitude.sessionReplay?.stop()
// ...
amplitude.sessionReplay?.start()
```

#### Java

```java
SessionReplay sessionReplay = amplitude.getSessionReplay();
if (sessionReplay != null) {
    sessionReplay.stop();
    // ...
    sessionReplay.start();
}
```

To choose when capture first starts, set `sessionReplay { autoStart = false }` and call `start()` yourself.

While Session Replay records, the plugin adds `[Amplitude] Session Replay ID` to each event whose device ID and session ID match the recording, including Experiment exposures. Charts use that property to link events to replays.

For masking, WebView capture, and log recording, go to the [Session Replay Android plugin](https://amplitude.com/docs/sdks/session-replay/session-replay-android-plugin).

## Share identity across products

`setUserId()`, `setDeviceId()`, `reset()`, opt-out, and session changes on `AmplitudeUnified` reach Session Replay and Experiment automatically. Go to [Identity and sessions](https://amplitude.com/docs/sdks/analytics/android/android-kotlin-sdk/instrument-and-configure#identity-and-sessions) in the Android-Kotlin SDK.

To change the user ID, device ID, and user properties in one step, call `setIdentity()`. The SDK passes the new identity to Experiment as one update, so the Experiment user carries the new properties on its next fetch. Read the device ID after Analytics finishes loading stored identity:

```kotlin
import com.amplitude.core.events.Identify

// Inside a coroutine
amplitude.isBuilt.await()
val deviceId = requireNotNull(amplitude.getDeviceId())
amplitude.setIdentity("user-123", deviceId, mapOf("plan" to "paid"))
```

`setIdentity()` replaces both IDs and the user properties together. The properties live in memory for the current process. The SDK doesn't persist them. If you omit the properties argument, `setIdentity()` clears the user properties. To remove a user property in Amplitude, send an identify: `amplitude.identify(Identify().unset("plan"))`. Shared identity requires Unified SDK 1.1.0 or later.

## Migrate from separate SDKs

If your app sets up the Android-Kotlin SDK, the Session Replay plugin, and Experiment separately, replace that setup with one `AmplitudeUnified`.

> **Warning:** Remove your own plugins first
>
> Remove every `SessionReplayPlugin` you add and every Experiment client you create with `Experiment.initializeWithAmplitudeAnalytics()` or `AmplitudeExperimentPlugin`. A second Experiment plugin makes `amplitude.experiment` return `null`, and a second Experiment client duplicates fetches, polling, and exposure events.

1. In your module's build file, replace `analytics-android`, `plugin-session-replay-android`, and `experiment-android-client` with `unified-android`.
2. Remove the `SessionReplayPlugin` registration and the Experiment client setup.
3. Replace the `Amplitude` constructor with `AmplitudeUnified`, moving each product's options into its block.

Before:

```kotlin
val amplitude = Amplitude("YOUR_API_KEY", applicationContext) {
    flushQueueSize = 20
}
amplitude.add(SessionReplayPlugin(applicationContext, sampleRate = 1.0))

val experiment = Experiment.initializeWithAmplitudeAnalytics(
    applicationContext, "YOUR_DEPLOYMENT_KEY", ExperimentConfig()
)
experiment.fetch().get()
```

After:

```kotlin
val amplitude = AmplitudeUnified("YOUR_API_KEY", applicationContext) {
    analytics { flushQueueSize = 20 }
    sessionReplay { sampleRate = 1.0 }
    experiment { deploymentKey = "YOUR_DEPLOYMENT_KEY" }
}

val experiment = amplitude.experiment
```

Keep the same `instanceName` (or leave it unset in both), so the Unified SDK reads the identity and queued events the separate SDK stored.

