Optimizely provides easy-to-use A/B testing solutions, allowing dynamic experimentation in your web, iOS, and Android apps.

mParticle supports the full breadth of the latest Optimizely X platform by bundling the Optimizely SDKs.

This integration allows you to send events tracked in mParticle to Optimizely to give further visibility into how the experiments you are running impact your engagement metrics. Use it to reduce the time it takes to evaluate an experiment by leveraging the events you already record with mParticle.


In order to enable mParticle’s integration with Optimizely, you will need your Optimizely SDK Key.

Note: as noted on the Optimizely website, earlier versions of their SDK use a Project ID rather than an SDK Key to create a manager. Project IDs are still supported in 2.x backwards compatibility. Versions 1.x and 2.x can use only a Project ID, while 3.0+ can use a Project ID or SDK key to instantiate the client with the datafile. The benefit of using an SDK Key is that you can retrieve datafiles for other environments and not just the primary environment as when you use a Project ID. See Initialize a mobile SDK for clarification.

Optimizely does not accept PII, so while mParticle allows for email addresses to be used to identify users, an anonymous user ID is required to send with the mParticle events that are sent to Optimizely. Additionally, the user ID used for the mParticle event must be the same that is passed into the Optimizely activate call. Please see Optimizely’s documentation regarding user IDs and event tracking for more information.


The mParticle Web SDK will automatically load the Optimizely JavaScript snippet for your SDK Key or Project ID once you’ve configured it in your mParticle dashboard. If you would like to load the Optimizely snippet yourself you can do so and, once enabled, mParticle will look for window.optimizely to prevent duplicate loading. In either case, mParticle will still forward events to the Optimzely object that is loaded.

While allowing mParticle to automatic load Optimizely reduces the amount of code you need to write, you may choose to initialize Optimizely yourself to prevent “page flashing” in the case where an Optimizely experiment is expected to alter the UI immediately on load. You can read more about this concern here and make the choice that’s best for your setup.

Adding the kit to your iOS or Android app

mParticle’s Optimizely integration requires that you add the Optimizely Kit to your iOS or Android app.

mParticle publishes the Optimizely Kit as separate iOS and Android libraries which have transitive dependencies on the mParticle Core SDK as well as the Optimizely SDK.

# Sample Podfile

source ''

target '<Your Target>' do
    pod 'mParticle-Optimizely'
// Sample build.gradle
// Add the kit dependency
dependencies {
    // Ensure the Kit version matches that of the mParticle Core SDK that you're using
    compile 'com.mparticle:android-optimizely-kit:5+'

Reference the Apple SDK and Android SDK guides to read more about kits.

Initializing the Optimizely Client

The mParticle integration will take care of initializing the Optimizely client for you with your configured SDK Key or Project ID, or you can initialize it yourself.

Accessing the mParticle-Initialized Client

If you’d like to use the client that mParticle creates you can access it directly from the kit on iOS or Android, or the window.optimizely object on web.

//save this reference to the client for later use
[MParticle sharedInstance] kitInstance:[NSNumber numberWithLong:MPKitInstanceOptimizely] completionHandler:^(id *kitInstance) {
    OPTLYClient *client = [MPKitOptimizely optimizelyClient];
let client = MParticle.sharedInstance()
OptimizelyKit.getOptimizelyClient(new OptimizelyKit.OptimizelyClientListener() {
    public void onOptimizelyClientAvailable(OptimizelyClient optimizelyClient) {
        //save this reference to the client for later use

Manually Initializing the Client

If you’d like to initialize the Optimizely client yourself you can do so, and tell mParticle to use it:

// Create the builder and manager. Then set the datafile manager
OPTLYManagerBuilder *builder = [OPTLYManagerBuilder builderWithBlock:^(OPTLYManagerBuilder * _Nullable builder) {
    builder.projectId = @"projectId"; //called sdk key in Optimizely console but projectID in their docs
OPTLYManager *manager = [[OPTLYManager alloc] initWithBuilder:builder];

// Synchronously initialize the client, then activate the client
OPTLYClient *client = [manager initialize];
// Get the reference to the kit and set client
MPKitOptimizely.optimizelyClient = client;

// Or, asynchronously initialize the client, then activate the client
[manager initializeWithCallback:^(NSError * _Nullable error,
                                  OPTLYClient * _Nullable client) {
    //Get the reference to the kit and set client
    MPKitOptimizely.optimizelyClient = client;
let builder = OPTLYManagerBuilder(block: { builder in
        builder?.projectId = "projectId"
let manager = OPTLYManager(builder: builder)

let client = manager.initialize()
MPKitOptimizely.optimizelyClient = client

manager.initialize(withCallback: { error, client in
    MPKitOptimizely.optimizelyClient = client

OptimizelyManager.Builder builder = OptimizelyManager.builder()
optimizelyManager.initialize(this, new OptimizelyStartListener() {
    public void onStart(OptimizelyClient optimizely) {
        //set the Optimizely client on mParticle

See Optimizely’s docs for a more in-depth explanation.


The mParticle Optimizely web integration will look for window.optimizely and use that if present. You can also use this object to access the Optimizely client that the integration automatically initializes.

Activate an Experiment

Once you have a reference to the Optimizely client, you can use it to activate an experiment. It’s crucial that you do so using the same user ID that the mParticle integration is configured to use, so that events are associated with the correct user.

By default, mParticle will use the device application stamp if present. See below for more information on the supported identity types. If you’ve configured a different ID than device application stamp, be sure to use that ID (if present) to activate experiments.

See Optimizely’s docs for a more in-depth explanation.

// Conditionally activate an experiment for the provided user
OPTLYVariation *variation = [MPKitOptimizely.optimizelyClient activate:@"my_experiment"
                                                                userId:[MParticle sharedInstance].identity.deviceApplicationStamp //or another appropriate id

if ([variation.variationKey isEqualToString:@"control"]) {
    // Execute code for control variation
else if ([variation.variationKey isEqualToString:@"treatment"]) {
    // Execute code for treatment variation
else {
    // Execute default code
// Conditionally activate an experiment for the provided user
let variation = MPKitOptimizely.optimizelyClient.activate("my_experiment", userId: MParticle.sharedInstance().identity.deviceApplicationStamp /*or another appropriate id */)

if (variation?.variationKey == "control") {
    // Execute code for control variation
} else if (variation?.variationKey == "treatment") {
    // Execute code for treatment variation
} else {
    // Execute default code
Variation variation = optimizelyClient.activate(experimentKey, MParticle.getInstance().Identity().getDeviceApplicationStamp());

if (variation != null) {
    if ("control")) {
        // Execute code for control variation
    } else if ("treatment")) {
        // Execute code for treatment variation
} else {
    // Execute default code


You can activate an experiment on web using exactly the same code as a standard Optimizely implementation.

See Optimizely’s docs for a more in-depth explanation.

Supported Identity Types

iOS and Android

All events sent to Optimizely must be tagged with a user ID. With mParticle’s integration you have the option to configure which user or device identity type should be mapped to the Optimizely User ID. This is present as a connection setting when configuring Optimizely in your mParticle dashboard. The following user identities are supported:

  • Device Application Stamp (default)
  • Customer ID
  • Email
  • mParticle ID
  • Other
  • Other 2
  • Other 3
  • Other 4

Note: For anonymous users, when your configured ID is not present, the integration will default to Device Application Stamp, which is always present.


The Optimizely-X web client platform does not currently support user ID values at this time. As soon as this becomes available, we’ll be sure to update the mParticle integration to send it!

Supported Event Types

mParticle forwards the following event types:

  • Custom Event
  • Commerce Event
  • Page View (Web only)

On iOS and Android, these events are mapped to Optimizely’s track API and will include the name of the event, custom attributes, user attributes, and your configured user ID. On Web, the events are pushed into the window.optimizely queue to be sent to the server.

Reserved Tags

Optimizely supports several “reserved” event tags including “revenue” and “value”. See the sections below for how mParticle maps to these tags.

Revenue Events

mParticle will map Purchase-type CommerceEvent’s as Optimizely revenue events, mapping the CommerceEvent revenue to Optimizely’s revenue event tag.

mParticle will use the default CommerceEvent purchase event name “eCommerce - purchase - Total” when invoking Optimizely’s track API. You may override this name by setting a Custom Flag on the given CommerceEvent:

MPProduct *product = [[MPProduct alloc] initWithName:@"Foo name"
                                                 sku:@"Foo sku"
MPTransactionAttributes *attributes = [[MPTransactionAttributes alloc] init];
attributes.transactionId = @"foo-transaction-id";
// mapped to Optimizely as 45000 cents
attributes.revenue = @450.00; = @30.00;
attributes.shipping = @30;

MPCommerceEventAction action = MPCommerceEventActionPurchase;
MPCommerceEvent *event = [[MPCommerceEvent alloc] initWithAction:action

// mapped to Optimizely as a custom event name
[event addCustomFlag:@"custom revenue event name"
event.transactionAttributes = attributes;
[[MParticle sharedInstance] logCommerceEvent:event];
let product = MPProduct(name: "Foo name", sku: "Foo sku", quantity: NSNumber(value: 4), price: NSNumber(value: 100.00))
let attributes = MPTransactionAttributes()
attributes.transactionId = "foo-transaction-id"
// mapped to Optimizely as 45000 cents
attributes.revenue = NSNumber(value: 450.00) = NSNumber(value: 30.00)
attributes.shipping = NSNumber(value: 30)

let action = MPCommerceEventActionPurchase as? MPCommerceEventAction
let event = MPCommerceEvent(action: action, product: product)

// mapped to Optimizely as a custom event name
event.addCustomFlag("custom revenue event name", withKey: MPKitOptimizelyEventName)
event.transactionAttributes = attributes
Product product = new Product.Builder("Foo name", "Foo sku", 100.00)
TransactionAttributes attributes = new TransactionAttributes("foo-transaction-id")
        // mapped to Optimizely as 45000 cents
CommerceEvent event = new CommerceEvent.Builder(Product.PURCHASE, product)
        // mapped to Optimizely as a custom event name
        .addCustomFlag(OptimizelyKit.OPTIMIZELY_EVENT_NAME, "custom revenue event name")
var product1 = mParticle.eCommerce.createProduct('Foo name', 'Foo sku', 100, 4),
    shipping = 30,
    tax = 30,
    ta = mParticle.eCommerce.createTransactionAttributes('foo-transaction-id', 'foo-affiliation', 'foo-coupon', 400, shipping, tax),
    logPurchaseBoolean = false,
    attributes = {foo: 'bar'},
    customFlags = {'Optimizely.EventName': 'custom revenue event name'};

mParticle.eCommerce.logPurchase(ta, product1, logPurchaseBoolean, attributes, customFlags);

You may also include Optimizely’s “revenue” tag as a custom attribute of any event (Commerce or Custom events) and it will be forwarded to Optimizely as such.

Value Events

Optimizely supports a reserved “value” event tag to associate a scalar value to a given event. You may include “value” as custom event attribute, or you can include this as a custom flag. The custom flag lets you stick to your dedicated taxonomy for custom attributes while also sending this reserved tag to Optimizely.

MPEvent *event = [[MPEvent alloc] initWithName:@"Foo conversion event"

// "10" will be parsed as a number and sent to Optimizely
[event addCustomFlag:@"10"

[[MParticle sharedInstance] logEvent:event];
let client = MParticle.sharedInstance()
var event: MPEvent?
event.setValue(10, forKey: "MPKitOptimizelyEventKeyValue")
Map flags = new HashMap<>();
// "10" will be parsed as a double and sent to Optimizely
flags.put(OptimizelyKit.OPTIMIZELY_VALUE_KEY, "10");
MPEvent event = new MPEvent.Builder("Foo conversion event")
var eventType = mParticle.EventType.Other,
    attributes = {foo: 'bar'},
    customFlags = {'Optimizely.Value': 15};

mParticle.logEvent('Foo conversion event', eventType, attributes, customFlags);

Single Page Applications (Web Only)

Optimizely works great on Single Page Applications (SPAs). Review this in depth article about how to set up your Optimizely settings and pages properly in order to avoid issues with Optimizely on your SPA. mParticle’s OptimizelyX Web Client SDK provides the logPageView method which allows you to apply a page context for manually activating a page, allowing for full flexibility for sites with dynamic content or challenging URL patterns. View more information here. The following example performs a mapping of the page watchedVideo as seen here.

var tags = {category: 'Kitchen', subcategory: 'blenders'}
mParticle.logPageView('watchedVideo', tags);

will map to the following.

  type: 'page',
  pageName: 'watchedVideo',
  tags: {
    'category': 'Kitchen',
    'subcategory': 'Blenders'

Configuration Settings

Setting Name Data Type Description
SDK Key string (required) Your Site/App’s Optimizely SDK Key.

Connection Settings

Setting Name Data Type Platform Default Value Description
User ID enum iOS/Android Device Application Stamp The User Identity you would like to map to Optimizely’s “userId” field. Supports Device Application Stamp, Customer ID, Email, or MPID.
Event Interval integer iOS/Android The interval (seconds) at which Optimizely’s SDK uploads events. Defaults to Optimizely’s own SDK default if not set.
Datafile Interval integer iOS/Android The interval (seconds) at which Optimizely’s SDK attempts to update the cached datafile. Defaults to Optimizely’s own SDK default if not set.

Was this page helpful?