Optimizely will be sunsetting Full Stack Experimentation on July 29, 2024. See the recommended Feature Experimentation migration timeline and documentation.

Dev GuideAPI Reference
Dev GuideAPI ReferenceUser GuideGitHubNuGetDev CommunitySubmit a ticketLog In
GitHubNuGetDev CommunitySubmit a ticket


This topic describes how to get access to project configuration data within the datafile using OptimizelyConfig.


Full Stack SDKs open a well-defined set of public APIs, hiding all implementation details. However, some clients may need access to project configuration data within the datafile.

Extend the public APIs to define data models and access methods, which clients can use to access project configuration data.

OptimizelyConfig API

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

Get OptimizelyConfig

You can access OptimizelyConfig from OptimizelyClient (top-level) with this public API call:

Future<OptimizelyConfigResponse> getOptimizelyConfig();

getOptimizelyConfig returns an OptimizelyConfigResponse containing optimizelyConfig instance which includes:

  • environment key
  • SDK key
  • the datafile revision number
  • all experiments mapped by their key values
  • all attributes
  • all audiences
  • all events
  • feature flags mapped by their key values



When the system updates the SDK datafile (the client can add a notification listener for OPTIMIZELY_CONFIG_UPDATE to get notified), the client should call the method to get the updated OptimizelyConfig data. See examples below.

Get datafile

To share the same datafile between multiple SDK instances (for example, in a client/server scenario), you can pass a JSON string representation of the config (the datafile) between the instances. To get the datafile, use the OptimizelyConfig object's datafile key. For more information, see Sharing the datafile with multiple SDK implementations.

Object model

The following shows the object model for OptimizelyConfig:

// OptimizelyConfig is an object describing the current project configuration data
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;
  String? datafile;

// OptimizelyFeature is an object describing a feature flag
class OptimizelyFeature {
  final String? id;
  final String? key;
  final List<OptimizelyExperiment> deliveryRules;
  final List<OptimizelyExperiment> experimentRules;

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

// OptimizelyVariation is an object describing a variation
class OptimizelyVariation {
  final String? id;
  final String? key;
  final bool featureEnabled;
  final Map<String, OptimizelyVariable> variablesMap;

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

// OptimizelyAttribute is an object describing an Attribute
class OptimizelyAttribute {
  final String? id;
  final String? key;

// OptimizelyAudience is an object describing an Audience
class OptimizelyAudience {
  final String? id;
  final String? name;
  final String? conditions;

// OptimizelyEvent is an object describing an Event
class OptimizelyEvent {
  final String? id;
  final String? key;
  final List<String> experimentIds;


OptimizelyConfig can be accessed from OptimizelyClient (top-level) like this:

  var configResponse = await flutterSDK.getOptimizelyConfig();
  var optimizelyConfig = configResponse.optimizelyConfig!;

  print("Optimizely [OptimizelyConfig] revision = ${optimizelyConfig.revision}");
  print("Optimizely [OptimizelyConfig] sdkKey = ${optimizelyConfig.sdkKey}");
  print("Optimizely [OptimizelyConfig] environmentKey = ${optimizelyConfig.environmentKey}");

  print("Optimizely [OptimizelyConfig] attributes = ${optimizelyConfig.attributes}");
  var attributes = optimizelyConfig.attributes;
  for (var attribute in attributes) {
    print("Optimizely [OptimizelyAttribute]  -- (id, key) = ${attribute.id}, ${attribute.key}");

  print("Optimizely [OptimizelyConfig] audiences = ${optimizelyConfig.audiences}");
  var audiences = optimizelyConfig.audiences;
  for (var audience in audiences) {
    print("Optimizely [OptimizelyAudience]  -- (id, key, conditions) = ${audience.id}, ${audience.name}, ${audience.conditions.toString()}");

  print("Optimizely [OptimizelyConfig] events = ${optimizelyConfig.events}");
  var events = optimizelyConfig.events;
  for (var event in events) {
    print("Optimizely [OptimizelyEvent]  -- (id, key, experimentIds) = ${event.id}, ${event.key}, ${event.experimentIds.toString()}");

// all features
  var featuresMap = optimizelyConfig.featuresMap;
  for (var flagKey in featuresMap.keys) {
    var flag = featuresMap[flagKey];
    var experimentRules = flag?.experimentRules;
    for (var experiment in experimentRules!) {
      print("Optimizely [OptimizelyExperiment]  -- Experiment Rule Key: ${experiment.key}");
      print("Optimizely [OptimizelyExperiment]  -- Experiment Audiences: ${experiment.audiences}");

      var variationsMap = experiment.variationsMap;
      for (var variationKey in variationsMap.keys) {
        var variation = variationsMap[variationKey];
        print("Optimizely [OptimizelyVariation]    -- variation = { key: ${variationKey}, id: ${variation?.id}, featureEnabled: ${variation?.featureEnabled}");
        // use variation data here...

        var optimizelyVariableMap = variation?.variablesMap;
        for (var variableKey in optimizelyVariableMap!.keys) {
          var variable = optimizelyVariableMap[variableKey];
          print("Optimizely [OptimizelyVariable]      -- variable = key: ${variableKey}, value: ${variable!.value}");
          // use variable data here...

  var deliveryRules = flag!.deliveryRules;
  for (var delivery in deliveryRules) {
    print("Optimizely [OptimizelyExperiment]  -- Delivery Rule Key: ${delivery.key}");
    print("Optimizely [OptimizelyExperiment]  -- Delivery Audiences: ${delivery.audiences.toString()}");

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

// listen to OPTIMIZELY_CONFIG_UPDATE to get updated data
flutterSDK.addUpdateConfigNotificationListener((msg) {
  var newConfig = flutterSDK.getOptimizelyConfig();