Return Types & Models

Kotlin data classes, enums, and feature-variable accessors

This page documents the public Kotlin types the SDK returns and the enums you pass in. All model types live in com.convert.sdk.core.model; the event constants live in com.convert.sdk.core.event. The SDK never throws from its public decision methods — absent or not-ready data surfaces as null or an empty list.

Variation

Returned by ConvertContext.runExperience(...) (nullable) and runExperiences(...) (as a list). A Kotlin data class with all-nullable fields:

public data class Variation(
    val id: String? = null,
    val key: String? = null,
    val name: String? = null,
    val experienceId: String? = null,
    val experienceKey: String? = null,
    val experienceName: String? = null,
    val bucketingAllocation: Double? = null,
    val changes: List<JsonElement>? = null,
)
  • key — the merchant-defined variation key from the Convert dashboard; this is what you branch on.
  • id — the variation identifier.
  • bucketingAllocation — the basis-point allocation the visitor hit. Populated on fresh bucketing; null on a sticky lookup.
  • changes — raw variation changes, as JsonElement values.
val variation = ctx.runExperience("homepage-redesign")
when (variation?.key) {
    "control" -> renderControl()
    "treatment" -> renderTreatment()
    null -> renderControl() // not ready / not bucketed / experience absent
}

Feature and FeatureStatus

Returned by ConvertContext.runFeature(...) (nullable) and runFeatures(...) (as a list):

public data class Feature(
    val id: String? = null,
    val key: String? = null,
    val name: String? = null,
    val status: FeatureStatus,
    val variables: Map<String, JsonElement>? = null,
    val experienceId: String? = null,
    val experienceKey: String? = null,
    val experienceName: String? = null,
) {
    val enabled: Boolean get() = status == FeatureStatus.ENABLED
}

public enum class FeatureStatus { ENABLED, DISABLED }
  • enabled is a convenience for status == FeatureStatus.ENABLED.
  • When a feature is DISABLED, variables is null and the accessors below return null.
val feature = ctx.runFeature("checkout-v2")
if (feature?.enabled == true) {
    enableCheckoutV2()
}

Feature variable accessors

When a feature is ENABLED, variables holds JsonElement values — usually JsonPrimitive scalars. For the common scalar case, use the extension helpers in com.convert.sdk.android (file facade FeatureExtensions):

import com.convert.sdk.android.getString
import com.convert.sdk.android.getInt
import com.convert.sdk.android.getDouble
import com.convert.sdk.android.getBoolean

val color = feature?.getString("ctaColor") ?: "#0066ff"
val limit = feature?.getInt("maxItems") ?: 20
val price = feature?.getDouble("price") ?: 9.99
val experimental = feature?.getBoolean("experimental") == true

Coercion is strict-then-loose: numeric primitives resolve directly; numeric strings fall back through toXxxOrNull(). JsonNull, arrays, nested objects, and absent keys all return null. For structured (JsonObject / JsonArray) variables, read feature.variables?.get("key") and decode the JsonElement yourself with kotlinx.serialization.

GoalData and GoalDataKey

Passed to ConvertContext.trackConversion(...) to attach transactional data to a conversion:

public data class GoalData(
    val key: GoalDataKey? = null,
    val value: JsonElement? = null,
)

GoalDataKey values and their JSON names on the wire:

Enum valueJSON nameTypical value
AMOUNTamountnumber
PRODUCTS_COUNTproductsCountinteger
TRANSACTION_IDtransactionIdstring
CUSTOM_DIMENSION_1customDimension1string / number
CUSTOM_DIMENSION_2customDimension2string / number
CUSTOM_DIMENSION_3customDimension3string / number
CUSTOM_DIMENSION_4customDimension4string / number
CUSTOM_DIMENSION_5customDimension5string / number
import com.convert.sdk.core.model.GoalData
import com.convert.sdk.core.model.GoalDataKey
import kotlinx.serialization.json.JsonPrimitive

ctx.trackConversion(
    goalKey = "purchase-completed",
    goalData = listOf(
        GoalData(GoalDataKey.AMOUNT, JsonPrimitive(49.99)),
        GoalData(GoalDataKey.PRODUCTS_COUNT, JsonPrimitive(3)),
        GoalData(GoalDataKey.TRANSACTION_ID, JsonPrimitive("tx-42")),
    ),
)

LogLevel

public enum class LogLevel { ERROR, WARN, INFO, DEBUG, TRACE }

Passed to Builder.logLevel(...). The default is ERROR. See Configuration Options.

SystemEvents

Well-known event names you can subscribe to with sdk.on(event, callback). Each is a String constant on com.convert.sdk.core.event.SystemEvents:

ConstantEvent name
READYready
CONFIG_UPDATEDconfig.updated
API_QUEUE_RELEASEDapi.queue.released
BUCKETINGbucketing
CONVERSIONconversion
SEGMENTSsegments
LOCATION_ACTIVATEDlocation.activated
LOCATION_DEACTIVATEDlocation.deactivated
AUDIENCESaudiences
DATA_STORE_QUEUE_RELEASEDdatastore.queue.released

The shared Event System doc explains when each fires.

EventCallback and SubscriptionToken

public fun interface EventCallback {
    public fun onEvent(data: Map<String, Any?>)
}

EventCallback is a Kotlin fun interface, so Kotlin and Java lambdas both convert to it. sdk.on(event, callback) returns an opaque SubscriptionToken; pass it to sdk.off(event, token) to unsubscribe. See Initialization and Java Interop.

Next steps