Skip to content

SDK Client Reference

intermediate

The Optimizely client is the entry point for the Feature Experimentation SDK. It downloads your project’s configuration (the datafile), manages the user profile service, dispatches events, and provides the createUserContext method that starts every feature decision.

You create one client instance per application lifecycle and reuse it for all decisions.

Creates and returns an Optimizely client configured with your SDK key. The client begins downloading the datafile immediately.

createInstance
javascript
import { createInstance } from '@optimizely/optimizely-sdk';

const optimizely = createInstance({
  sdkKey: 'YOUR_SDK_KEY',

  // Optional configuration
  datafileOptions: {
    autoUpdate: true,            // Poll for datafile changes
    updateInterval: 60_000,      // Poll every 60 seconds
  },
  eventBatchSize: 10,            // Batch up to 10 events
  eventFlushInterval: 30_000,    // Flush every 30 seconds
  eventMaxQueueSize: 10_000,     // Max queued events before dropping
});
csharp
using OptimizelySDK;

// Standard initialization
var optimizely = OptimizelyFactory.NewDefaultInstance(
    "YOUR_SDK_KEY"
);

// With custom configuration
var config = new OptimizelyConfig
{
    SdkKey = "YOUR_SDK_KEY",
    DatafileAutoUpdate = true,
    DatafileUpdateInterval = TimeSpan.FromSeconds(60),
    EventBatchSize = 10,
    EventFlushInterval = TimeSpan.FromSeconds(30),
};
var optimizely = OptimizelyFactory.NewDefaultInstance(config);
python
from optimizely import optimizely
from optimizely.config_manager import PollingConfigManager

# Standard initialization
client = optimizely.Optimizely(sdk_key='YOUR_SDK_KEY')

# With polling configuration
config_manager = PollingConfigManager(
    sdk_key='YOUR_SDK_KEY',
    update_interval=60,  # seconds
)
client = optimizely.Optimizely(
    config_manager=config_manager
)
OptionTypeDefaultDescription
sdkKeystring(required)Your SDK key from Settings > Environments in the Optimizely app.
datafileOptions.autoUpdatebooleanfalseWhen true, the SDK polls for datafile changes at the specified interval.
datafileOptions.updateIntervalnumber300000 (5 min)Polling interval in milliseconds. Minimum is 30000 (30 seconds).
eventBatchSizenumber10Number of events to batch before dispatching. Higher values reduce network calls.
eventFlushIntervalnumber30000Maximum time in milliseconds to hold events before flushing, even if the batch is not full.
eventMaxQueueSizenumber10000Maximum events to queue. Events beyond this limit are dropped.
defaultDecideOptionsOptimizelyDecideOption[][]Default decision options applied to every decide call. Individual calls can override these.

Returns a promise that resolves when the SDK has downloaded and parsed the datafile. In JavaScript, always await this before making decisions.

onReady
javascript
const optimizely = createInstance({ sdkKey: 'YOUR_SDK_KEY' });

// Wait with a timeout
const result = await optimizely.onReady({ timeout: 5000 });

if (result.success) {
  console.log('SDK ready — datafile loaded');
} else {
  console.warn('SDK timed out — using defaults');
  // decide() still works but returns default (off) decisions
}
csharp
// NewDefaultInstance blocks until the datafile is ready.
// No separate onReady call is needed in C#.
var optimizely = OptimizelyFactory.NewDefaultInstance("YOUR_SDK_KEY");

// The client is ready to use immediately after this line.
var user = optimizely.CreateUserContext("user-42");
python
# The Python SDK initializes synchronously.
# If using PollingConfigManager, the first fetch happens before returning.
client = optimizely.Optimizely(sdk_key='YOUR_SDK_KEY')

# Check if the config is valid
if client.config_manager.get_config() is not None:
    print('SDK ready')
else:
    print('Config not yet available')
ParameterTypeRequiredDescription
timeoutnumberNoMaximum time in milliseconds to wait for the datafile. If the datafile is not available within this window, the promise resolves with { success: false }. JavaScript only.
FieldTypeDescription
successbooleantrue if the datafile was loaded before the timeout.
reasonstringWhen success is false, describes why initialization failed (e.g., "TIMEOUT").

Creates an OptimizelyUserContext for making decisions. See the User Context reference for full details.

createUserContext
javascript
const user = optimizely.createUserContext('user-42', {
  plan: 'enterprise',
  country: 'US',
});
csharp
var user = optimizely.CreateUserContext("user-42",
    new UserAttributes
    {
        { "plan", "enterprise" },
        { "country", "US" },
    });
python
user = client.create_user_context('user-42', {
    'plan': 'enterprise',
    'country': 'US',
})

Returns a snapshot of the current project configuration. Use this for debugging or building admin interfaces that display the active datafile state.

getOptimizelyConfig
javascript
const config = optimizely.getOptimizelyConfig();

if (config) {
  console.log('Revision:', config.revision);
  console.log('SDK Key:', config.sdkKey);
  console.log('Environment:', config.environmentKey);

  // Iterate over feature flags
  for (const [key, feature] of Object.entries(config.featuresMap)) {
    console.log(`Flag: ${key}`);
    for (const [varKey, variable] of Object.entries(feature.variablesMap)) {
      console.log(`  Variable: ${varKey} = ${variable.value}`);
    }
  }
}
csharp
var config = optimizely.GetOptimizelyConfig();

if (config != null)
{
    Console.WriteLine($"Revision: {config.Revision}");
    Console.WriteLine($"SDK Key: {config.SdkKey}");

    foreach (var feature in config.FeaturesMap)
    {
        Console.WriteLine($"Flag: {feature.Key}");
        foreach (var variable in feature.Value.VariablesMap)
        {
            Console.WriteLine($"  Variable: {variable.Key} = {variable.Value.Value}");
        }
    }
}
python
config = client.get_optimizely_config()

if config:
    print(f'Revision: {config.revision}')
    print(f'SDK Key: {config.sdk_key}')

    for key, feature in config.features_map.items():
        print(f'Flag: {key}')
        for var_key, variable in feature.variables_map.items():
            print(f'  Variable: {var_key} = {variable.value}')
FieldTypeDescription
revisionstringThe datafile revision number. Increments with each publish in the Optimizely app.
sdkKeystringThe SDK key used to initialize the client.
environmentKeystringThe environment (e.g., "production", "development").
featuresMapMap<string, FeatureConfig>All feature flags with their variables and experiment rules.
attributesAttribute[]All custom attributes defined in the project.
eventsEvent[]All events defined in the project.
audiencesAudience[]All audiences defined in the project.

Shuts down the Optimizely client. Flushes any pending events, stops datafile polling, and releases resources. Call this when your application shuts down to avoid losing event data.

close
javascript
// Flush pending events and stop polling
await optimizely.close();
console.log('Optimizely client shut down');
csharp
// In a .NET 8+ application, call on shutdown
optimizely.Dispose();
Console.WriteLine("Optimizely client shut down");
python
# Flush pending events and stop polling
client.close()
print('Optimizely client shut down')

In web server applications, register the close call with your application’s shutdown hook:

Register shutdown hook (.NET 8+)
csharp
var builder = WebApplication.CreateBuilder(args);

// Register Optimizely as a singleton
var optimizely = OptimizelyFactory.NewDefaultInstance("YOUR_SDK_KEY");
builder.Services.AddSingleton(optimizely);

var app = builder.Build();

// Clean up on shutdown
app.Lifetime.ApplicationStopping.Register(() =>
{
    optimizely.Dispose();
});

app.Run();

Register callbacks that fire when the SDK makes decisions, dispatches events, or updates the datafile.

Notification listeners
javascript
import { NOTIFICATION_TYPES } from '@optimizely/optimizely-sdk';

// Listen for decision events
const listenerId = optimizely.notificationCenter.addNotificationListener(
  NOTIFICATION_TYPES.DECISION,
  (notification) => {
    console.log('Decision made:', {
      type: notification.type,
      userId: notification.userId,
      flagKey: notification.decisionInfo.flagKey,
      enabled: notification.decisionInfo.enabled,
    });
  }
);

// Listen for datafile updates
optimizely.notificationCenter.addNotificationListener(
  NOTIFICATION_TYPES.OPTIMIZELY_CONFIG_UPDATE,
  () => {
    console.log('Datafile updated — new config is active');
  }
);

// Remove a specific listener
optimizely.notificationCenter.removeNotificationListener(listenerId);

// Remove all listeners
optimizely.notificationCenter.clearAllNotificationListeners();
csharp
// Listen for decision events
optimizely.NotificationCenter.AddNotification(
    NotificationCenter.NotificationType.Decision,
    (notification) =>
    {
        Console.WriteLine($"Decision: {notification.Type}");
    });

// Listen for datafile updates
optimizely.NotificationCenter.AddNotification(
    NotificationCenter.NotificationType.OptimizelyConfigUpdate,
    () =>
    {
        Console.WriteLine("Datafile updated");
    });
python
from optimizely.notification_center import NotificationCenter

def on_decision(notification_type, args):
    print(f'Decision made: {args}')

client.notification_center.add_notification_listener(
    NotificationCenter.NOTIFICATION_TYPES.DECISION,
    on_decision
)

def on_config_update():
    print('Datafile updated')

client.notification_center.add_notification_listener(
    NotificationCenter.NOTIFICATION_TYPES.OPTIMIZELY_CONFIG_UPDATE,
    on_config_update
)
TypeWhen it firesPayload
DECISIONAfter every decide callDecision type, user ID, flag key, enabled state, variation key
LOG_EVENTWhen the SDK dispatches an event batchThe event payload being sent to Optimizely
OPTIMIZELY_CONFIG_UPDATEWhen the SDK detects a new datafile revisionNo payload — call getOptimizelyConfig to inspect the new config
TRACKAfter every trackEvent callEvent key, user ID, event tags

The Optimizely client is thread-safe. You can share a single instance across threads, goroutines, or async contexts. User context objects are not thread-safe — create a new user context per request or thread.