Choose Variations Using Kotlin SDK

The Choose Variations call activates one or more Dynamic Yield campaigns by name and retrieves data necessary to render personalized content. Learn more about the Choose call in the Experience API guide.

Note: All Choose Variations calls are asynchronous.

Parameters

Note: Either selectorNames or selectorGroups must be provided in the request body.

ParameterData Structure TypeMandatoryDescription
selectorNames
required if selectorGroups is not used
List<String>NoA list of campaigns to choose variations for. A selector represents a technical name for a campaign.
Learn more about using selectors in your campaigns.
selectorGroups
required if selectorNames is not used
List<String>NoCall a group of selectors instead of listing each selector individually.
Learn more about working with selector groups.
pagePageYesAn object containing information about the currently viewed page.
selectorPreviewsList<String>NoCampaigns to generate previews for.
Learn more about enabling preview mode.
dayPart
(Restaurants only)
DayPartNoDefines the period of the day the request relates to.
For Restaurant Recommendations campaigns only.
cartList<CartItem>NoA list of all items currently in the cart.
branchIdStringNoThe unique identifier of the branch.
Applies only when branch context exists and must match the IDs in the branch feed.
optionsChooseOptionsNoRequest configuration parameters (report a new pageview/impression, return additional metadata).
pageAttributesMap<String, PageAttribute>NoKey-value pairs that can be used for targeting. Values may be strings or numbers.
recsProductDataRecsProductDataNoAn object with 2 parameters:
* fieldFilter to specify the fields to be included in the recommendation campaign response
* skusOnly to fetch only the SKUs to reduce the size of the response.
See the Choose API reference for more information.

Example

private suspend fun chooseVariationsWithAllParameters() { 
    var result = DYSdk.getInstance().chooseVariations( 
        page = Page.homePage(pageLocation = "ScreenName", pageReferrer = "otherScreenName"), 
        selectorNames = listOf("example-campaign-1", "example-campaign-2"), 
        selectorGroups = listOf("example-group"), 
        selectorPreviews = listOf("example-previews"), 
        branchId = "example-branch-id", 
        options = ChooseOptions(), 
        pageAttributes = mapOf( 
            "Attr1" to PageAttribute("value-1"), 
            "Attr2" to PageAttribute(5), 
        ), 
        recsProductData = RecsProductDataOptions(), 
    ) 
} 
private suspend fun chooseVariationsWithAllParameters() { 
    var result = DYSdk.getInstance().chooseVariations( 
        page = Page.homePage(pageLocation = "ScreenName", pageReferrer = "otherScreenName"), 
        selectorNames = listOf("example-campaign-1", "example-campaign-2"), 
        selectorGroups = listOf("example-group"), 
        selectorPreviews = listOf("example-previews"), 
        dayPart = DayPart.DINNER, 
        cart = listOf( 
            CartItem( 
                productId = "example-id", quantity = 1u, itemPrice = 5f, innerProducts = listOf( 
                    CartInnerItem(productId = "example-id", quantity = 1u, itemPrice = 3f) 
                ) 
            ) 
        ), 
        branchId = "example-branch-id", 
        options = ChooseOptions(), 
        pageAttributes = mapOf( 
            "Attr1" to PageAttribute("value-1"), 
            "Attr2" to PageAttribute(5), 
        ), 
        recsProductData = RecsProductDataOptions(), 
    ) 
} 

Return Values

class DYChooseResult(
    val choices: List<Choice>? = null,
    val status: ResultStatus,
    val warnings: List<Warning>? = null,
    val error: Exception? = null,
    val rawNetworkData: RawNetworkData? = null,
) 

DYChooseResult

inherits from DYResult

private suspend fun chooseVariationResult() { 
     var chooseResult = DYSdk.getInstance().chooseVariations( 
        page = Page.homePage("ScreenName"), 
        selectorNames = listOf("example-campaign-1", "example-campaign-2") 
    ) 
    when (chooseResult.status) { 
        ResultStatus.SUCCESS -> { 
            chooseResult.choices?.forEach { choice -> 
                //Search for your campaign by name 
            } 
        } 
        ResultStatus.WARNING -> { 
            chooseResult.choices?.forEach { choice -> 
                //Search for your campaign by name
            } 
            chooseResult.warnings?.let { 
                 //Log the warnings  
            } 
        } 
        ResultStatus.ERROR -> { 
            chooseResult.error?.let { exception -> 
                //Obtain the exception object here 
            } 
            chooseResult.rawNetworkData?.let { rawNetworkData -> 
                //Log rawNetworkData to further investigate the error 
            } 
        } 
    } 
} 

Choice

PropertyDescriptionData Structure Type
idThe choice’s IDInt
decisionIdThe decision’s ID as returned from the serverString
nameThe name of the campaign (selector)String
typeThe choice’s typeChoiceType (DECISION, RECS_DECISION, STORE_RECS_DECISION, NO_DECISION)
variationsThe campaign’s chosen variationsList<Variation>
groupsThe groups the requested campaigns belong toList<String>

Variation

PropertyDescriptionData Structure Type
idThe variation IDInt
analyticsMetadataReturns additional metadata. Useful for debugging and reporting to analytics tools.AnalyticsMetadata
payloadPossible values: CustomJsonPayload, RecsPayload, StoreRecsPayloadPayload

Handling the DYResult

PropertyDescriptionData Structure Type
statusThe Choose call's status. If the type is "WARNING," it indicates that the request was successful, but there are warnings associated with the response.ResultStatus:
SUCCESS, ERROR, WARNING
warningsList of warnings returned from the server. Each warning item has a code and message.List<Warning>?
errorErrors and exceptionsException?
choicesThe chosen variations returnedList<Choice>?
rawNetworkDataNetwork-related data (for debugging purposes)RawNetworkData?

Dealing with partial success

The Dynamic Yield SDK chooseVariations call supports multiple campaigns in the same call. In a scenario where results for some of the campaigns return successfully, while there is an error for others, the result status returned is “WARNING”.

The Choice return object will contain values only for the campaigns that have returned successfully.

Campaign types

The available campaign types are: API Custom Code, API Recommendations, and Restaurant Recommendations. Each variation in the return value matches the campaign type that was determined in the campaign creation process in ExperienceOS.

API Custom Code campaigns

Custom API campaigns let you use the power of Dynamic Yield A/B testing and automatic allocation, while fully controlling how the campaigns are rendered on your app.

CustomJsonPayload

PropertyDescriptionData Structure Type
typeThe decision typeDecisionType=DECISION
dataThe variation dataString (JSON format)

Example

private suspend fun chooseCustomJsomVariationExample() { 
    var chooseResult = DYSdk.getInstance().chooseVariations( 
        page = Page.homePage("ScreenName"), 
        selectorNames = listOf("custom-json-campaign") 
    ) 
    when (chooseResult.status) { 
        ResultStatus.SUCCESS, ResultStatus.WARNING -> { 
            chooseResult.choices?.firstOrNull { it.name == "custom-json-campaign" } 
                ?.let { choice -> 
                    if (choice.type == ChoiceType.DECISION) 
                    //Assumming there is only one variation 
                        (choice.variations.firstOrNull()?.payload as? CustomJsonPayload)?.let { payload -> 
                            var data = payload.data
                        } 
                } 
        } 
        ResultStatus.ERROR -> TODO() 
    } 
} 

API Recommendations campaigns

Recommendations enable you to automatically display the most relevant items to each user.

RecsPayload

PropertyDescriptionData Structure Type
typeThe decision typeDecisionType=RECS_DECISION
dataThe variation dataRecsData

RecsData

PropertyDescriptionData Structure Type
customThe variation custom dataString (JSON format)
slotsA list of objects containing data for each slotList<RecsSlot>

Example

private suspend fun chooseRecsVariationExample() { 
    var chooseResult = DYSdk.getInstance().chooseVariations( 
        page = Page.homePage("ScreenName"), 
        selectorNames = listOf("recs-campaign") 
   			 ) 
    when (chooseResult.status) { 
        ResultStatus.SUCCESS, ResultStatus.WARNING -> { 
            chooseResult.choices?.firstOrNull { it.name == "recs-campaign" }?.let { choice -> 
                if (choice.type == ChoiceType.RECS_DECISION) 
                //Assuming there is only one variation 
                    (choice.variations.firstOrNull()?.payload as? RecsPayload)?.let { payload -> 
                        var slots = payload.data.slots
                        var custom = payload.data.custom 
                    } 
            } 
        } 
        ResultStatus.ERROR -> TODO() 
    } 
} 

Restaurant Recommendations campaigns

StoreRecsPayload

PropertyDescriptionData Structure Type
typeThe decision typeDecisionType=STORE_RECS_DECISION
dataThe variation dataStoreRecsData

StoreRecsData

PropertyDescriptionData Structure Type
customThe variation dataString (JSON format)
slotsA list of objects containing data for each slotList<StoreRecsSlot>

Example

private suspend fun chooseRestaurantsRecsVariationExample() { 
    var chooseResult = DYSdk.getInstance().chooseVariations( 
        page = Page.homePage("ScreenName"), 
        selectorNames = listOf("qsr-recs-campaign") 
    ) 
    when (chooseResult.status) { 
        ResultStatus.SUCCESS, ResultStatus.WARNING -> { 
            chooseResult.choices?.firstOrNull { it.name == "qsr-recs-campaign" }?.let { choice -> 
                if (choice.type == ChoiceType.STORE_RECS_DECISION) 
                //Assumming there is only one variation 
                    (choice.variations.firstOrNull()?.payload as? StoreRecsPayload)?.let { payload -> 
                        var slots = payload.data.slots 
                    } 
            } 
        } 
        ResultStatus.ERROR -> TODO() 
    } 
}