# Variation Distribution

When running an A/B Test, you need to assign users to Variations and implement logic for each Variation. You can use the Hackle SDK to handle this user distribution.

## variation

{% hint style="info" %}
When using the Java/Kotlin SDK, duplicate exposure events for the same A/B Test distribution result triggered consecutively by the same user within 1 minute are removed.

Events within 1 minute are counted as 1 occurrence.
{% endhint %}

{% hint style="warning" %}
Cohort Targeting is not supported in the Server SDK.\
If the Targeting includes a cohort, please run the test using the Client SDK.
{% endhint %}

Pass the **Experiment Key** and **User Identifier** to the `variation()` method to assign users to a Variation and receive the result. Then implement logic for each Variation.

In the example code below, Experiment Key 42 is passed and the User Identifier is "ae2182e0". There are two Variations: A and B.

{% tabs %}
{% tab title="Kotlin" %}

```kotlin
import io.hackle.sdk.HackleClient
import io.hackle.sdk.common.Variation

// Determines which Variation to show to the user identified as "ae2182e0"
// in the A/B Test with Experiment Key 42.
// Returns Variation A if a decision cannot be made.
val variation: Variation = hackleClient.variation(42, "ae2182e0")

// Logic for the assigned Variation
if (variation == Variation.A) {
  // Group A logic
} else if (variation == Variation.B) {
  // Group B logic
}
```

{% endtab %}

{% tab title="Java" %}

```java
import io.hackle.sdk.HackleClient
import io.hackle.sdk.common.Variation


// Determines which Variation to show to the user identified as "ae2182e0"
// in the A/B Test with Experiment Key 42.
// Returns Variation A if a decision cannot be made.
Variation variation = hackleClient.variation(42, "ae2182e0");

// Logic for the assigned Variation
if (variation == Variation.A) {
  // Group A logic
} else if (variation == Variation.B) {
  // Group B logic
}
```

{% endtab %}
{% endtabs %}

## variationDetail

The `variationDetail()` method works the same as `variation()` but additionally provides the reason for being assigned to a specific group. This method is useful for verifying that distribution is working correctly.\
You must pass the Experiment Key as a parameter. In the example code below, Experiment Key 42 is passed.

{% tabs %}
{% tab title="Kotlin" %}

```kotlin
import io.hackle.sdk.HackleClient
import io.hackle.sdk.common.Variation
import io.hackle.sdk.common.decision.Decision
import io.hackle.sdk.common.decision.DecisionReason

// Variation distribution decision detail
val decision: Decision = hackleClient.variationDetail(42, "ae2182e0")

// Assigned Variation
val variation: Variation = decision.variation

// Decision reason
val reason: DecisionReason = decision.reason
```

{% endtab %}

{% tab title="Java" %}

```java
import io.hackle.sdk.HackleClient
import io.hackle.sdk.common.Variation
import io.hackle.sdk.common.decision.Decision
import io.hackle.sdk.common.decision.DecisionReason

// Variation distribution decision detail
Decision decision = hackleClient.variationDetail(42, "ae2182e0");

// Assigned Variation
Variation variation = decision.getVariation();

// Decision reason
DecisionReason reason = decision.getReason();
```

{% endtab %}
{% endtabs %}

The decision reason is returned in a format such as **`SDK_NOT_READY`**. Refer to the table below for details.

<table><thead><tr><th width="319.12109375">Distribution Reason</th><th width="305.35546875">Description</th><th>Distribution Result</th></tr></thead><tbody><tr><td><code>SDK_NOT_READY</code></td><td><p>The SDK is not ready to use.</p><p>(e.g., initialization attempted with an invalid SDK Key)</p></td><td>A (Control Group)</td></tr><tr><td><code>EXPERIMENT_NOT_FOUND</code></td><td>No A/B Test was found for the provided Experiment Key. The Experiment Key may be incorrect, or the experiment may be archived.</td><td>A (Control Group)</td></tr><tr><td><code>NOT_IN_MUTUAL_EXCLUSION_EXPERIMENT</code></td><td>The experiment is included in Mutually Exclusive Settings, but<br>the user was not assigned to that Mutually Exclusive Group.</td><td>A (Control Group)</td></tr><tr><td><code>EXPERIMENT_DRAFT</code></td><td>The A/B Test is in draft state.</td><td>A (Control Group)</td></tr><tr><td><code>EXPERIMENT_PAUSED</code></td><td>The A/B Test is paused.</td><td>A (Control Group)</td></tr><tr><td><code>EXPERIMENT_COMPLETED</code></td><td>The A/B Test has ended.</td><td>Winning Variation selected at completion</td></tr><tr><td><code>OVERRIDDEN</code></td><td>The user was assigned to a specific group<br>by Override.</td><td>Override-assigned<br>group</td></tr><tr><td><code>NOT_IN_EXPERIMENT_TARGET</code></td><td>The user is not an A/B Test target.</td><td>A (Control Group)</td></tr><tr><td><code>TRAFFIC_NOT_ALLOCATED</code></td><td>The A/B Test is running, but<br>the user was not allocated to the test.</td><td>A (Control Group)</td></tr><tr><td><code>TRAFFIC_ALLOCATED</code></td><td>The user has been allocated to the A/B Test.</td><td>Allocated group</td></tr><tr><td><code>VARIATION_DROPPED</code></td><td>The originally allocated group has been removed from the test.</td><td>A (Control Group)</td></tr><tr><td><code>INVALID_INPUT</code></td><td>The input value is invalid.</td><td>A (Control Group)</td></tr><tr><td><code>EXCEPTION</code></td><td>An unknown error occurred.</td><td>A (Control Group)</td></tr></tbody></table>

## Parameters

* You can also receive the parameter values for the assigned Variation through the `variationDetail()` method.
* The `Decision` instance returned by `variationDetail()` contains a `ParameterConfig` object with the full parameter configuration.
* Since parameter values configured in the Hackle A/B Test screen are stored as key-value pairs, use the methods below according to the parameter type to retrieve the configured values.

{% tabs %}
{% tab title="Kotlin" %}

#### getString

* Returns parameter values configured as STRING or JSON type.
* Returns the value configured for the assigned Variation.

```kotlin
import io.hackle.sdk.HackleClient
import io.hackle.sdk.common.decision.Decision
import io.hackle.sdk.common.decision.DecisionReason

val decision: Decision = hackleClient.variationDetail(42, "ae2182e0")
val config: ParameterConfig = decision.config

val strValue: String = decision.getString("parameter_key_string_type", "defaultValue")
val strValueInConfig: String = config.getString("parameter_key_string_type", "defaultValue")

val jsonValue: String = decision.getString("parameter_key_json_type", "defaultValue")
val jsonValueInConfig: String = config.getString("parameter_key_json_type", "defaultValue")
```

#### getInt

* Returns parameter values configured as Number type as an Int.
* Returns the value configured for the assigned Variation.

```kotlin
import io.hackle.sdk.HackleClient
import io.hackle.sdk.common.decision.Decision

val decision: Decision = hackleClient.variationDetail(42, "ae2182e0")
val config: ParameterConfig = decision.config

val intValue: Int = decision.getInt("parameter_key_number_type", 0)
val intValueInConfig: Int = config.getInt("parameter_key_number_type", 0)
```

#### getDouble

* Returns parameter values configured as Number type as a Double.
* Returns the value configured for the assigned Variation.

```kotlin
import io.hackle.sdk.HackleClient
import io.hackle.sdk.common.decision.Decision

val decision: Decision = hackleClient.variationDetail(42, "ae2182e0")
val config: ParameterConfig = decision.config

val doubleValue: Double = decision.getDouble("parameter_key_number_type", 0.0)
val doubleValueInConfig: Double = config.getDouble("parameter_key_number_type", 0.0)
```

#### getLong

* Returns parameter values configured as Number type as a Long.
* Returns the value configured for the assigned Variation.

```kotlin
import io.hackle.sdk.HackleClient
import io.hackle.sdk.common.decision.Decision

val decision: Decision = hackleClient.variationDetail(42, "ae2182e0")
val config: ParameterConfig = decision.config

val longValue: Long = decision.getLong("parameter_key_number_type", 0L)
val longValueInConfig: Long = config.getLong("parameter_key_number_type", 0L)
```

#### getBoolean

* Returns parameter values configured as Boolean type.
* Returns the value configured for the assigned Variation.

```kotlin
import io.hackle.sdk.HackleClient
import io.hackle.sdk.common.decision.Decision

val decision: Decision = hackleClient.variationDetail(42, "ae2182e0")
val config: ParameterConfig = decision.config

val booleanValue: Boolean = decision.getBoolean("parameter_key_boolean_type", false)
val booleanValueInConfig: Boolean = config.getBoolean("parameter_key_boolean_type", false)
```

{% endtab %}

{% tab title="Java" %}

#### getString

* Returns parameter values configured as STRING or JSON type.
* Returns the value configured for the assigned Variation.

```java
import io.hackle.sdk.HackleClient
import io.hackle.sdk.common.decision.Decision
import io.hackle.sdk.common.decision.DecisionReason

Decision decision = hackleClient.variationDetail(42, "ae2182e0");
ParameterConfig config = decision.getConfig();

String strValue = decision.getString("parameter_key_string_type", "defaultValue");
String strValueInConfig = config.getString("parameter_key_string_type", "defaultValue");

String jsonValue = decision.getString("parameter_key_json_type", "defaultValue");
String jsonValueInConfig = config.getString("parameter_key_json_type", "defaultValue");
```

#### getInt

* Returns parameter values configured as Number type as an Int.
* Returns the value configured for the assigned Variation.

```java
import io.hackle.sdk.HackleClient
import io.hackle.sdk.common.decision.Decision

Decision decision = hackleClient.variationDetail(42, "ae2182e0");
ParameterConfig config = decision.getConfig();

int intValue = decision.getInt("parameter_key_number_type", 0);
int intValueInConfig = config.getInt("parameter_key_number_type", 0);
```

#### getDouble

* Returns parameter values configured as Number type as a Double.
* Returns the value configured for the assigned Variation.

```java
import io.hackle.sdk.HackleClient
import io.hackle.sdk.common.decision.Decision

Decision decision = hackleClient.variationDetail(42, "ae2182e0");
ParameterConfig config = decision.getConfig();

double doubleValue = decision.getDouble("parameter_key_number_type", 0.0);
double doubleValueInConfig = config.getDouble("parameter_key_number_type", 0.0);
```

#### getLong

* Returns parameter values configured as Number type as a Long.
* Returns the value configured for the assigned Variation.

```java
import io.hackle.sdk.HackleClient
import io.hackle.sdk.common.decision.Decision

Decision decision = hackleClient.variationDetail(42, "ae2182e0");
ParameterConfig config = decision.getConfig();

long longValue = decision.getLong("parameter_key_number_type", 0L);
long longValueInConfig = config.getLong("parameter_key_number_type", 0L);
```

#### getBoolean

* Returns parameter values configured as Boolean type.
* Returns the value configured for the assigned Variation.

```java
import io.hackle.sdk.HackleClient
import io.hackle.sdk.common.decision.Decision

Decision decision = hackleClient.variationDetail(42, "ae2182e0");
ParameterConfig config = decision.getConfig();

boolean booleanValue = decision.getBoolean("parameter_key_boolean_type", false);
boolean booleanValueInConfig = config.getBoolean("parameter_key_boolean_type", false);
```

{% endtab %}
{% endtabs %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.hackle.io/en/development-guide/java-kotlin/java-variation.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
