Skip to content

SDK User Context Reference

intermediate

OptimizelyUserContext represents a user in the Optimizely SDK. It holds the user ID and attributes, provides methods for making feature decisions, and supports forced decisions for testing. You create a user context from the Optimizely client and then call decide on it.

Every decision requires a user context. The context ties together the user’s identity, their attributes (used for audience targeting), and any forced decisions you set for testing.

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

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

// Minimal — user ID only
const user = optimizely.createUserContext('user-42');

// With attributes for audience targeting
const userWithAttrs = optimizely.createUserContext('user-42', {
  plan: 'enterprise',
  country: 'US',
  age: 34,
  beta_user: true,
});
csharp
using OptimizelySDK;

var optimizely = OptimizelyFactory.NewDefaultInstance("YOUR_SDK_KEY");

// Minimal — user ID only
var user = optimizely.CreateUserContext("user-42");

// With attributes for audience targeting
var userWithAttrs = optimizely.CreateUserContext("user-42",
    new UserAttributes
    {
        { "plan", "enterprise" },
        { "country", "US" },
        { "age", 34 },
        { "beta_user", true },
    });
python
from optimizely import optimizely

client = optimizely.Optimizely(sdk_key='YOUR_SDK_KEY')

# Minimal — user ID only
user = client.create_user_context('user-42')

# With attributes for audience targeting
user_with_attrs = client.create_user_context('user-42', {
    'plan': 'enterprise',
    'country': 'US',
    'age': 34,
    'beta_user': True,
})
ParameterTypeRequiredDescription
userIdstringYesA unique identifier for the user. Must be consistent across sessions for sticky bucketing.
attributesobject / DictionaryNoA map of attribute names to values. Used by audience conditions in the Optimizely app. Supported types: string, number, boolean.
  • Attribute names must match the attribute keys defined in your Optimizely project under Audiences > Attributes.
  • Attribute values are type-sensitive. If your audience condition checks age > 25, pass age as a number, not a string.
  • Attributes you pass that are not defined in the project are silently ignored.
  • You can pass as many attributes as needed. Only attributes referenced by active audience conditions affect bucketing.

Evaluates a feature flag for this user. See the decide() method reference for full details.

user.decide(flagKey, options?)

Evaluates multiple feature flags in a single call. Returns a map of flag keys to decision objects.

decideForKeys
javascript
const decisions = user.decideForKeys(
  ['checkout_redesign', 'hero_banner', 'pricing_test']
);

for (const [flagKey, decision] of Object.entries(decisions)) {
  console.log(`${flagKey}: enabled=${decision.enabled}`);
}
csharp
var decisions = user.DecideForKeys(
    new[] { "checkout_redesign", "hero_banner", "pricing_test" }
);

foreach (var (flagKey, decision) in decisions)
{
    Console.WriteLine($"{flagKey}: enabled={decision.Enabled}");
}
python
decisions = user.decide_for_keys(
    ['checkout_redesign', 'hero_banner', 'pricing_test']
)

for flag_key, decision in decisions.items():
    print(f'{flag_key}: enabled={decision.enabled}')

Evaluates every feature flag in the project for this user. Use ENABLED_FLAGS_ONLY to filter the results.

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

// Get all enabled flags for this user
const enabledFlags = user.decideAll([
  OptimizelyDecideOption.ENABLED_FLAGS_ONLY,
]);

console.log(`User has ${Object.keys(enabledFlags).length} active features`);
csharp
var enabledFlags = user.DecideAll(new[]
{
    OptimizelyDecideOption.ENABLED_FLAGS_ONLY,
});

Console.WriteLine($"User has {enabledFlags.Count} active features");
python
from optimizely.decision.optimizely_decide_option import OptimizelyDecideOption

enabled_flags = user.decide_all([
    OptimizelyDecideOption.ENABLED_FLAGS_ONLY,
])

print(f'User has {len(enabled_flags)} active features')

Sends a conversion event for this user. Events must be created in the Optimizely app before tracking them.

trackEvent
javascript
// Track a simple event
user.trackEvent('purchase_completed');

// Track with event tags (revenue in cents, value as float)
user.trackEvent('purchase_completed', {
  revenue: 4999,    // $49.99 in cents
  value: 49.99,     // Numeric value for aggregation
  currency: 'USD',  // Custom tag
});
csharp
// Track a simple event
user.TrackEvent("purchase_completed");

// Track with event tags (revenue in cents, value as float)
user.TrackEvent("purchase_completed",
    new EventTags
    {
        { "revenue", 4999 },
        { "value", 49.99 },
        { "currency", "USD" },
    });
python
# Track a simple event
user.track_event('purchase_completed')

# Track with event tags (revenue in cents, value as float)
user.track_event('purchase_completed', event_tags={
    'revenue': 4999,
    'value': 49.99,
    'currency': 'USD',
})
ParameterTypeRequiredDescription
eventKeystringYesThe event key as defined in the Optimizely app.
eventTagsobject / DictionaryNoA map of tag names to values. revenue (integer, cents) and value (float) are reserved for Optimizely metrics. Custom tags are stored but not used in default reports.

Overrides the normal evaluation for a specific flag or flag-rule pair. Forces the user into a specific variation regardless of audience or traffic allocation. Use this for QA testing.

setForcedDecision
javascript
// Force a user into a specific variation for a flag
user.setForcedDecision(
  { flagKey: 'checkout_redesign' },
  { variationKey: 'variation_b' }
);

// Force a specific rule within a flag
user.setForcedDecision(
  { flagKey: 'checkout_redesign', ruleKey: 'experiment_1' },
  { variationKey: 'control' }
);

// Now decide returns the forced variation
const decision = user.decide('checkout_redesign');
console.log(decision.variationKey); // 'variation_b'
csharp
// Force a user into a specific variation for a flag
user.SetForcedDecision(
    new OptimizelyDecisionContext("checkout_redesign"),
    new OptimizelyForcedDecision("variation_b")
);

// Force a specific rule within a flag
user.SetForcedDecision(
    new OptimizelyDecisionContext("checkout_redesign", "experiment_1"),
    new OptimizelyForcedDecision("control")
);

var decision = user.Decide("checkout_redesign");
Console.WriteLine(decision.VariationKey); // "variation_b"
python
from optimizely.optimizely_user_context import OptimizelyUserContext

# Force a user into a specific variation for a flag
user.set_forced_decision(
    OptimizelyUserContext.OptimizelyDecisionContext(
        flag_key='checkout_redesign'
    ),
    OptimizelyUserContext.OptimizelyForcedDecision(
        variation_key='variation_b'
    )
)

decision = user.decide('checkout_redesign')
print(decision.variation_key)  # 'variation_b'
ParameterTypeRequiredDescription
contextOptimizelyDecisionContextYesIdentifies the flag (and optionally the rule) to force. Contains flagKey and optional ruleKey.
forcedDecisionOptimizelyForcedDecisionYesThe variation to force. Contains variationKey.

Removes a forced decision for a specific flag or flag-rule pair.

removeForcedDecision
javascript
// Remove the forced decision for a flag
user.removeForcedDecision(
  { flagKey: 'checkout_redesign' }
);

// Remove the forced decision for a specific rule
user.removeForcedDecision(
  { flagKey: 'checkout_redesign', ruleKey: 'experiment_1' }
);
csharp
user.RemoveForcedDecision(
    new OptimizelyDecisionContext("checkout_redesign")
);

user.RemoveForcedDecision(
    new OptimizelyDecisionContext("checkout_redesign", "experiment_1")
);
python
user.remove_forced_decision(
    OptimizelyUserContext.OptimizelyDecisionContext(
        flag_key='checkout_redesign'
    )
)

Clears all forced decisions on the user context. Call this to return to normal evaluation after QA testing.

removeAllForcedDecisions
javascript
// Clear all forced decisions
user.removeAllForcedDecisions();

// Future decide calls use normal evaluation
const decision = user.decide('checkout_redesign');
csharp
user.RemoveAllForcedDecisions();

var decision = user.Decide("checkout_redesign");
python
user.remove_all_forced_decisions()

decision = user.decide('checkout_redesign')

The user ID you pass to createUserContext determines how users are bucketed. Choose a strategy that matches your use case:

StrategyExample IDBest for
Authenticated user ID"user-42", "db-uuid-abc123"Logged-in users. Consistent across devices and sessions.
Session ID"sess-xyz789"Anonymous users. Bucketing is consistent within a session but not across sessions.
Device ID"device-a1b2c3"Mobile apps. Consistent on one device.
Cookie-based ID"opti-anon-id-from-cookie"Web applications. Persists across page loads via a first-party cookie.

For experiments, use the most stable identifier available. Inconsistent user IDs cause users to see different variations across sessions, which pollutes experiment results.