---
title: OptimizelyConfig for the C# SDK
slug: feature-experimentation/docs/optimizelyconfig-csharp
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.

```csharp
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
- Function to retrieve the project configuration (the datafile)

:::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 ensure multiple SDK instances use the same configuration, such as in a client or server scenario, pass a JSON string of the config (the datafile) between them. 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`:

```csharp
// OptimizelyConfig is class describing the current project configuration data being used by this SDK instance.
 public class OptimizelyConfig
 {
   public string Revision { get; private set; }
   public string SDKKey { get; private set; }
   public string EnvironmentKey { get; private set; }
   public OptimizelyEvent[] Events { get; private set; }
   public OptimizelyAudience[] Audiences { get; private set; }
   public OptimizelyAttribute[] Attributes { get; private set; }
   
   // 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.
   public IDictionary<string, OptimizelyExperiment> ExperimentsMap { get; private set; }
   
   public IDictionary<string, OptimizelyFeature> FeaturesMap { get; private set; }
   public string GetDatafile { get; private set; }
 }

// Entity.IdKeyEntity is an abstract class used for inheritance in OptimizelyExperiment, OptimizelyFeature, OptimizelyVariation and OptimizelyVariable classes.
public abstract class IdKeyEntity : Entity, IEquatable<object>
{
  public string Id { get; set; }
  public string Key { get; set; }
}

// OptimizelyAttribute is a class describing attribute and inherited from Entity.IdKeyEntity.
public class OptimizelyAttribute : Entity.IdKeyEntity
{
}

// OptimizelyAudience is a class describing an audience.
public class OptimizelyAudience
{
  public string Id { get; set; }
  public string Name { get; set; }
  public object Conditions { get; set; }
}

// OptimizelyEvent is a class describing an event and inherited from Entity.IdKeyEntity.
public class OptimizelyEvent : Entity.IdKeyEntity
{
  public string[] ExperimentIds { get; set; }
}

// OptimizelyFeature is a class describing a feature flag and inherited from Entity.IdKeyEntity.
public class OptimizelyFeature : Entity.IdKeyEntity
{
  
  public List<OptimizelyExperiment> ExperimentRules { get; private set; }
  public List<OptimizelyExperiment> DeliveryRules { get; private set; }
  public IDictionary<string, OptimizelyVariable> VariablesMap { get; private set; }
  
  [Obsolete("Use experimentRules and deliveryRules.")]
  public IDictionary<string, OptimizelyExperiment> ExperimentsMap { get; private set; }
}

// OptimizelyExperiment is a class describing an experiment and inherited from Entity.IdKeyEntity.
public class OptimizelyExperiment : Entity.IdKeyEntity
{
  public IDictionary<string, OptimizelyVariation> VariationsMap { get; private set; }
  public string Audiences { get; private set; }
}

// OptimizelyVariation is a class describing a variation in an experiment and inherited from Entity.IdKeyEntity.
public class OptimizelyVariation : Entity.IdKeyEntity
{
  [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
  public bool? FeatureEnabled { get; private set; }
  public IDictionary<string, OptimizelyVariable> VariablesMap { get; private set; }
}

// OptimizelyVariable is a class describing a feature flag variable and inherited from Entity.IdKeyEntity.
public class OptimizelyVariable : Entity.IdKeyEntity
{
  public string Type { get; private set; }
  public string Value { get; private set; }
}
```

## Examples

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

```csharp
var optimizelyConfig = optimizely.GetOptimizelyConfig();

// Get the revision
Console.WriteLine($"[OptimizelyConfig] revision:{optimizelyConfig.Revision}");

// Get the SDK key
Console.WriteLine($"[OptimizelyConfig] SDKKey:{optimizelyConfig.SDKKey}");

// Get the environment key
Console.WriteLine($"[OptimizelyConfig] environmentKey:{optimizelyConfig.EnvironmentKey}");

// All attributes
Console.WriteLine("[OptimizelyConfig] attributes:");
var attributes = optimizelyConfig.Attributes;
foreach (var attribute in attributes)
{
    Console.WriteLine(
        $"[OptimizelyAttribute]   -- (id, key) = (({attribute.Id}), ({attribute.Key}))");
}

// All audiences
Console.WriteLine("[OptimizelyConfig] audiences:");
var audiences = optimizelyConfig.Audiences;
foreach (var audience in audiences)
{
    Console.WriteLine(
        $"[OptimizelyAudience]   -- (id, name, conditions) = (({audience.Id}), ({audience.Name}), ({audience.Conditions}))");

    // use audience data here.
}

// All events
Console.WriteLine("[OptimizelyConfig] events:");
var events = optimizelyConfig.Events;
foreach (var _event in events)
{
    Console.WriteLine(
        $"[OptimizelyEvent]   -- (id, key, experimentIds) = (({_event.Id}), ({_event.Key}), ({_event.ExperimentIds}))");

    // use event data here.
}

// All flags
var flags = optimizelyConfig.FeaturesMap.Values;
foreach (var flag in flags)
{
    // use experiment rules and delivery rules and other flag data here...
    var experimentRules = flag.ExperimentRules;
    foreach (var experimentRule in experimentRules)
    {
        Console.WriteLine($"[OptimizelyExperiment]   - experiment rule-key = {experimentRule.Key}");
        Console.WriteLine(
            $"[OptimizelyExperiment]   - experiment audiences = {experimentRule.Audiences}");

        // all variations
        var variations = experimentRule.VariationsMap.Values;
        foreach (var variation in variations)
        {
            Console.WriteLine(
                $"[OptimizelyVariation]       -- variation = {{ key: {variation.Key}, id: {variation.Id}, featureEnabled: {variation.FeatureEnabled} }}");

            var variables = variation.VariablesMap.Values;
            foreach (var variable in variables)
            {
                Console.WriteLine(
                    $"[OptimizelyVariable]           --- variable: {variable.Key}, {variable}");
                
                // use variable data here.
            }

            // use experimentRule data here.
        }

    }

    var deliveryRules = flag.DeliveryRules;
    foreach (var deliveryRule in deliveryRules)
    {
        Console.WriteLine($"[OptimizelyExperiment]   - delivery rule-key = {deliveryRule.Key}");
        Console.WriteLine(
            $"[OptimizelyExperiment]   - delivery audiences = {deliveryRule.Audiences}");

        // use delivery rule data here.
    }

    // Listen to OPTIMIZELY_CONFIG_UPDATE to get updated data
    NotificationCenter.OptimizelyConfigUpdateCallback configUpdateListener = () =>
    {
        var config = optimizely.GetOptimizelyConfig();
        Console.WriteLine($"[OptimizelyConfig] revision = {config?.Revision}");
    };
    optimizely.NotificationCenter.AddNotification(
        NotificationCenter.NotificationType.OptimizelyConfigUpdate, configUpdateListener);
}
```
