Data Exporting

To export Apptimize experiment information, such as which variant a user is participating in, use our client-side APIs. Note that we automatically export this information in some of our third party integrations. By accessing this information in your application code you can use or send the data wherever you like. This is most commonly used when you want to send the data to your custom backend. The following events (approximate names) are available to your application:

OnParticipatedInExperimentNotification

Triggered every time a user participates in an experiment

OnEnrolledInExperimentNotification

Triggered anytime metadata or Apptimize configuration changes cause a user to become enrolled in one or more experiments.

OnUnenrolledInExperimentNotification

Triggered anytime metadata or Apptimize configuration changes cause a user to become unenrolled from one or more experiments

Be sure to note the differences between enrolled and participating. Enrolled means Apptimize bucketed the user into the experiment (they met the filtering requirements and randomized allocation) while participating means the user was enrolled and then actually saw the experiment. A user might not participate if they are enrolled but never navigate to the screen that contains the experiment. In most cases we recommend that you use participation information because it is more useful in calculating statistics on your experiments.

Data Exporting - Detailed User Interaction

You can also choose to export detailed experiment participation. In order to do that, you would need to set up an Amazon S3 Bucket to which we can upload the export files.

Set up AWS S3

  1. Log in to Amazon Web Services. Click Services and go to S3.

  2. Create a bucket. Follow Amazon’s process for creating an S3 bucket, selecting US Standard for S3 Region. For more information on S3 regions, see Amazon Regions.

  3. Grant permissions to your newly-created bucket.

    1. Go to Permissions >> Access Control List.

    2. Click Add Account, and use Apptimize’s ID as the canonical ID / account field: 77cb04d110994f05ffa1eb3eb37642f8283198d4dcd6c49ca5fcd2062c9bdbaf

    3. Select List objects and Write objects. You can select additional permission, but your bucket must have these permissions to support an Airship integration.

    4. Click Save.

Realtime Participation

In your application code you can listen for participation events and then forward them wherever you like. Note that these events happen over time as a user participates in your experiment.

Android (Java)
import com.apptimize.Apptimize;
import com.apptimize.ApptimizeTestInfo;
import com.apptimize.Apptimize.OnExperimentRunListener;

// Do this before Apptimize.setup called from wherever Apptimize is initialized
Apptimize.setOnTestRunListener(new OnTestRunListener() {

    // This method is called by Apptimize whenever the user participates in an experiment
    @Override
    public void onTestRun(ApptimizeTestInfo testInfo, boolean isFirstParticipation) {
        String experimentAndVariantName = testInfo.getExperimentName() + "-" + testInfo.getVariantName();
        Map<String, String> exportExperimentInfo = new java.util.HashMap<String, String>(5);
        exportExperimentInfo.put("experimentName",testInfo.getExperimentName());
        exportExperimentInfo.put("variantName",testInfo.getVariantName());
        exportExperimentInfo.put("nameAndVariation",experimentAndVariantName);
        exportExperimentInfo.put("experimentId",testInfo.getTestId().toString());
        exportExperimentInfo.put("variantId",new Long(testInfo.getEnrolledVariantId()).toString());

        // Sending a participation event
        // Examples - depending on how you track events
        // Single participating event name and experiment & variant info in the dictionary
        CustomTracking.trackEvent("Participated", exportExperimentInfo);
        // Or put the info directly in the event name
        CustomTracking.trackEvent("Participated|" + experimentAndVariantName, exportExperimentInfo);

        // Setting the participation as persistent state (dimension/attribute)
        // Examples - depending on how you track state information
        CustomTracking.putParticipatingExperiment(experimentAndVariantName);
        // or possibly by adding it to an array dimension called "participating"
        CustomTracking.addValueToDimensionArray("participating", experimentAndVariantName);
    }
});

Realtime Enrollment

In your application code you can listen for enrollment events and then forward them wherever you like. Note that these events happen over time as experiment configurations are updated (downloading them from the server either the first time a user runs your application or as they are changed by you in the dashboard), or if you make changes to the Apptimize SDK configuration.

Android (Java)
import com.apptimize.Apptimize;
import com.apptimize.ApptimizeTestInfo;
import com.apptimize.Apptimize.OnExperimentRunListener;

// Do this before Apptimize.setup called from wherever Apptimize is initialized
Apptimize.setOnTestEnrollmentChangedListener(new OnTestEnrollmentChangedListener() {

    // This method is called by Apptimize whenever the user becomes enrolled in a test
    @Override
    public void onEnrolledInTest(ApptimizeTestInfo testInfo) {
        String experimentAndVariantName = testInfo.getExperimentName() + "-" + testInfo.getVariantName();
        Map<String, String> exportExperimentInfo = new java.util.HashMap<String, String>(5);
        exportExperimentInfo.put("experimentName",testInfo.getExperimentName());
        exportExperimentInfo.put("variantName",testInfo.getVariantName());
        exportExperimentInfo.put("nameAndVariation",experimentAndVariantName);
        exportExperimentInfo.put("experimentId",testInfo.getTestId().toString());
        exportExperimentInfo.put("variantId",new Long(testInfo.getEnrolledVariantId()).toString());

        // Sending a participation event
        // Examples - depending on how you track events
        // Single participating event name and experiment & variant info in the dictionary
        CustomTracking.trackEvent("Enrolled", exportExperimentInfo);
        // Or put the info directly in the event name
        CustomTracking.trackEvent("Enrolled|" + experimentAndVariantName, exportExperimentInfo);
    }

    // This method is called by Apptimize whenever the user becomes unenrolled in a test
    @Override
    public void onUnenrolledInTest(ApptimizeTestInfo testInfo, UnenrollmentReason reason) {
        String experimentAndVariantName = testInfo.getExperimentName() + "-" + testInfo.getVariantName();
        Map<String, String> exportExperimentInfo = new java.util.HashMap<String, String>(5);
        exportExperimentInfo.put("experimentName",testInfo.getExperimentName());
        exportExperimentInfo.put("variantName",testInfo.getVariantName());
        exportExperimentInfo.put("nameAndVariation",experimentAndVariantName);
        exportExperimentInfo.put("experimentId",testInfo.getTestId().toString());
        exportExperimentInfo.put("variantId",new Long(testInfo.getEnrolledVariantId()).toString());

        // Sending a participation event
        // Examples - depending on how you track events
        // Single participating event name and experiment & variant info in the dictionary
        CustomTracking.trackEvent("Unenrolled", exportExperimentInfo);
        // Or put the info directly in the event name
        CustomTracking.trackEvent("Unenrolled|" + unenrollmentReason +"|" + experimentAndVariantName, exportExperimentInfo);
    }
});

Note: Our Server Side SDKs are stateless and hence there is no enrollment state unlike the client side SDKs.

Snapshot Enrollment and Participation

You can also lookup the current state of which variants a user is enrolled and participating in. This enables you to check whenever you like to get a snapshot of the state. Although, to be most accurate we recommend that you instead listen for participation events (above) so that you can operate on that data in real-time.

Android (Java)
// At some point after Apptimize.setup in your application code where you want to
// take a new snapshot
// Note: in most cases it's better to listen for participation events instead

// Loop through all the enrolled experiments
Map<String, ApptimizeTestInfo> testInfoMap = Apptimize.getTestInfo();
if (testInfoMap == null) {
    return;
}

for (String key : testInfoMap.keySet()) {
    ApptimizeTestInfo testInfo = testInfoMap.get(key);
    String experimentAndVariantName = testInfo.getTestName() + "-" + testInfo.getEnrolledVariantName();

    // Set enrollment as persistent state (dimension/attribute)
    // Example - depending on how you track state information
    CustomTracking.putEnrolledExperiment(experimentAndVariantName);
    // or possibly by adding it to an array dimension called "enrolled"
    CustomTracking.addValueToDimensionArray("enrolled", experimentAndVariantName);

    if(testInfo.userHasParticipated()) {
        // Set participation (if applicable) as persistent state (dimension/attribute)
        // Example - depending on how you track state information
        CustomTracking.putParticipatingExperiment(experimentAndVariantName);
        // or possibly by adding it to an array dimension called "participating"
        CustomTracking.addValueToDimensionArray("participating", experimentAndVariantName);
    }
}

Note

It is not possible to retrieve a snapshot of enrollment and participation with our Server Side SDKs because they are stateless. You can snapshot participation using variantInfo.getParticipationPhase() API on the server SDKs.