Optimizely X Destination

This destination is currently in beta. If you are interested in joining, let us know!

Segment makes it easy to send your data to Optimizely X (and lots of other destinations). Once you've tracked your data through our open source libraries we'll translate and route your data to Optimizely X in the format they understand.

Getting Started

Optimizely X works differently than other integrations. When enabling this destination for mobile and to ensure that it is initialized as soon as possible, you will have to hard-code your Optimizely X project ID on initialization.

Because using Optimizely X via Segment requires familiarity with Optimizely’s native SDKs, we encourage you to review their documentation.


Optimizley does provide different ways to initialize the client, however, Segment only supports initializing with the Optimizely Manager. The Optimizely Manager continuously checks for any updates made via the Optimizely UI and updates the cdn periodically with those changes.

In the unlikely scenario the Optimizely Client is slow to initialize, Segment automatically queues up to 100 events and polls the client asynchronously, flushing all events once a valid client is returned.

Initializing Optimizely synchronously with a manual or cached datafile would require more work on your end to keep the datafile up to date. Given that we queue events in memory before Segment is initialized, you can initialize Optimizely X synchronously and independently of Segment if you so choose. Just remember that we’ll only queue up to 100 events in memory, and only flush them once Optimizely X is finally initialized.


To get started on Android, initialize the OptimizelyManager class in your app’s Application subclass. Before you can import the OptimizelyManager class, you must first include Optimizely X’s native SDK in your your app-level build.gradle file: compile 'com.optimizely.ab:android-sdk:+'. Then, pass the Manager instance to Segment’s Optimizely X integration factory.

Here’s a code example of what your application subclass could look like.

import com.segment.analytics.android.integrations.optimizelyx.OptimizelyXIntegration;
import com.optimizely.ab.android.sdk.OptimizelyManager;

public class OptimizelyApp extends Application {

    private static final String WRITE_KEY = "<YOUR_WRITE_KEY>";
    public static final String PROJECT_ID = "<YOUR_PROJECT_ID>";
    private OptimizelyManager optimizelyManager;

    public OptimizelyManager getOptimizelyManager() {
        return optimizelyManager;

    public void onCreate() {

        optimizelyManager = OptimizelyManager.builder(PROJECT_ID)

        optimizelyManager.initialize(this, new OptimizelyStartListener() {
            public void onStart(OptimizelyClient optimizely) {
                assert optimizely == optimizelyManager.getOptimizely();

                Analytics analytics = new Analytics.Builder(OptimizelyApp.this, WRITE_KEY) //


Here, initializing Segment in Optimizely’s onStart callback is non-blocking since Optimizely returns a dummy OptimizelyClient if a valid client cannot be initialized immediately.


To get started on iOS, initialize the OPTLYManager and provide this to the Segment Optimizely-X Integration.

    SEGAnalyticsConfiguration *configuration = [SEGAnalyticsConfiguration configurationWithWriteKey:@"<YOUR_WRITE_KEY>"];

    // Initialize an Optimizely manager
    self.optlyManager = [OPTLYManager init:^(OPTLYManagerBuilder *_Nullable builder) {
        builder.projectId = @"<YOUR_PROJECT_ID";

    // Provide the OPTLYManager to SEGOptimizelyXIntegrationFactory
    [configuration use:[SEGOptimizelyXIntegrationFactory instanceWithOptimizely:self.optlyManager]];
    [SEGAnalytics setupWithConfiguration:configuration];

    // Initialize an Optimizely client by asynchronously downloading the datafile
    [self.optlyManager initializeWithCallback:^(NSError *_Nullable error, OPTLYClient *_Nullable client) {
        // Activate user in an experiment
        OPTLYVariation *variation = [client activate:@"<YOUR_VARIATION>" userId:@"<USER_ID>"];
        if ([variation.variationKey isEqualToString:@"variation1"]) {
          // execute code for variation1
        } else if ([variation.variationKey isEqualToString:@"variation2"]) {
          // execute code for variation2
        } else {
          // execute default code

Note that if there are any delays to the Optimizely Client being initialized, the activate method may fail. You will want to consider wrapping the variation logic around a condition to check if Optimizely has been initialized.

Server Side

If you have entered your Account ID and Datafile URL in your destination settings, you can start sending server side events. Assuming you have called Optimizely’s own .activate() method else where in your codebase for a given userId and an Optimizely experiment, if you send conversion events to Segment, we will use the Optimizely’s Node SDK to send them to your project. Because we use Optimizely’s official Node SDK, each event will be sent with its attributed Optimizely variation IDs via what they call decisions.

NOTE: The server side integration only maps to your .track() event. However, if you would like to send custom user attributes you can send user traits under context.traits and we will forward those along with your events.

IMPORTANT: Note that before you can send Optimizely X events via server side, you MUST pre-create/define them inside Optimizely’s UI. The event name or key are case sensitive so please heed close attention and make sure what you create inside Optimizely and the event name syntax you are sending to Segment are equal. This requirement also applies to when you try to send context.traits. Make sure you pre-create/define these custom attributes inside Optimizely when you create your custom audiences.


When you call identify, Segment stores any user traits in memory and passes them to Optimizely as attributes when you call track using Segment’s API. Optimizely will reject any attributes you haven’t defined within their dashboard first, so be sure to set these up in advance of deploying your app with Optimizely X enabled. You can use attributes to define audience segments in your Optimizely dashboard.


Segment maps our own track events to Optmizely track events. We will pass traits set via Segment identify calls as attributes and track event properties as eventTags.

Optimizely eventTags are contextual metadata about conversion events that you track and are accessible via raw data export in Optimizely’s event_features column. Please contact Optimizely’s support team for more information on how to access and manipulate eventTags.

By default, the integration will use anonymous ID as the ID passed to OptimizelyX but you can turn the setting ‘Use User ID’ on to use user ID instead. The integration cannot use user ID and fall back to anonymous ID as Optimizely X does not currently support identity resolution.


Invalidates the listener for the Experiment Viewed event.


To pass revenue to Optimizely, simply pass a property in your Segment track call with key revenue.


Sending Experiment Data to Segment

A key feature of our Optimizely destination is the ability to send your experiment data back into Segment so that you can analyze them in your other analytics providers. In your Optimizely settings, you can opt to choose to send experiment data via track.

Track Experiment Event

The corresponding event will look something like this in your Segment debugger:


analytics.track("Experiment Viewed", new Properties()
    .putValue("experimentId", "1234567890")
    .putValue("experimentName", "android_experiment")
    .putValue("nonInteraction", 1)
    .putValue("variationId", "0987654321")
    .putValue("variationName", "variation_name"));


[[SEGAnalytics sharedAnalytics] track:@"Experiment Viewed", properties: @{
    @"experimentId" : @"8734392016",
    @"experimentName" : @"variation_view",
    @"nonInteraction" : @1,
    @"variationId" : @"8729081299",
    @"variationName" : @"variation1"

Segment sends an Experiment Viewed event whenever you activate an Optimizely experiment, or whenever you access an Optimizely live variable.

If you’d prefer not to trigger an Experiment Viewed event each time you access a live variable, you can simply pass the false flag when you get your variable.


Boolean myVariable = optimizelyClient.getVariableBoolean("myVariable",


bool myVariable = [optimizely variableBoolean:@"myVariable"

nonInteraction Property

By default, Segment adds a nonInteraction property to your Experiment Viewed events to prevent creating new sessions in Google Analytics. If you don’t use Google Analytics, or if you’d prefer that we don’t append this property, you can disable this in your destination settings.

nonInteraction Setting


You can send computed traits and audiences generated through Segment Personas to this destination as a user property. To learn more about Personas, reach out for a demo.

For user-property destinations, an identify call will be sent to the destination for each user being added and removed. The property name will be the snake_cased version of the audience name you provide with a true/false value. For example, when a user first completes an order in the last 30 days, we will send an identify call with the property order_completed_last_30days: true, and when this user no longer satisfies we will set that value to false.

When the audience is first created an identify call is sent for every user in the audience. Subsequent syncs will only send updates for those users which were added or removed since the last sync.

Supported Sources and Connection Modes

📱 Device-based
☁️ Cloud-based

To learn more about about Connection Modes and what dictates which we support, see here.

Segment offers an optional Device-based Connection Mode for Mobile data with Optimizely X. If you’d like to use those features that require client-based functionality, follow the steps above to ensure you have packaged the Optimizely X SDK with Segment’s.


Segment lets you change these destination settings via your Segment dashboard without having to touch any code.

Account ID

In order to use Optimizely X via server side, you must enter your Account ID from your Optimizely account. You can find this ID by visiting https://app.optimizely.com/v2/accountsettings/account/plan

Cache Exp

To optimize the server side integration, we will cache the fetched Datafile that you have provided for this amount of time (in seconds) in Redis. Since the datafile should not change unless you modified the conditions or variation rules of your experiments, it is advised to have a minimum floor of 300 seconds (5 minutes).

Datafile URL

In order to use Optimizely X server side, you must enter the entire URL for your datafile. It should look something like https://cdn.optimizely.com/json/9218021209.json

Sends the experiment and variation information as properties on a track call.

Send experiment data to other tools (as a track call). An “Experiment Viewed” track event will be triggered each time you access an Optimizely live variable. If you’re regularly accessing live variables and want to reduce the number of track events triggered, pass the “false” flag, for example our Android library would be:

Boolean myVariable = optimizelyClient.getVariableBoolean("myVariable",

And for our iOS library:

bool myVariable = [optimizely variableBoolean:@"myVariable"

Specifies the Experiment Viewed as a non-interaction event for Google Analytics

Send Experiment Viewed as a non-interaction event

Only Track Known Users

Optimizely does not alias known and unknown users. By default, Segment will only send the anonymousId to Optimizely. Enable this to only send the userId to Optimizely. Important: This setting only applies if you are bundling this integration for mobile sources.

Use User ID

Enable this if you want the server side integration to use User ID instead of anonymous ID in your identify calls

If you have any questions or see anywhere we can improve our documentation, please let us know or kick off a conversation in the Segment Community!