Kotlin

Native Kotlin SDK for Android/JVM apps.

Overview

The Kotlin SDK provides realtime flag updates, polling fallback, identity targeting, and telemetry with one client object: TruflagClient.

Get started

Install

KKOTLIN
dependencies {
implementation("com.truflag:truflag-android-client-sdk:1.0.2")
}

Configure

apiKey is required. If no user is passed, the SDK starts anonymous automatically.

KKOTLIN
import com.truflag.sdk.TruflagClient
val client = TruflagClient()
client.configure(
apiKey = BuildConfig.TRUFLAG_CLIENT_KEY,
userId = "user-123",
userAttributes = mapOf(
"plan" to "pro",
"country" to "US",
),
)

SDK API overview

Full configure surface for Kotlin.

KKOTLIN
suspend fun configure(
apiKey: String,
userId: String? = null,
userAttributes: Map<String, Any?>? = null,
baseUrl: String = "https://sdk.truflag.com",
streamUrl: String = "wss://stream.sdk.truflag.com",
streamEnabled: Boolean = true,
logLevel: TruflagLogLevel = TruflagLogLevel.DEBUG,
cacheTtlMs: Long = 300_000,
pollingIntervalMs: Long = 60_000,
requestTimeoutMs: Long = 6_000,
telemetryEnabled: Boolean = true,
telemetryFlushIntervalMs: Long = 10_000,
telemetryBatchSize: Int = 50,
logger: TruflagLogger? = null,
fetchFn: TruflagFetchFn? = null,
storage: TruflagStorage? = null,
): Unit
data class TruflagConfigureOptions(
val apiKey: String,
val user: TruflagUser? = null,
val baseUrl: String = "https://sdk.truflag.com",
val streamUrl: String = "wss://stream.sdk.truflag.com",
val streamEnabled: Boolean = true,
val logLevel: TruflagLogLevel = TruflagLogLevel.DEBUG,
val cacheTtlMs: Long = 300_000,
val pollingIntervalMs: Long = 60_000,
val requestTimeoutMs: Long = 6_000,
val telemetryEnabled: Boolean = true,
val telemetryFlushIntervalMs: Long = 10_000,
val telemetryBatchSize: Int = 50,
val logger: TruflagLogger? = null,
val fetchFn: TruflagFetchFn? = null,
val storage: TruflagStorage? = null,
)

Identity

KKOTLIN
client.login(
userId = "user-456",
attributes = mapOf("plan" to "enterprise"),
)
client.setAttributes(
mapOf("plan" to "enterprise", "region" to "us-east-1"),
)
client.logout() // switches to anonymous user and refreshes

Flag reads

Use one read method: getFlag(key, fallback).

KKOTLIN
// One-off read with fallback:
val enabled = client.getFlag("my-flag", false)
val variant = client.getFlag("checkout-variant", "control")
val config = client.getFlag("checkout-config", emptyMap<String, Any?>())
// Optional metadata
val payload = client.getFlagPayload("my-flag")

Events

KKOTLIN
client.track(
eventName = "checkout_completed",
properties = mapOf(
"source" to "android",
"value" to 99.95,
"context" to mapOf("screen" to "checkout"),
"items" to listOf("sku_1", "sku_2"),
),
)
client.expose(
flagKey = "my-flag",
)

Reactive updates

state() emits when flags/identity/diagnostics change, including websocket-driven updates.

KKOTLIN
// Reactive UI pattern:
scope.launch {
client.state().collect {
val next = client.getFlag("my-flag", false)
// update UI state here
}
}

Troubleshooting

Flags always return fallback

Confirm client.isReady() is true and the flag key exists in the environment tied to your apiKey.

No realtime updates

Verify streamEnabled = true and a validstreamUrl. Polling fallback remains active if stream connectivity drops.