---
title: OptimizelyConfig for the Android SDK
slug: feature-experimentation/docs/optimizelyconfig-android
docTags: 
createdAt: 2026-08-05T20:39:55.000Z
---

Optimizely Feature Experimentation SDKs open a well-defined set of public APIs, hiding implementation details. However, you may need access to project configuration data within the [datafile](docId:3LmHm4b3kTxKBuoR93KN8). The following section extends the public APIs to define data models and access methods, which you can use to access project configuration data.

A public configuration data model (OptimizelyConfig) is defined as a structured format of static Optimizely Project data.

### Get `OptimizelyConfig`

You can access `OptimizelyConfig` through the `OptimizelyClient` (top-level) using this public API call.

```java
public OptimizelyConfig getOptimizelyConfig();
```

`getOptimizelyConfig` returns an `OptimizelyConfig` instance, which includes the following:

- Environment key
- SDK key
- Datafile revision number
- Experiments mapped by key values
- All attributes
- All audiences
- All events
- Feature flags mapped by key values

:::hint{type="info"}
When the system updates the datafile, you can add a [OptimizelyConfigUpdate notification listener](#)  to get notified. After receiving the notification, call the method to get the updated `OptimizelyConfig` data.
:::

### Get datafile

To share the same datafile between multiple SDK instances, such as in a client and server scenario, pass a JSON string representation of the config (the datafile) between instances. To get the datafile, use the `OptimizelyConfig` object's `getDatafile` method. For information, see [Sharing the datafile with multiple SDK implementations](docId\:eH-UMm_rOn_GdGDGLV6__).

### Object model

The following sample shows the object model for `OptimizelyConfig`:

```java
// OptimizelyConfig is an object describing the current project configuration data 
public class OptimizelyConfig {
  
    // This experimentsMap is for experiments of legacy projects only.
    // For flag projects, experiment keys are not guaranteed to be unique 
    // across multiple flags, so this map may not include all experiments 
    // when keys conflict.
    Map<String, OptimizelyExperiment> experimentsMap;
  
    Map<String, OptimizelyFeature> featuresMap;
    List<OptimizelyAttribute> attributes;
    List<OptimizelyEvent> events;
    List<OptimizelyAudience> audiences;
    String revision;
    String sdkKey;
    String environmentKey;
}

// OptimizelyFeature is an object describing a feature flag
public class OptimizelyFeature {
    String id;
    String key;
  
    /**
     * @deprecated use {@link #experimentRules} and {@link #deliveryRules} instead
     */
    @Deprecated
    Map<String, OptimizelyExperiment> experimentsMap;
  
    Map<String, OptimizelyVariable> variablesMap;
    List<OptimizelyExperiment> experimentRules;
    List<OptimizelyExperiment> deliveryRules;
}

// OptimizelyExperiment is an object describing an experiment
public class OptimizelyExperiment {
    String id;
    String key;
    String audiences;
    Map<String, OptimizelyVariation> variationsMap;
}

// OptimizelyVariation is an object describing a variation
public class OptimizelyVariation {
    String id;
    String key;
    Boolean featureEnabled;
    Map<String, OptimizelyVariable> variablesMap;
}

// OptimizelyVariable is an object describing a Variable
public class OptimizelyVariable {
    String id;
    String key;
    String type;
    String value;
}

// OptimizelyAttribute is an object describing an Attribute
public class OptimizelyAttribute {
  String id;
  String key;
}

// OptimizelyAudience is an object describing an Audience
public class OptimizelyAudience {
  String id;
  String name;
  String conditions;
}

// OptimizelyEvent is an object describing an Event
public class OptimizelyEvent {
  String id;
  String key;
  List<String> experimentIds;
}
```

## Examples

You can access `OptimizelyConfig` from the `OptimizelyClient` (top-level) using the following code examples:

```kotlin
val config = optimizelyClient.optimizelyConfig
            
Log.d("Optimizely", "[OptimizelyConfig] revision = " + config!!.revision)
Log.d("Optimizely", "[OptimizelyConfig] sdkKey = " + config.sdkKey)
Log.d("Optimizely", "[OptimizelyConfig] environmentKey = " + config.environmentKey)

Log.d("Optimizely", "[OptimizelyConfig] attributes:")
for (attribute in config.attributes) {
    Log.d("Optimizely", "[OptimizelyAttribute]  -- (id, key) = " + attribute.id + ", " + attribute.key)
}
            
Log.d("Optimizely", "[OptimizelyConfig] audiences:")
for (audience in config.audiences) {
    Log.d("Optimizely", "[OptimizelyAudience]  -- (id, name, conditions) = " + audience.id + ", " + audience.name + ", " + audience.conditions)
}
            
Log.d("Optimizely", "[OptimizelyConfig] events:")
for (event in config.events) {
    Log.d("Optimizely", "[OptimizelyEvent]  -- (id, key, experimentIds) = " + event.id + ", " + event.key + ", " + Arrays.toString(event.experimentIds.toTypedArray()))
}

// all features
for (flagKey in config.featuresMap.keys) {
    val flag = config.featuresMap.get(flagKey)!!
                
    for (experiment in flag.experimentRules) {
        Log.d("Optimizely", "[OptimizelyExperiment]  -- Experiment Rule Key: " + experiment.key)
        Log.d("Optimizely", "[OptimizelyExperiment]  -- Experiment Audiences: " + experiment.audiences)
 
        val variationsMap = experiment.variationsMap
        for (variationKey in variationsMap.keys) {
            val variation = variationsMap.get(variationKey)!!
            Log.d("Optimizely", "[OptimizelyVariation]    -- variation = { key: " + variationKey + ", id: " + variation.id + ", featureEnabled: " + variation.featureEnabled + " }")
            // use variation data here...
                        
            val optimizelyVariableMap = variation.variablesMap
            for (variableKey in optimizelyVariableMap.keys) {
                val variable = optimizelyVariableMap.get(variableKey)!!
                Log.d("Optimizely", "[OptimizelyVariable]      -- variable = key: " + variableKey + ", value: " + variable.value)
                // use variable data here...
                            
            }
        }
    }

    for (delivery in flag.deliveryRules) {
        Log.d("Optimizely", "[OptimizelyExperiment]  -- Delivery Rule Key: " + delivery.key)
        Log.d("Optimizely", "[OptimizelyExperiment]  -- Delivery Audiences: " + delivery.audiences)
    }

    // use experiments and other feature flag data here...

}

// listen to OPTIMIZELY_CONFIG_UPDATE to get updated data
optimizelyClient.notificationCenter?.addNotificationHandler(
    UpdateConfigNotification::class.java,
    NotificationHandler { handler: UpdateConfigNotification? ->
        val newConfig = optimizelyClient.optimizelyConfig
    }
)
```

```java
OptimizelyConfig config = optimizelyClient.getOptimizelyConfig();

Log.d("Optimizely", "[OptimizelyConfig] revision = " + config.getRevision());
Log.d("Optimizely", "[OptimizelyConfig] sdkKey = " + config.getSdkKey());
Log.d("Optimizely", "[OptimizelyConfig] environmentKey = " + config.getEnvironmentKey());

Log.d("Optimizely", "[OptimizelyConfig] attributes:");
for (OptimizelyAttribute attribute: config.getAttributes()) {
  Log.d("Optimizely", "[OptimizelyAttribute]  -- (id, key) = " + attribute.getId() + ", " + attribute.getKey());
}

Log.d("Optimizely", "[OptimizelyConfig] audiences:");
for (OptimizelyAudience audience: config.getAudiences()) {
  Log.d("Optimizely", "[OptimizelyAudience]  -- (id, name, conditions) = " + audience.getId() + ", " +  audience.getName() + ", " + audience.getConditions());
}

Log.d("Optimizely", "[OptimizelyConfig] events:");
for (OptimizelyEvent event: config.getEvents()) {
  Log.d("Optimizely", "[OptimizelyEvent]  -- (id, key, experimentIds) = " + event.getId() + ", "  + event.getKey() + ", "  + Arrays.toString(event.getExperimentIds().toArray()));
}

// all features
for (String flagKey: config.getFeaturesMap().keySet()) {
  OptimizelyFeature flag = config.getFeaturesMap().get(flagKey);

  for (OptimizelyExperiment experiment: flag.getExperimentRules()) {
    Log.d("Optimizely", "[OptimizelyExperiment]  -- Experiment Rule Key: " + experiment.getKey());
    Log.d("Optimizely", "[OptimizelyExperiment]  -- Experiment Audiences: " + experiment.getAudiences());

    Map<String, OptimizelyVariation> variationsMap = experiment.getVariationsMap();
    for (String variationKey: variationsMap.keySet()) {
      OptimizelyVariation variation = variationsMap.get(variationKey);
      Log.d("Optimizely", "[OptimizelyVariation]    -- variation = { key: " + variationKey + ", id: " + variation.getId() + ", featureEnabled: " + variation.getFeatureEnabled() + " }");
      // use variation data here...

      Map<String, OptimizelyVariable> optimizelyVariableMap = variation.getVariablesMap();
      for (String variableKey: optimizelyVariableMap.keySet()) {
        OptimizelyVariable variable = optimizelyVariableMap.get(variableKey);
        Log.d("Optimizely", "[OptimizelyVariable]      -- variable = key: " + variableKey + ", value: " + variable.getValue());
        // use variable data here...

      }
    }

  }

  for (OptimizelyExperiment delivery: flag.getDeliveryRules()) {
    Log.d("Optimizely", "[OptimizelyExperiment]  -- Delivery Rule Key: " + delivery.getKey());
    Log.d("Optimizely", "[OptimizelyExperiment]  -- Delivery Audiences: " + delivery.getAudiences());
  }

  // use experiments and other feature flag data here...

}

// listen to OPTIMIZELY_CONFIG_UPDATE to get updated data
optimizelyClient.getNotificationCenter().addNotificationHandler(UpdateConfigNotification.class, handler -> {
  OptimizelyConfig newConfig = optimizelyClient.getOptimizelyConfig();
});
```
