# Feature Flag Decision

A Feature Flag has two states: on and off. Different features are configured for each state.\
When a user accesses a feature with a Feature Flag applied, the SDK must be able to return either the on or off state. You can use the Hackle SDK to handle this state decision.

## isFeatureOn

Pass the **Feature Key** to the `isFeatureOn()` method to receive the state result for the user. Then implement logic based on the state.

In the example code below, Feature Key 42 is passed and the User Identifier for the user whose state will be retrieved is "ae03e1adf".

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

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

// Determines the user's state for the Feature Flag with Feature Key 42.
// Returns false (off state) if a decision cannot be made.
val isFeatureOn: Boolean = hackleClient.isFeatureOn(42, "ae03e1adf")

if (isFeatureOn) {
    // ON feature
} else {
    // OFF feature
}
```

{% endtab %}

{% tab title="Java" %}

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

// Determines the user's state for the Feature Flag with Feature Key 42.
// Returns false (off state) if a decision cannot be made.
boolean isFeatureOn = hackleClient.isFeatureOn(42, "ae03e1adf");

if (isFeatureOn) {
    // ON feature
} else {
    // OFF feature
}
```

{% endtab %}
{% endtabs %}

## featureFlagDetail

The `featureFlagDetail()` method works the same as `isFeatureOn()` but additionally provides the reason for the state decision. This is useful for verifying that Override is working correctly or when the result proportion seems inconsistent with the configured Traffic Allocation.

You must pass the Feature Key as a parameter. In the example code below, Feature Key 42 is passed.

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

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

val decision: FeatureFlagDecision = hackleClient.featureFlagDetail(42, "ae03e1adf")

// Feature on/off status
val isFeatureOn: Boolean = decision.isOn()

// Decision reason
val reason: DecisionReason = decision.getReason()
```

{% endtab %}

{% tab title="Java" %}

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

FeatureFlagDecision decision = hackleClient.featureFlagDetail(42, "ae03e1adf");

// Feature on/off status
boolean isFeatureOn = decision.isOn();

// 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="233.71875">Decision Reason</th><th width="370.8046875">Description</th><th>Distribution Result</th></tr></thead><tbody><tr><td><code>SDK_NOT_READY</code></td><td>The SDK is not ready to use.<br>(e.g., initialization attempted with an invalid SDK Key)</td><td>Default state<br>(off)</td></tr><tr><td><code>FEATURE_FLAG_NOT_FOUND</code></td><td>No Feature Flag was found for the provided Feature Key.<br>The Feature Key may be incorrect, or the Feature Flag may be archived.</td><td>Default state<br>(off)</td></tr><tr><td><code>FEATURE_FLAG_INACTIVE</code></td><td>The Feature Flag is in the off state.</td><td>Default state<br>(off)</td></tr><tr><td><code>INDIVIDUAL_TARGET_MATCH</code></td><td>Matched by Individual Targeting.</td><td>State configured by<br>Individual Targeting</td></tr><tr><td><code>TARGET_RULE_MATCH</code></td><td>Matched by User Targeting.</td><td>State configured by User Targeting</td></tr><tr><td><code>DEFAULT_RULE</code></td><td>Did not match either Individual Targeting or User Targeting.</td><td>State configured by<br>default rule</td></tr><tr><td><code>EXCEPTION</code></td><td>An unknown error occurred.</td><td>Default state<br>(off)</td></tr></tbody></table>

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

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

## Feature Flag Parameters

* You can also receive the parameter values for the state decision through the `featureFlagDetail()` method.
* The `FeatureFlagDecision` instance returned by `featureFlagDetail()` contains a `ParameterConfig` object with the full parameter configuration.
* Since parameter values configured in the Hackle Feature Flag screen are stored as key-value pairs, use the methods below according to the parameter type to retrieve the configured values.
* You can dynamically update values in the Feature Flag parameter configuration screen.

### getString

* Returns parameter values configured as STRING or JSON type.
* Returns the value configured for False or True based on the state decision.

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

```kotlin
import io.hackle.sdk.HackleClient
import io.hackle.sdk.common.decision.FeatureFlagDecision
import io.hackle.sdk.common.ParameterConfig

val decision: FeatureFlagDecision = hackleClient.featureFlagDetail(42, "ae03e1adf")
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")
```

{% endtab %}

{% tab title="Java" %}

```java
import io.hackle.sdk.HackleClient
import io.hackle.sdk.common.decision.FeatureFlagDecision
import io.hackle.sdk.common.ParameterConfig

FeatureFlagDecision decision = hackleClient.featureFlagDetail(42, "ae03e1adf");
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");
```

{% endtab %}
{% endtabs %}

### getInt

* Returns parameter values configured as Number type as an Int.
* Returns the value configured for False or True based on the state decision.

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

```kotlin
import io.hackle.sdk.HackleClient
import io.hackle.sdk.common.decision.FeatureFlagDecision
import io.hackle.sdk.common.ParameterConfig

val decision: FeatureFlagDecision = hackleClient.featureFlagDetail(42, "ae03e1adf")
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)
```

{% endtab %}

{% tab title="Java" %}

```java
import io.hackle.sdk.HackleClient
import io.hackle.sdk.common.decision.FeatureFlagDecision
import io.hackle.sdk.common.ParameterConfig

FeatureFlagDecision decision = hackleClient.featureFlagDetail(42, "ae03e1adf");
ParameterConfig config = decision.getConfig();

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

{% endtab %}
{% endtabs %}

### getDouble

* Returns parameter values configured as Number type as a Double.
* Returns the value configured for False or True based on the state decision.

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

```kotlin
import io.hackle.sdk.HackleClient
import io.hackle.sdk.common.decision.FeatureFlagDecision
import io.hackle.sdk.common.ParameterConfig

val decision: FeatureFlagDecision = hackleClient.featureFlagDetail(42, "ae03e1adf")
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)
```

{% endtab %}

{% tab title="Java" %}

```java
import io.hackle.sdk.HackleClient
import io.hackle.sdk.common.decision.FeatureFlagDecision
import io.hackle.sdk.common.ParameterConfig

FeatureFlagDecision decision = hackleClient.featureFlagDetail(42, "ae03e1adf");
ParameterConfig config = decision.getConfig();

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

{% endtab %}
{% endtabs %}

### getLong

* Returns parameter values configured as Number type as a Long.
* Returns the value configured for False or True based on the state decision.

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

```kotlin
import io.hackle.sdk.HackleClient
import io.hackle.sdk.common.decision.FeatureFlagDecision
import io.hackle.sdk.common.ParameterConfig

val decision: FeatureFlagDecision = hackleClient.featureFlagDetail(42, "ae03e1adf")
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)
```

{% endtab %}

{% tab title="Java" %}

```java
import io.hackle.sdk.HackleClient
import io.hackle.sdk.common.decision.FeatureFlagDecision
import io.hackle.sdk.common.ParameterConfig

FeatureFlagDecision decision = hackleClient.featureFlagDetail(42, "ae03e1adf");
ParameterConfig config = decision.getConfig();

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

{% endtab %}
{% endtabs %}

### getBoolean

* Returns parameter values configured as Boolean type.
* Returns the value configured for False or True based on the state decision.

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

```kotlin
import io.hackle.sdk.HackleClient
import io.hackle.sdk.common.decision.FeatureFlagDecision
import io.hackle.sdk.common.ParameterConfig

val decision: FeatureFlagDecision = hackleClient.featureFlagDetail(42, "ae03e1adf")
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" %}

```java
import io.hackle.sdk.HackleClient
import io.hackle.sdk.common.decision.FeatureFlagDecision
import io.hackle.sdk.common.ParameterConfig

FeatureFlagDecision decision = hackleClient.featureFlagDetail(42, "ae03e1adf");
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-feature-flag.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.
