SDK User Context Reference
Overview
Section titled “Overview”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.
Creating a user context
Section titled “Creating a user context”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,
}); 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 },
}); 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,
}) Parameters
Section titled “Parameters”| Parameter | Type | Required | Description |
|---|---|---|---|
userId | string | Yes | A unique identifier for the user. Must be consistent across sessions for sticky bucketing. |
attributes | object / Dictionary | No | A map of attribute names to values. Used by audience conditions in the Optimizely app. Supported types: string, number, boolean. |
Attribute guidelines
Section titled “Attribute guidelines”- 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, passageas 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.
Methods
Section titled “Methods”decide
Section titled “decide”Evaluates a feature flag for this user. See the decide() method reference for full details.
user.decide(flagKey, options?)decideForKeys
Section titled “decideForKeys”Evaluates multiple feature flags in a single call. Returns a map of flag keys to decision objects.
const decisions = user.decideForKeys(
['checkout_redesign', 'hero_banner', 'pricing_test']
);
for (const [flagKey, decision] of Object.entries(decisions)) {
console.log(`${flagKey}: enabled=${decision.enabled}`);
} var decisions = user.DecideForKeys(
new[] { "checkout_redesign", "hero_banner", "pricing_test" }
);
foreach (var (flagKey, decision) in decisions)
{
Console.WriteLine($"{flagKey}: enabled={decision.Enabled}");
} 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}') decideAll
Section titled “decideAll”Evaluates every feature flag in the project for this user. Use ENABLED_FLAGS_ONLY to filter the results.
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`); var enabledFlags = user.DecideAll(new[]
{
OptimizelyDecideOption.ENABLED_FLAGS_ONLY,
});
Console.WriteLine($"User has {enabledFlags.Count} active features"); 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') trackEvent
Section titled “trackEvent”Sends a conversion event for this user. Events must be created in the Optimizely app before tracking them.
// 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
}); // 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" },
}); # 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',
}) | Parameter | Type | Required | Description |
|---|---|---|---|
eventKey | string | Yes | The event key as defined in the Optimizely app. |
eventTags | object / Dictionary | No | A 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. |
setForcedDecision
Section titled “setForcedDecision”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.
// 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' // 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" 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' | Parameter | Type | Required | Description |
|---|---|---|---|
context | OptimizelyDecisionContext | Yes | Identifies the flag (and optionally the rule) to force. Contains flagKey and optional ruleKey. |
forcedDecision | OptimizelyForcedDecision | Yes | The variation to force. Contains variationKey. |
removeForcedDecision
Section titled “removeForcedDecision”Removes a forced decision for a specific flag or flag-rule pair.
// 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' }
); user.RemoveForcedDecision(
new OptimizelyDecisionContext("checkout_redesign")
);
user.RemoveForcedDecision(
new OptimizelyDecisionContext("checkout_redesign", "experiment_1")
); user.remove_forced_decision(
OptimizelyUserContext.OptimizelyDecisionContext(
flag_key='checkout_redesign'
)
) removeAllForcedDecisions
Section titled “removeAllForcedDecisions”Clears all forced decisions on the user context. Call this to return to normal evaluation after QA testing.
// Clear all forced decisions
user.removeAllForcedDecisions();
// Future decide calls use normal evaluation
const decision = user.decide('checkout_redesign'); user.RemoveAllForcedDecisions();
var decision = user.Decide("checkout_redesign"); user.remove_all_forced_decisions()
decision = user.decide('checkout_redesign') User ID strategies
Section titled “User ID strategies”The user ID you pass to createUserContext determines how users are bucketed. Choose a strategy that matches your use case:
| Strategy | Example ID | Best 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.