Leanplum

Suggest Edits

Leanplum SDK setup

An introduction to Leanplum and our SDK

 

Leanplum allows mobile teams to go from insight to action quickly using the lean cycle of releasing, analyzing, and optimizing content and messaging. See below to learn more about our SDK setup and features.

Setting up the SDK

Follow our setup guides to integrate the Leanplum SDK with your app.

Messaging

With Leanplum's messaging features, you can send customized messages to users and analyze your results from the Leanplum dashboard. You can also send messages manually via our API, depending on your organization's needs.

Once you integrate the Leanplum SDK, in-app messaging should be ready to use. Next, set up Push notification registration to send push notifications directly from the Leanplum dashboard. We also offer email services as an add-on feature, so your team can manage all of your app's messaging channels from one place.

Variables

Variables and resources will appear in the Variables tab automatically once they are detected by the SDK. After your variables are defined, you'll be able to change your variable values from the dashboard, without writing additional code or waiting for App Store approval.

You can preview variable changes on your device instantly before send them out to your users. After you publish your changes, your users will see any updates the next time they open the app. You can also target variable changes to specific user segments to personalize their in-app experience.

After you install the SDK, see Defining variables and Variable types for more.

Analytics

With 19 out-of-the-box metrics, Leanplum's Analytics tab allows you to start gathering intelligence on your app from the moment the SDK is integrated. Our goal is to give you the data and tools you need to create an informed and results-driven content strategy. By seeing which metrics need improvement, you can decide whether to continue with your current strategy or A/B test a new one.

In addition to the metrics calculated automatically by Leanplum, you can also track custom Events and States in your app. Doing so allows you to create custom metrics in the Analytics dashboard. You can also trigger messages and other content changes for your users based on an event or state change.

A/B Testing

Testing different feature releases and messaging strategies ensures that you are rolling out the most effective content for your users. After you set up the Leanplum SDK (along with any custom variables, events, etc.) you'll be able to test different versions of messages or UI changes on a smaller pool of users before releasing changes to your entire userbase.

Once you've collected enough data, Leanplum will notify you of any statistically significant changes in your metrics. Then you can decide which message version or UI change you want to roll out to all of your users.

Suggest Edits

iOS setup

Get started setting up Leanplum with your app

 

Initial setup

The steps below use CocoaPods, but you can also install the SDK manually if it suits you.

Supports iOS 7.0 and above.

For more detail, you can also check out our generated iOS docs or review the source code on Github.

Download CocoaPods

CocoaPods is the dependency manager for Objective-C and Swift projects. If you haven't already, install CocoaPods by running the following command in the terminal:

$ sudo gem install cocoapods

For issues installing CocoaPods, see their website for help.

Add a Podfile

In the terminal, navigate to your app's directory. Add a Podfile to your app by running the following command:

$ pod init

Edit your Podfile

Open your Podfile by running the following command:

$ open -a Xcode Podfile

Insert the following into your Podfile:

pod 'Leanplum-iOS-SDK'

# Uncomment for UI Editor.
# pod 'Leanplum-iOS-UIEditor'

# Uncomment one of the following for Location Services.
# pod 'Leanplum-iOS-Location'
# pod 'Leanplum-iOS-LocationAndBeacons'

See Geofencing and location for more on setting up location services.

Install your pods

Now, install the Leanplum SDK pods by running the following command:

$ pod install

If you prefer to use Carthage, you can simply add the following to your Cartfile.

github "Leanplum/Leanplum-iOS-SDK"

# Uncomment for UI Editor.
# github "Leanplum/Leanplum-iOS-UIEditor"

# Uncomment one of the following for Location Services.
# github "Leanplum/Leanplum-iOS-Location"
# github "Leanplum/Leanplum-iOS-LocationAndBeacons"

Add DEBUG flag (Swift only)

In your Build Settings, add -D DEBUG to Debug mode in Other Swift Flags.

Edit your AppDelegate

Remember to import Leanplum before doing anything. You can avoid this by adding the import to your app's prefix header (.pch) file.

For tighter security, remove your development key from your app delegate before submitting to the App Store.

import UIKit
#if DEBUG
    import AdSupport
#endif
import Leanplum

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

var window: UIWindow?

func application(application: UIApplication!, didFinishLaunchingWithOptions launchOptions: NSDictionary!) -> Bool {
  // We've inserted your Test API keys here for you :)
  #if DEBUG
    Leanplum.setDeviceId(ASIdentifierManager.shared().advertisingIdentifier.uuidString)
    Leanplum.setAppId("YOUR_APP_ID",
      withDevelopmentKey:"YOUR_DEVELOPMENT_KEY")
  #else
    Leanplum.setAppId("YOUR_APP_ID",
      withProductionKey: "YOUR_PRODUCTION_KEY")
  #endif

  // Optional: Tracks in-app purchases automatically as the "Purchase" event.
  // To require valid receipts upon purchase or change your reported
  // currency code from USD, update your app settings.
  // Leanplum.trackInAppPurchases()

  // Optional: Tracks all screens in your app as states in Leanplum.
  // Leanplum.trackAllAppScreens()

  // Optional: Activates UI Editor.
  // Requires the Leanplum-iOS-UIEditor framework.
  // LeanplumUIEditor.shared().allowInterfaceEditing()

  // Starts a new session and updates the app content from Leanplum.
  Leanplum.start()

  return true
}
...
#import "AppDelegate.h"
#import <Leanplum/Leanplum.h>

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
  // Insert your API keys here.
  #ifdef DEBUG
    LEANPLUM_USE_ADVERTISING_ID;
    [Leanplum setAppId:@"YOUR_APP_ID"
     withDevelopmentKey:@"YOUR_DEVELOPMENT_KEY"];
  #else
    [Leanplum setAppId:@"YOUR_APP_ID"
     withProductionKey:@"YOUR_PRODUCTION_KEY"];
  #endif

  // Optional: Tracks in-app purchases automatically as the "Purchase" event.
  // To require valid receipts upon purchase or change your reported
  // currency code from USD, update your app settings.
  // [Leanplum trackInAppPurchases];

  // Optional: Tracks all screens in your app as states in Leanplum.
  // [Leanplum trackAllAppScreens];

  // Optional: Activates UI Editor.
  // Requires the Leanplum-iOS-UIEditor framework.
  // [[LeanplumUIEditor sharedEditor] allowInterfaceEditing];

  // Sets the app version, which otherwise defaults to
  // the build number (CFBundleVersion).
  [Leanplum setAppVersion:@"2.4.1"];

  // Starts a new session and updates the app content from Leanplum.
  [Leanplum start];
  return YES;
}
...

@end

Verify your setup (iOS)

When testing your build, run your app in Debug/development mode using the Development key. Use the Production key when the app is pushed live (to be used by real users/in production).

The Development key is used to:

  • Send data to the development/test pipeline (via an open web socket in real-time)
  • Log processes in the debugger for validation
  • See and register your developer devices in the dashboard
  • Force your test device into specific A/B test variants
  • Keep your data segregated from the live users (instead it will show up in the Developer Activity section)
  • Update custom templates and variables to the content management system

Never use a development key in a production/live build.

A development key uses an open socket for real-time analytics — this pipeline cannot support real users (in a production build). Additionally, any user data will be lost as it is not captured in analytics.

Run your project and register your device

Registering a test device will allow you to test your messages, variable changes, and other Leanplum projects on a real device.

To register your device, first make sure you're in Debug mode. To ensure Debug mode is enabled, make sure the DEBUG preprocessor macro is set in Build Settings.

Next, go to Devices in the Leanplum dashboard, then hover over your device and click Register.

Test in-app messaging

Send yourself an in-app message to see it in action. While running your device in Debug mode, go to the Leanplum Message Composer. Create a new message and click Send Preview. The message will be sent to all registered test devices.

Create a custom variable (optional)

Variables you define will show up in the Leanplum dashboard, where you can change them, segment them, and A/B test them without having to update your app. You can verify the variable has been set by checking the Variables tab in the Leanplum dashboard.

Add the following lines to your app delegate or another class of your choosing:

#import <Leanplum/Leanplum.h>

DEFINE_VAR_STRING(welcomeMessage, @"Welcome to Leanplum!");

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{ ...
  [Leanplum onVariablesChanged:^{
    NSLog(@"%@", welcomeMessage.stringValue);
  }];
  return YES;
}
...
@end
import UIKit
import Foundation

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow?
    var welcomeMessage = LPVar.define("welcomeMessage",
    withString: "Welcome to Leanplum!")

    func application(application: UIApplication!, didFinishLaunchingWithOptions launchOptions: NSDictionary!) -> Bool {
        ...
        Leanplum.onVariablesChanged({
            NSLog((self.welcomeMessage?.stringValue())!)
        })
        ...
        return true
    }
...
}

See Defining variables for more on setting up variables.

It's important to use callbacks if the value is needed around the time the app starts. This guarantees the latest value. See more on how to handle asynchronous code with Callbacks.

Track an event (optional)

Events allow you to measure statistics about what your users do inside your app. You can verify an event is tracked in the Debugger or Events tabs in the Dashboard.

Add the following lines of code to track an event. You can place it anywhere after calling start; this is just an example:

#import <Leanplum/Leanplum.h>

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{ ...
  [Leanplum onVariablesChanged:^{
    NSLog(@"%@", welcomeMessage.stringValue);
    [Leanplum track:@"Launch"];
  }];
  return YES;
}
...
@end
import UIKit
import Foundation

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow?
    var welcomeMessage = LPVar.define("welcomeMessage", withString: "Welcome to Leanplum!")

    func application(application: UIApplication!, didFinishLaunchingWithOptions launchOptions: NSDictionary!) -> Bool {
        ...
        Leanplum.onVariablesChanged({
            NSLog((self.welcomeMessage?.stringValue())!)
            Leanplum.track("Launch")
        })
        ...
        return true
    }
		...
}

See Events for more on tracking custom events with Leanplum.

iOS extensions

Leanplum can be used from iOS extensions. Before calling [Leanplum start] when your ViewController loads, you need to call [Leanplum setExtensionContext:self.extensionContext].

Suggest Edits

Android setup

 

The following setup guide is for developers using Gradle to manage dependencies. For manual setup instructions, see the note below in Edit your manifest.

Supports Android 4.0.1 (API Level 14) and above.

For more detail, feel free to check out our generated Javadoc or view the source code on Github.

Update your gradle files

In your project-level build.gradle build file:

  1. add the Leanplum repo to your allproject repositories.
  2. add google-services to your dependencies for Firebase Cloud Messaging.

Here's a simple example:

buildscript {
  repositories {
    jcenter()
  }
  dependencies {
    classpath 'com.android.tools.build:gradle:2.2.3'

    // For Firebase Cloud Messaging.
    classpath 'com.google.gms:google-services:3.2.0'
  }
}
allprojects {
  repositories {
    jcenter()
    maven {
      url "https://repo.leanplum.com/"
    }
    maven {
      url "https://maven.google.com"
  }
}

In your module-level build.gradle build file:

  1. Add the required Leanplum libraries in your dependencies, based on which Leanplum services you intend to use (see below).

In SDK 4.0+, our features are split into modular libraries.

Library
Description

leanplum-fcm OR leanplum-gcm

Enables push notifications through Leanplum. You must choose one, depending on which service you use (FCM/GCM).

leanplum-location

Enables location-based messaging. See more here.

leanplum-uieditor

Enables UI changes through the Leanplum dashboard. See more here.

leanplum-core

Enables core Leanplum functionality: in-app messages, a/b tests, states/events tracking, etc.

You can use any combination of these libraries except:

  • You cannot use FCM and GCM libraries together — only one Leanplum push service per app.
  • You do not need to add core with other libraries (if using Gradle). All of our feature-specific libraries automatically include core, so you should only add core if you don’t include any other Leanplum libraries.

Given that, here is a fully-loaded gradle file.

 dependencies {
  
  // Firebase messaging.
  // Only include if you plan to use Firebase for Leanplum push messaging.
  // Minimum supported version of Firebase is 10.0.1.
  compile 'com.leanplum:leanplum-fcm:+'
  compile 'com.google.firebase:firebase-messaging:11.8+'

  // Location services.
  // Only include if you need location-based messaging.
  // Minimum supported version of play location is:
  // 8.3.0 for GCM, 10.0.1 for FCM.
  compile 'com.leanplum:leanplum-location:+'
  compile 'com.google.android.gms:play-services-location:11.8+'
  
  // UI Editor
  // Only include if you need the UI Editor.
  compile 'com.leanplum:leanplum-uieditor:+'
  
}
// Include for FCM.
apply plugin: 'com.google.gms.google-services'

Or if you want to use GCM instead of Firebase, replace the first two dependencies:

dependencies {

  // GCM messaging.
  // Minimum supported version of GCM is 8.3.0.
  compile 'com.leanplum:leanplum-gcm:+' // Use this instead of our Firebase library.
  compile 'com.google.android.gms:play-services-gcm:11.8+' // Use Google's GCM library.

  ... // The rest remains the same as above.

}
// No plugin required.

Or, if you just want core functionality (aka "none of the above"):

dependencies {

  // NONE OF THE ABOVE
  // Automatically included with any/all of the above Leanplum libraries.
  // Only include if you do not use any other Leanplum libraries.
  compile 'com.leanplum:leanplum-core:+'

}

You can see more detailed examples in our guide to updating to Android SDK 4.0.

With previous versions of our SDK (< 4.0), you only needed to include com.leanplum:Leanplum (and optionally com.leanplum:UIEditor). The Leanplum library included GCM, FCM, and geolocation libraries.

Edit your manifest

On Android SDK 2.1.0+, we support manifest merging with gradle only which will add all needed services into your manifest automatically, including GCM or FCM services.

Want to install our Android SDK manually?

Download our SDK here. Be sure to drag the .jar file for each required library into your project's libs/ folder. Also be sure to include leanplum-core (and leanplum-push if using either push library). See the .jar manifest files below for more info.

Here are example AndroidManifest.xml files, including two full manifest files for .jar setups (non-gradle).

<?xml version="1.0" encoding="utf-8"?>
<manifest package="[com.YOUR_PACKAGE]"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" >

  <uses-sdk
      android:minSdkVersion="14"
      tools:overrideLibrary="com.leanplum, com.google.android.gms"/>

  <!-- These permissions are required only for push notifications. -->

  <!-- GCM requires a Google account (necessary only if if the device is running a version lower than Android 4.0.4). -->
  <uses-permission android:name="android.permission.GET_ACCOUNTS"/>

  <!-- Optional. Prevents the device from sleeping when a message is received. -->
  <uses-permission android:name="android.permission.WAKE_LOCK"/>

  <!-- These permissions are required only for geofencing. -->
  <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
  <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>

  <application
    android:allowBackup="true"
    android:icon="@drawable/ic_launcher"
    android:label="@string/app_name"
    android:theme="@style/AppTheme"
    android:name=".[YOUR_APPLICATION_CLASS]" >
      <meta-data
          android:name="com.google.android.gms.version"
          android:value="@integer/google_play_services_version" />
    ...
  </application>

</manifest>
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="[com.YOUR_PACKAGE]"
    android:versionCode="1"
    android:versionName="1.0" >

<uses-sdk
    android:minSdkVersion="14" />
<!-- Base permissions for Leanplum Android SDK. -->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.INTERNET"/>

<!-- Optional. Prevents the device from sleeping when a message is received. -->
<uses-permission android:name="android.permission.WAKE_LOCK"/>

<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE"/>
<permission android:name="[com.YOUR_PACKAGE].permission.C2D_MESSAGE"
    android:protectionLevel="signature" />
<uses-permission android:name="[com.YOUR_PACKAGE].permission.C2D_MESSAGE" />

<!-- These permissions are required only for geofencing. -->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>

<application
  android:allowBackup="true"
  android:icon="@drawable/ic_launcher"
  android:label="@string/app_name"
  android:theme="@style/AppTheme"
  android:name=".[YOUR_APPLICATION_CLASS]" >

    <meta-data
        android:name="com.google.android.gms.version"
        android:value="@integer/google_play_services_version" />

    <receiver
        android:name="com.leanplum.LeanplumPushReceiver"
        android:exported="false" >
        <intent-filter>
            <action android:name="com.leanplum.LeanplumPushFirebaseMessagingService" />
        </intent-filter>
    </receiver>


    <service android:name="com.leanplum.LeanplumLocalPushListenerService" />

    <service android:name="com.leanplum.LeanplumPushRegistrationService" />

    <service
        android:name="com.leanplum.LeanplumPushFirebaseMessagingService"
        android:exported="false">
        <intent-filter>
            <action android:name="com.google.firebase.MESSAGING_EVENT" />
        </intent-filter>
    </service>
    <service
        android:name="com.leanplum.LeanplumPushFcmListenerService"
        android:exported="false">
        <intent-filter>
            <action android:name="com.google.firebase.INSTANCE_ID_EVENT" />
        </intent-filter>
    </service>

  <!-- For geofencing only -->
  <service android:name="com.leanplum.ReceiveTransitionsIntentService" />

  <activity
      android:name="[com.YOUR_PACKAGE].MainActivity"
      android:label="@string/app_name" >
      <intent-filter>
          <action android:name="android.intent.action.MAIN" />
          <category android:name="android.intent.category.LAUNCHER" />
      </intent-filter>
  </activity>
</application>

</manifest>
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="[com.YOUR_PACKAGE]"
    android:versionCode="1"
    android:versionName="1.0" >

<uses-sdk
    android:minSdkVersion="14" />
<!-- Base permissions for Leanplum Android SDK. -->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.INTERNET"/>

<!-- GCM requires a Google account (necessary only if if the device is running a version lower than Android 4.0.4). -->
<uses-permission android:name="android.permission.GET_ACCOUNTS"/>

<!-- Optional. Prevents the device from sleeping when a message is received. -->
<uses-permission android:name="android.permission.WAKE_LOCK"/>

<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE"/>
<permission android:name="[com.YOUR_PACKAGE].permission.C2D_MESSAGE"
    android:protectionLevel="signature" />
<uses-permission android:name="[com.YOUR_PACKAGE].permission.C2D_MESSAGE" />

<!-- These permissions are required only for geofencing. -->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>

<application
  android:allowBackup="true"
  android:icon="@drawable/ic_launcher"
  android:label="@string/app_name"
  android:theme="@style/AppTheme"
  android:name=".[YOUR_APPLICATION_CLASS]" >

    <meta-data
        android:name="com.google.android.gms.version"
        android:value="@integer/google_play_services_version" />

    <receiver
        android:name="com.google.android.gms.gcm.GcmReceiver"
        android:exported="true"
        android:permission="com.google.android.c2dm.permission.SEND" >
        <intent-filter>
            <action android:name="com.google.android.c2dm.intent.RECEIVE" />
            <action android:name="com.google.android.c2dm.intent.REGISTRATION" />
            <category android:name="[com.YOUR_PACKAGE]" />
        </intent-filter>
    </receiver>

    <receiver
        android:name="com.leanplum.LeanplumPushReceiver"
        android:exported="false" >
        <intent-filter>
            <action android:name="com.leanplum.LeanplumPushListenerService" />
        </intent-filter>
    </receiver>


    <service android:name="com.leanplum.LeanplumLocalPushListenerService" />

    <service android:name="com.leanplum.LeanplumPushRegistrationService" />

    <service
        android:name="com.leanplum.LeanplumPushListenerService"
        android:exported="false" >
        <intent-filter>
            <action android:name="com.google.android.c2dm.intent.RECEIVE" />
        </intent-filter>
    </service>

    <service
        android:name="com.leanplum.LeanplumPushInstanceIDService"
        android:exported="false">
        <intent-filter>
            <action android:name="com.google.android.gms.iid.InstanceID" />
        </intent-filter>
    </service>

  <!-- For geofencing only -->
  <service android:name="com.leanplum.ReceiveTransitionsIntentService" />

  <activity
      android:name="[com.YOUR_PACKAGE].MainActivity"
      android:label="@string/app_name" >
      <intent-filter>
          <action android:name="android.intent.action.MAIN" />
          <category android:name="android.intent.category.LAUNCHER" />
      </intent-filter>
  </activity>
</application>

</manifest>

Edit your application class

Add the following to your application class. If your application class does not extend LeanplumApplication, you must call enableLifecycleCallbacks (like the example below). Failure to do so will prevent the SDK from properly tracking states and displaying in-app messages on app resume.

If you want to use one or more push services alongside Leanplum's push service, you'll need to create a custom class that extends the correct Leanplum push messaging class. See our guide here.

For tighter security, remove your development key from your application class before submitting to the Play Store.

package [com.YOUR_PACKAGE];

import com.leanplum.Leanplum;

// For tracking user sessions.
import com.leanplum.LeanplumActivityHelper;
// For push notifications.
import com.leanplum.LeanplumPushService;

import com.leanplum.annotations.Parser;
import com.leanplum.annotations.Variable;
import com.leanplum.callbacks.StartCallback;
import com.leanplum.callbacks.VariablesChangedCallback;

public class ApplicationClass extends Application {

  @Override
  public void onCreate() {
    super.onCreate();

    Leanplum.setApplicationContext(this);
    Parser.parseVariables(this);
    //  For session lifecyle tracking.
    LeanplumActivityHelper.enableLifecycleCallbacks(this);

    // Insert your API keys here.
    if (BuildConfig.DEBUG) {
      Leanplum.setAppIdForDevelopmentMode("Your App ID", "Your Development Key");
    } else {
      Leanplum.setAppIdForProductionMode("Your App ID", "Your Production Key");
    }

    // Optional: Tracks all screens in your app as states in Leanplum.
    // Leanplum.trackAllAppScreens();

    // This will only run once per session, even if the activity is restarted.
    Leanplum.start(this);
    ...
  }
  ...
}

If you are still using Google Cloud Messaging, you'll need to call setGcmSenderId in the onCreate method of your Application class. See more below.

// Optional: For Google Cloud Messaging ONLY
LeanplumPushService.setGcmSenderId(SENDER_ID);

Set up push notifications

Below are setup instructions for using either FCM or GCM. If you want to use other push services with Leanplum's, see our guide to using multiple push services.

If you target Android 8.0 (API level 26) or above, you must register at least one notification channel in order to send notifications to users with devices running Android 8.0 (level 26) or later. See our guide to Using Android Notification Channels.

To use Firebase Cloud Messaging (FCM) with Leanplum, you need to:

  1. Verify that your Gradle files include the correct FCM and Leanplum libraries (see above).
  2. Download your google-services.json config file (see how here).
  3. Add the above file to your root app/ folder.
Adding config file to app folder

Adding config file to app folder

  1. Copy your FCM Server Key. In the Firebase console, click the gear icon next to Overview, then click Project Settings.
Open settings in Firebase console

Open settings in Firebase console

Then, in your project's settings, go to the Cloud Messaging tab. In this section of your settings, you will see your Server key. Copy the key.

Server key in FCM Console

Server key in FCM Console

  1. Add your FCM Server Key to Leanplum. In the Leanplum dashboard, in your App Settings click Keys & Settings. Go to the Push Notifications tab and enter/paste your key into the Google API key field.
Add key to Leanplum dashboard

Add key to Leanplum dashboard

To use Google Cloud Messaging (instead of Firebase), you need to:

  1. Register your GCM Push service in your Application class. You can do this one of three ways:
// OPTION 1: Register with Leanplum's Sender ID.
// LeanplumPushService.setGcmSenderId(LeanplumPushService.LEANPLUM_SENDER_ID);

// OPTION 2: Register your own Sender ID.
// LeanplumPushService.setGcmSenderId(YOUR_SENDER_ID);

// OPTION 3: Register with a Registration Id.
// LeanplumPushService.setGcmRegistrationId(YOUR_REGISTRATION_ID);

Leanplum.start();
  1. Add your Legacy Server Key to Leanplum. If you use your own ID, you need to give Leanplum permission to send notifications on your behalf. Paste your Legacy Server Key (this is different from your sender ID!) into the Google API Key field in the Push Notification tab of your App's Keys & Settings. You do not need to do this if you register with the LEANPLUM_SENDER_ID.

Google is deprecating GCM. To see how to switch to FCM, see our guide on Migrating to Firebase, or Google's setup instructions for more information.

Add Proguard configuration

This is only needed in your proguard-project.txt if you use Proguard to obfuscate your code, and if you install via JAR. Our AAR library already includes this configuration.

-keepclassmembers class *
{
  @com.leanplum.annotations.* <fields>;
}
-keep class com.leanplum.** { *; }
-dontwarn com.leanplum.**

Verify your setup (Android)

For testing purposes, run your app in Debug/development mode using the Development key. The Production key should be used when the app is pushed live and used by real users in production.

The Development key is used to:

  • Send data to the development/test pipeline (via an open web socket in real-time)
  • Log processes in the debugger for validation
  • See and register your developer devices in the dashboard
  • Force your test device into specific A/B test variants
  • Keep your data segregated from the live users (instead it will show up in the Developer Activity section)
  • Update custom templates and variables to the content management system

Never use a development key in a production/live build.

Using a development key utilizes an open socket for real-time analytics, but this pipeline cannot support real users (in a production build). Additionally, any user data will be lost as it is not captured in analytics.

Run your project and register your device

Registering a test device will allow you to test your messages, variable changes, and other Leanplum projects on a real device.

To register your device, first make sure you're in Debug mode. Then, from the Leanplum dashboard, go to Devices then hover over your device and click Register.

Next, go to Devices in the Leanplum dashboard, then hover over your device and click Register.

Test in-app messaging

Send yourself an in-app message to see it in action. While running your device in Debug mode, go to the Leanplum Message Composer. Create a new message and click Send Preview. The message will be sent to all registered test devices.

Create a custom variable (optional)

Variables you define will show up in the Leanplum dashboard, where you can change them, segment them, and A/B test them without having to update your app. You can verify the variable has been set by checking the Variables tab in the Leanplum dashboard.

Add the following lines to your application class or another class of your choosing:

import com.leanplum.annotations.Variable;
import com.leanplum.annotations.Parser;

public class ApplicationClass extends Application {

  // All variables must be defined before calling Leanplum.start.
  // Use the Parser class (see docs) since your variables are outside of your main activity.
  @Variable public static String welcomeMessage = "Welcome to Leanplum!";

  @Override
  public void onCreate() {
    ...
    // Be sure to set the context to this in the Parser.
    Parser.parseVariables(this);

    // It's important to use the variables changed callback if the value is needed
    // around the time the app starts, so that we're guaranteed to have the latest value.
    Leanplum.addVariablesChangedHandler(new VariablesChangedCallback() {
      @Override
      public void variablesChanged() {
        Log.i("Test", welcomeMessage);
      }
    });
    ...

    Leanplum.start();
  }
}

See Defining variables for more on setting up variables.

Track an event (Optional)

Events allow you to measure statistics about what your users do inside your app. You can also use events to target users for certain messages, tests, or other content changes. You can verify when an event is tracked in the Debugger or the Events tab in the Leanplum dashboard.

Add the following lines of code to track an event. You can place the Leanplum track call anywhere after calling start. For example:

import com.leanplum.annotations.Variable;
import com.leanplum.annotations.Parser;

public class ApplicationClass extends Application {

  @Variable public static String welcomeMessage = "Welcome to Leanplum!";

  @Override
  public void onCreate() {
    ...
    Parser.parseVariables(this);

    Leanplum.addVariablesChangedHandler(new VariablesChangedCallback() {
      @Override
      public void variablesChanged() {
        Log.i("Test", welcomeMessage);
        Leanplum.track("Launch");
      }
    });
    ...

    Leanplum.start();
  }
}

See Events for more on tracking events in Leanplum.

Suggest Edits

Unity setup

 

Our Unity SDK includes both a native Unity implementation of the Leanplum SDK as well as wrappers around the native iOS and Android SDKs. This setup allows us to provide feature parity on the iOS and Android platforms while still retaining support for other Unity platforms. The following matrix shows the features supported on each platform:

Feature
iOS
Android
Standalone

Data modeling

Analytics

Unity asset bundles

-

-

In-app messaging

-

Push notifications

-

Supports Unity 5.0 and above for Android, iOS, and Standalone platforms.

Import the UnityPackage into your project

Make sure you import the directories Plugins and Standard Assets. Optionally import Editor, and/or LeanplumSample to include a sample project demonstrating how to manipulate the speed of rain with a Leanplum variable.

Add the Leanplum Prefab

Copy the Leanplum Prefab from Standard Assets/Leanplum into the first scene in your project that loads. Make sure the prefab is linked with the script LeanplumWrapper.cs. This GameObject will persist across scene changes so you don't have to worry about adding it to other scenes.

Add your app keys

Copy your app ID and keys into the Leanplum GameObject's inspector. You can find these in App Settings > Keys & Settings.

Initialize the SDK

The code in LeanplumWrapper.cs initializes the SDK. If you require asset bundle support on iOS and Android, you can switch to use the native Unity implementation for all platforms. However, this means that you won't get in-app messaging or push notification support.

The code snippets on this page exists only in the LeanplumSDK namespace. Remember to add the following to every source file that calls Leanplum's functions.

using LeanplumSDK;

Verify the setup

For testing purposes, run your app in Debug/development mode using the Development key. The Production key should be used when the app is pushed live and used by real users in production.

The Development key is used to:

  • Send data to the development/test pipeline (via an open web socket in real-time)
  • Log processes in the debugger for validation
  • See and register your developer devices in the dashboard
  • Force your test device into specific A/B test variants
  • Keep your data segregated from the live users (instead it will show up in the Developer Activity section)
  • Update custom templates and variables to the content management system

Never use a development key in a production/live build.

A development key uses an open socket for real-time analytics, but this pipeline cannot support real users (in a production build). Additionally, any user data will be lost as it is not captured in analytics.

Run your project and register your device

Make sure the Development Build checkbox is checked in Unity's Build Settings menu. From the Leanplum dashboard, go to Devices then hover over your device and click Register.

Create a custom variable (optional)

The variables you define with Leanplum will show up in the Leanplum dashboard, where you can change them, segment them, and A/B test them without having to update your app. You can verify the variable has been set by viewing the Variables tab in Leanplum.

Add the highlighted lines to your app delegate or another class of your choosing:

using LeanplumSDK;

public class LeanplumWrapper : MonoBehaviour
{   ...
    private Var<string> welcomeMessage;

    void Start()
    {   ...
        // Avoid assigning the variable where its declared up top becuase
        // that code may run multiple times and will produce an error.
        welcomeMessage = Var<string>.Define("welcomeMessage", "Welcome to Leanplum!");
        Leanplum.Start();
    }

    void OnEnable()
    {
        // It's important to use the variables changed callback or welcomeMessage.ValueChanged if the
        // value is needed around the time the app starts, so that we're guaranteed to have the latest value.
        Leanplum.VariablesChanged += OnLeanplumOnVariablesChanged;
    }

    void OnDisable()
    {
        Leanplum.VariablesChanged -= OnLeanplumOnVariablesChanged;
    }

    private void OnLeanplumOnVariablesChanged()
    {
        Debug.Log(welcomeMessage.Value);
    }
}

See Defining variables for more on using variables with Leanplum.

Track an event (optional)

Events allow you to measure statistics about what your users do inside your app. You can also trigger messages and other content changes after certain events. You can verify an event is tracked in the Debugger or Events tabs in the Dashboard.

Add the highlighted line of code to track an event. You can place it anywhere after calling start. Example:

using LeanplumSDK;

public class LeanplumWrapper : MonoBehaviour
{   ...
    void Start()
    {   ...
      Leanplum.Track("Launch");
    }
}

See Events for more on tracking events with Leanplum.

Suggest Edits

JavaScript setup

 

Install the SDK

Download Leanplum JavaScript SDK

Add leanplum.js to your project

<script type="text/javascript" src="leanplum.js"></script>

Add sw.min.js to your project

To use web push in your app, you must add the Service Worker file sw.min.js from our SDK to your root directory, then register the Service Worker and user for push notifications.

For more see Push notifications.

Initialize Leanplum

// This value should be set to true only if you're developing on your server.
var isDevelopmentMode = true;

// Sample variables. This can be any JSON object.
var variables = {
 items: {
   color: 'red',
   size: 20,
   showBadges: true
 },
 showAds: true
};

// We've inserted your Test API keys here for you :)
if (isDevelopmentMode) {
 Leanplum.setAppIdForDevelopmentMode("YOUR_APP_ID", "YOUR_DEVELOPMENT_KEY");
} else {
 Leanplum.setAppIdForProductionMode("YOUR_APP_ID", "YOUR_PRODUCTION_KEY");
}

Leanplum.setVariables(variables);
Leanplum.start(function(success) {
 console.log('Success: ' + success);
 console.log('Variables', Leanplum.getVariables());
});

Verify the setup

For testing purposes, run your app in Debug/development mode using the Development key. The Production key should be used when the app is pushed live and used by real users in production.

The Development key is used to:

  • Send data to the development/test pipeline (via an open web socket in real-time)
  • Log processes in the debugger for validation
  • See and register your developer devices in the dashboard
  • Force your test device into specific A/B test variants
  • Keep your data segregated from the live users (instead it will show up in the Developer Activity section)
  • Update custom templates and variables to the content management system

Never use a development key in a production/live build.

Using a development key utilizes an open socket for real-time analytics, but this pipeline cannot support real users (in a production build). Additionally, any user data will be lost as it is not captured in analytics.

Register your device

Be sure to run your app in development mode. From the Leanplum dashboard, go to Devices then hover over your device and click Register.

How to track events in your app

Leanplum.track("View Cart");
Leanplum.track("View Cart", {itemsInCart: 4});
Leanplum.track("Purchase", 4.99, {itemCategory: 'Apparel', itemName: 'Shoes'});

How to track states transitions. These are sections of your app the user is in.

Leanplum.advanceTo("Cart");
Leanplum.advanceTo("Level", level.name);

// The 'null' state. Causes the user to leave the current state and not enter another one.
Leanplum.advanceTo(null);

Passing custom user IDs.

Leanplum.start('mike3958');

Passing user attributes. User attributes are applied to the user, so they're saved across sessions. If an attribute no longer applies, you can set it to null.

Leanplum.start({hasFacebookProfile: true});
Leanplum.start('userId', {age: 20, gender: 'Male'}, callback);

Starts Leanplum by simply loading the cached variables, and doesn't log a new session. Useful for subsequent page loads inside the app.

Leanplum.startFromCache('mike3958');

How to track the session lifecycle.

Leanplum.pauseSession();  // Pauses the current session.
Leanplum.resumeSession();  // Resumes the current session.
Leanplum.stop();  // Ends the current session. Sessions will automatically timeout after 2 hours if stop isn't called explicitly (30 minutes if paused).

Javascript SDK settings

Set the path of the API server.

Leanplum.setApiPath('https://www.leanplum.com/api');

Set the email address of the developer. This prevents the email prompt from being displayed. Set a blank email to prevent Leanplum from being registered.

Leanplum.setEmail('myself@gmail.com');

Sets whether Leanplum checks for and alerts about updates at startup in development mode (Default: true).

Leanplum.setUpdateCheckingEnabledInDevelopmentMode(false);

Sets the network timeout in seconds. (Default: 10).

Leanplum.setNetworkTimeout(5);

Sets the request batching strategy. This applies to production mode only. The default behavior is to batch every 5 seconds.

Leanplum.setRequestBatching(false); // No batching.
Leanplum.setRequestBatching(true); // Batching enabled. Unsent requests are sent on start, pauseSession, resumeSession, and stop
Leanplum.setRequestBatching(true, 30); // Same as above except unsent requests are also sent every 30 seconds.

Sets a function for prompting the user for information. This is called to ask for an email address in development mode.

Leanplum.setPromptFunction(function(message, defaultValue, callback) {
  callback(prompt(message, defaultValue));
});

Enables development mode, and sets the app ID and client key.

Leanplum.setAppIdForDevelopmentMode('appId', 'clientKey');

Enables production mode, and sets the app ID and client key.

Leanplum.setAppIdForProductionMode('appId', 'clientKey');

Sets a custom device ID. If this is not called, Leanplum will assign a device ID automatically.

Leanplum.setDeviceId('DevId');

Sets the current version of your app.

Leanplum.setAppVersion('1.0.1');

Sets the device name to override the default.

Leanplum.setDeviceName("Andrew's iMac");

Sets the device model to override the default.

Leanplum.setDeviceModel('Mac');

Sets the system name to override the default.

Leanplum.setSystemName('Mac OS X');

Sets the system version to override the default.

Leanplum.setSystemVersion('10.8');
Suggest Edits

Manual SDK setup

 

If you'd rather set up your SDK manually, see below for iOS and Android instructions.

Suggest Edits

Manual setup iOS

Setting up the SDK manually

 

You can install our SDK manually using the steps below for iOS.

Install the SDK

First, Download Leanplum iOS SDK.

Supports iOS 7.0 and above.

Add Leanplum.framework to your project

Drop the .framework package into the "Embedded Binaries" list in your targets > general tab. This will add the .framework to "Linked Frameworks and Libraries" as well.

If you are using the static version of our framework, you only need to add it to "Linked Frameworks and Libraries".

If you want to use Location services on Leanplum, add LeanplumLocation.framework. Alternatively, if you also need iBeacon services on Leanplum, add LeanplumLocationAndBeacons.framework.

Add Leanplum frameworks to your project

Add CFNetwork, SystemConfiguration, Security, AdSupport, and StoreKit frameworks. AdSupport and StoreKit can be marked as Optional. IDFA is only used (optionally) in development mode and not in the build sent to the App Store. If you're linking LeanplumLocation or LeanplumLocationAndBeacons, add CoreLocation.

Add the -ObjC -fobjc-arc linker flags (optional)

This is only needed if your project has CLANG_ENABLE_OBJC_ARC or Objective-C Automatic Reference Counting set to NO (aka ARC disabled). By default ARC is enabled, so this flag is only needed if you have disabled ARC.

The -ObjC flag may not be compatible with certain libraries. You can replace it with -force_load ${SRCROOT}/Leanplum.framework/Leanplum. Make sure the path matches the location of Leanplum.framework on your filesystem.

Strip framework script (for release builds)

In order to submit a release build of the app to the App Store, you must make sure that the following script is in place to strip the framework to valid architectures. Navigate to 'Build Phases' in your project, add 'New Run Script', and move the 'New Run Script' after the Embed Frameworks. Then add the following code:

cd "${BUILT_PRODUCTS_DIR}/${FRAMEWORKS_FOLDER_PATH}/Leanplum.framework/"
lipo -remove i386 -remove x86_64 Leanplum -output Leanplum

Make sure to check 'Run script only when installing'. Once completed, the setup should look like the following:

Add DEBUG flag (optional)

Add -D DEBUG to Other Swift Flags only for Debug mode.

Edit your AppDelegate

Remember to import Leanplum before doing anything. You can avoid this by adding the import to your app's prefix header (.pch) file.

For tighter security, remove your development key from your app delegate before submitting to the App Store.

import UIKit
#if DEBUG
    import AdSupport
#endif
import Leanplum

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

var window: UIWindow?

func application(application: UIApplication!, didFinishLaunchingWithOptions launchOptions: NSDictionary!) -> Bool {
  // We've inserted your Test API keys here for you :)
  #if DEBUG
    Leanplum.setDeviceId(ASIdentifierManager.shared().advertisingIdentifier.uuidString)
    Leanplum.setAppId("YOUR_APP_ID",
      withDevelopmentKey:"YOUR_DEVELOPMENT_KEY")
  #else
    Leanplum.setAppId("YOUR_APP_ID",
      withProductionKey: "YOUR_PRODUCTION_KEY")
  #endif

  // Optional: Tracks in-app purchases automatically as the "Purchase" event.
  // To require valid receipts upon purchase or change your reported
  // currency code from USD, update your app settings.
  // Leanplum.trackInAppPurchases()

  // Optional: Tracks all screens in your app as states in Leanplum.
  // Leanplum.trackAllAppScreens()

  // Optional: Activates UI Editor.
  // Requires the Leanplum-iOS-UIEditor framework.
  // LeanplumUIEditor.shared().allowInterfaceEditing()

  // Starts a new session and updates the app content from Leanplum.
  Leanplum.start()

  return true
}
...
#import "AppDelegate.h"
#import <Leanplum/Leanplum.h>

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
  // Insert your API keys here.
  #ifdef DEBUG
    LEANPLUM_USE_ADVERTISING_ID;
    [Leanplum setAppId:@"YOUR_APP_ID"
     withDevelopmentKey:@"YOUR_DEVELOPMENT_KEY"];
  #else
    [Leanplum setAppId:@"YOUR_APP_ID"
     withProductionKey:@"YOUR_PRODUCTION_KEY"];
  #endif

  // Optional: Tracks in-app purchases automatically as the "Purchase" event.
  // To require valid receipts upon purchase or change your reported
  // currency code from USD, update your app settings.
  // [Leanplum trackInAppPurchases];

  // Optional: Tracks all screens in your app as states in Leanplum.
  // [Leanplum trackAllAppScreens];

  // Optional: Activates UI Editor.
  // Requires the Leanplum-iOS-UIEditor framework.
  // [[LeanplumUIEditor sharedEditor] allowInterfaceEditing];

  // Sets the app version, which otherwise defaults to
  // the build number (CFBundleVersion).
  [Leanplum setAppVersion:@"2.4.1"];

  // Starts a new session and updates the app content from Leanplum.
  [Leanplum start];
  return YES;
}
...

@end

Verify the setup

Verify the setup

When testing your build, run your app in Debug/development mode using the Development key. Use the Production key when the app is pushed live (to be used by real users/in production).

The Development key is used to:

  • Send data to the development/test pipeline (via an open web socket in real-time)
  • Log processes in the debugger for validation
  • See and register your developer devices in the dashboard
  • Force your test device into specific A/B test variants
  • Keep your data segregated from the live users (instead it will show up in the Developer Activity section)
  • Update custom templates and variables to the content management system

Never use a development key in a production/live build.

Using a development key utilizes an open socket for real-time analytics, but this pipeline cannot support real users (in a production build). Additionally, any user data will be lost as it is not captured in analytics.

Run your project and register your device

Make sure you're in Debug mode. To ensure Debug mode is enabled, make sure the DEBUG preprocessor macro is set in Build Settings.

From the Leanplum dashboard, go to Devices then hover over your device and click Register.

Test in-app messaging

Send yourself an in-app message to see it in action. While running your device in Debug mode, go to the Leanplum Message Composer. Create a new message and click Send Preview. The message will be sent to all registered test devices.

Create a custom variable (optional)

The variables you define will show up in the Leanplum dashboard, where you can change them, segment them, and A/B test them without having to update your app. You can verify the variable has been set by viewing the Variables tab in the Leanplum dashboard.

Add the following lines to your app delegate or another class of your choosing:

import UIKit
import Foundation

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow?
    var welcomeMessage = LPVar.define("welcomeMessage",
    withString: "Welcome to Leanplum!")

    func application(application: UIApplication!, didFinishLaunchingWithOptions launchOptions: NSDictionary!) -> Bool {
        ...
        Leanplum.onVariablesChanged({
            NSLog((self.welcomeMessage?.stringValue())!)
        })
        ...
        return true
    }
...
#import <Leanplum/Leanplum.h>

DEFINE_VAR_STRING(welcomeMessage, @"Welcome to Leanplum!");

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{ ...
  [Leanplum onVariablesChanged:^{
    NSLog(@"%@", welcomeMessage.stringValue);
  }];
  return YES;
}
...
@end

It's important to use the variables changed callback onVariablesChanged, or welcomeMessage.onValueChanged (for our example variable welcomeMessage), if the value is needed around the time the app starts. This guarantees the latest value. See more on how to handle asynchronous code with Callbacks.

For more on Variables, see Defining variables.

Track an event (optional)

Events allow you to measure statistics about what your users do in your app. You can also use events to trigger messages and other content changes. You can verify an event is tracked in the Debugger or Events tabs in the Leanplum dashboard.

Add the following lines of code to track an event. You can place it anywhere after calling start. Example:

import UIKit
import Foundation

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow?
    var welcomeMessage = LPVar.define("welcomeMessage", withString: "Welcome to Leanplum!")

    func application(application: UIApplication!, didFinishLaunchingWithOptions launchOptions: NSDictionary!) -> Bool {
        ...
        Leanplum.onVariablesChanged({
            NSLog((self.welcomeMessage?.stringValue())!)
            Leanplum.track("Launch")
        })
        ...
        return true
    }
...
#import <Leanplum/Leanplum.h>

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{ ...
  [Leanplum onVariablesChanged:^{
    NSLog(@"%@", welcomeMessage.stringValue);
    [Leanplum track:@"Launch"];
  }];
  return YES;
}
...
@end

For more on tracking events with Leanplum, see Events.

Suggest Edits

Variables

Defining variables with the Leanplum SDK

 

You can create variables that can take on new values from the server. Using variables in the Leanplum dashboard allows you to roll out changes without having to push an update through the App Store or Google Play. You can also create A/B tests to change variables for only a percentage of your users.

Variable data comes back asynchronously after you call start. If you need to use a variable when the app starts, make sure you use Callbacks.

When you define a variable in your code, it will appear in the Variables tab in Leanplum the next time your app starts in development mode.

iOS

It's important to define all of your variables before calling Leanplum.Start. Use periods to group variables on the dashboard.

Objective-C

Define variables outside of your methods, like you would a constant, using our DEFINE_VAR macros. Use underscores in the name to group values into a structured variable. See Modeling structured data for examples.

Swift

Swift doesn't support macros like Objective-C. Instead, define variables using LPVar.define directly. Use dots in the name to group values into a structured variable. See Modeling structured data for examples.

With Swift, you must define all of your Leanplum variables before calling Leanplum.start.

To access a variable in another controller or file, call define again; the first define call (before start) will set the value, subsequent calls will return the cached value. Be careful where you place define calls to ensure the first call is truly called first.

See Variable types for more specifics on each type of variable.

Android (Java)

There are two ways to define variables.

  1. Using the @Variable annotation on public static class members
    This is the easiest and most convenient way to define variables.
public class MainActivity extends LeanplumActivity {
    @Variable public static String welcomeLabel = "Welcome!";
    ...
}

You can use this method to define variables:

  • Inside your Application class if it extends LeanplumApplication.
  • In your main activity if it extends one of the LeanplumActivityclasses and calls Leanplum.start.
  • In another class. Use the Parser class to detect the annotations before calling Leanplum.start.

If you choose to define variables in an Activity or Class that does make your start call, you will need to use Parser.parseVariablesForClasses to collect these variable definitions before your start call.

For example, if we have variables defined in ClassA and ClassB, we need to add the following to our ApplicationClass before start:

...
import com.leanplum.annotations.Parser;
...
public class ApplicationClass extends LeanplumApplication {

  @Override
  public void onCreate() {
    super.onCreate();
    Leanplum.setApplicationContext(this);
    ...
    // Parse variables from other classes.
    Parser.parseVariablesForClasses(ClassA.class, ClassB.class);
    // Then, call start.
    Leanplum.start();
  }

}

If you define your variables in an ApplicationClass or Activity where you call start, and the class does not extend LeanplumApplication or LeanplumActivity, then you must use the Parser class to detect that class's variable annotations.

...
import com.leanplum.annotations.Parser;
...
public class ApplicationClass extends Application {

  @Variable
  public static String welcome = "Hi there!";

  @Override
  public void onCreate() {
    super.onCreate();
    Leanplum.setApplicationContext(this);
    ...
    // Parse variables from this class.
    Parser.parseVariables(this);
    // Then, call start.
    Leanplum.start();
  }

}
  1. Using Var.define
public class MainActivity extends LeanplumActivity {
    public static Var<String> welcomeLabel = Var.define("welcomeLabel", "Welcome!");
  ...
}

You must define variables with this method before calling Leanplum.start.

Unity

It's important to define all of your variables before calling Leanplum.Start. Use periods to group variables on the dashboard.

JavaScript (HTML5)

Sets your variables:

Leanplum.setVariables({
  StoreTitle: "Powerup Store",
  Items: [
    {
      name: "Speed Boost",
      price: 100
    }, {
      name: "Health Boost",
      price: 150
    }
  ]
});

Gets your variables:

var variables = Leanplum.getVariables();
//Gets a particular variable.
var title = Leanplum.getVariable('StoreTitle');
var speedBoost = Leanplum.getVariable('Items', 0);
var healthBoostName = Leanplum.getVariable('Items', 1, 'name');

See Variable types for more specifics on each type of variable.

Suggest Edits

Variable types

Examples of how to set and access variable values for different types of variables in Leanplum.

 

Float

//Set the value with the macro LPVar.define. To access the value in your code, use the floatValue method.

var shootSpeed = LPVar.define("shootSpeed", with:1.0); // How fast your ship shoots.
...
Leanplum.onVariablesChanged {
  // Move ship according to its speed.
  myShip.moveWithSpeed(shootSpeed?.floatValue())
}
//Set the value with the macro DEFINE_VAR_FLOAT. To access the value in your code, use the floatValue method.

DEFINE_VAR_FLOAT(shootSpeed, 1.0);  // How fast your ship shoots.
...
[Leanplum onVariablesChanged:^() {
  // Move ship according to its speed.
  [myShip moveWithSpeed:shootSpeed.floatValue];
}];
@Variable public static float shootSpeed = 1;  // How fast your ship shoots.
Var<float> shootSpeed = Var<float>.Define("shootSpeed", 1.0);  // How fast your ship shoots.
...
void MoveShip() {
    MoveWithSpeed(shootSpeed.Value);
}

Boolean

//Set the value with the macro LPVar.define. To access the value in your code, use the boolValue method.

var showAds = LPVar.define("showAds", with: false) // Whether or not to show ads in the app.
...
Leanplum.onVariablesChanged {
  if(showAds?.boolValue())! {
    self.view.addSubview(adView)
  }
}
//Set the value with the macro DEFINE_VAR_BOOL. To access the value in your code, use the boolValue method.

DEFINE_VAR_BOOL(showAds, false);  // Whether or not to show ads in the app.
...
[Leanplum onVariablesChanged:^() {
  if (showAds.boolValue) {
    [self.view addSubview:adView];
  }
}];
// The variable showAds will show up on our dashboard as "Show Ads".
@Variable(name="Show Ads") public static boolean showAds = false;  // Whether or not to show ads in the app.
// Boolean with custom name: the variable showAds will show up on our dashboard as "Show Ads".
Var<bool> showAds = Var<bool>.Define("Show Ads", false);
...
void ShowAds() {
  if (showAds.Value) {
    MakeAdBanner();
  }
}

String

//Set the value with the macro LPVar.define. To access the value in your code, use the stringValue method.

var startLabel = LPVar.define("startLabel", with: "Start") // Label of the "Start" button
...
Leanplum.onVariablesChanged {
  let startButton: UIButton = UIButton()
  startButton.setTitle(startLabel?.stringValue(), for: .normal)
  self.view.addSubview(startButton)
}
//Set the value with the macro DEFINE_VAR_STRING. To access the value in your code, use the stringValue method.

DEFINE_VAR_STRING(startLabel, @"Start");  // Label of the "Start" button.
...
[Leanplum onVariablesChanged:^() {
  UIButton* startButton = [[UIButton alloc] init];
  startButton.text = startLabel.stringValue;
  [self.view addSubview:startButton];
}];
// The variable startLabel will show up on our dashboard within the group "mainScreen".
@Variable(group="mainScreen") public static String startLabel = "Start";  // Label of the "Start" button.

// Use "." to nest groups. You can also use "." with the "name" argument.
@Variable(group="screens.mainScreen") public static String startLabel = "Start";  // Label of the "Start" button.
String
Var<string> startLabel = Var<string>.Define("startLabel", "Start");  // Label for "Start" button.
...
void CreateStartButton() {
  AddButtonWithText(startLabel.Value);
}

Color

//Set the value with the macro LPVar.define. 
//To access the value in your code, use the colorValue method.

var myColor = LPVar.define("myColor", with: UIColor.gray)
...
Leanplum.onVariablesChanged {
  startButton.setTitleColor(myColor?.colorValue(), for: .normal)
}
//Set the value with the macro DEFINE_VAR_COLOR. To access the value in your code, use the colorValue method.

DEFINE_VAR_COLOR(myColor, [UIColor colorWithRed:14.0/255.0 green:114.0/255.0 blue:199.0/255.0 alpha:1]);
...
[Leanplum onVariablesChanged:^() {
  [startButton setTitleColor:myColor.colorValue];
}];

Assets

File variables work like variables except that the file data comes back from Leanplum separately. When you edit a file variable, you change its filename. If a file with the same name does not exist on the device, it will download from Leanplum.

//Set the value with the macro LPVar.define using a withFile parameter. To access the value in your code, use the fileValue or imageValue method.

// Image
var goldStar = LPVar.define("goldStar", withFile: "gold_star.png") // Location of Gold Star image file.
...
Leanplum.onVariablesChanged {
  self.splashView?.image = goldStar?.imageValue()
}
//Set the value with the macro DEFINE_VAR_FILE. To access the value in your code, use the fileValue or imageValue method.

// Image and file.
DEFINE_VAR_FILE(goldStar, @"gold_star.png");  // Location of Gold Star image file.
DEFINE_VAR_FILE(config, @"config.plist");
...
[Leanplum onVariablesChanged:^() {
  // imageValue is compatible with Asset Catalogs.
  self.splashView.image = goldStar.imageValue;
  NSDictionary* config = [NSDictionary dictionaryWithContentsOfFile:config.fileValue];
}];
public static Var<String> mario = Var.defineAsset("Mario", "Mario.png");
...
mario.addFileReadyHandler(new VariableCallback<String>() {
    @Override
    public void handle(Var<String> variable) {
        im.setImageBitmap(BitmapFactory.decodeStream(mario.stream()));
    }
});
// It is necessary to specify platform-specific AssetBundles as they are not cross-platform.
// The filenames specified when defining an AssetBundle represent the default
// bundles that will be loaded if present in Leanplum's file manager.

Var<AssetBundle> background = Var<AssetBundle>.DefineAssetBundle(
    "forestBackground",
    standaloneBundleName: "Standalone-Forest.unity3d",
    androidBundleName: "Android-Forest.unity3d",
    iosBundleName: "iOS-Forest.unity3d");
...
void LoadBackground() {
  if (background.Value != null) {
    Instantiate(background.Value.mainAsset);
  }
}

Dictionary

//Set the value with the macro LPVar.define. 
//To access a dictionary value in your code, use the objectForKey method to get to the correct property, then use an accessor method (stringValue, boolValue, floatValue, etc.) to get the actual value. 
//In Swift, you may need to cast after using objectForKey.

let powerUp = LPVar.define("powerUp", with: [
  "name": "Turbo Boost",
  "price": 150,
  "speedMultiplier": 1.5,
  "timeout": 15])
...
Leanplum.onVariablesChanged {
  self.speed = (powerUp?.object(forKey: "speedMultiplier") as! NSNumber).floatValue
}
//Set the value with the macro DEFINE_VAR_DICTIONARY_WITH_OBJECTS_AND_KEYS. To access a dictionary value in your code, use the objectForKey method to get to the correct property, then use an accessor method (stringValue, boolValue, floatValue, etc.) to get the actual value. 

DEFINE_VAR_DICTIONARY_WITH_OBJECTS_AND_KEYS(
  powerUp,
  @"Turbo Boost", @"name",
  @150, @"price",
  @1.5, @"speedMultiplier",
  @15, @"timeout",
  nil);
...
[Leanplum onVariablesChanged:^() {
  self.speed *= [[powerUp objectForKey:@"speedMultiplier"] floatValue];
}];
@Variable public static Map<String, Object> powerup = new HashMap<String, Object>() {
    {
        put("name", "Turbo Boost");
        put("price", 150);
        put("speedMultiplier", 1.5);
        put("timeout", 15);
        put("slots", Arrays.asList(1, 2, 3));
    }
};
Dictionary<string, object> powerupInit = new Dictionary<string, object>();
powerupInit.Add("price", 150);
powerupInit.Add("speedMultiplier", 1.5);
powerupInit.Add("timeout", 15);
Var<Dictionary<string, object>> powerup = Var<Dictionary<string, object>>.Define("powerup", powerupInit);

Array (List)

//Set the value with the macro LPVar.define.  
//To access a dictionary value in your code, use the objectAtIndex method to get to the correct object, then use an accessor method (stringValue, boolValue, floatValue, etc.) to get the actual value. 
//In Swift, you may need to cast after using objectAtIndex.

let storeItemsOrder = LPVar.define("storeItemsOrder", with: [0, 1, 2, 3, 4])
Leanplum.onVariablesChanged {
  for var i in 0..<storeItemsOrder!.count(){
    let item = storeItemsOrder!.object(at: i) as! NSNumber
    print(item.intValue)
    i += 1
  }
}
//Set the value with the macro DEFINE_VAR_ARRAY_WITH_OBJECTS.  To access a dictionary value in your code, use the objectAtIndex method to get to the correct object, then use an accessor method (stringValue, boolValue, floatValue, etc.) to get the actual value.

DEFINE_VAR_ARRAY_WITH_OBJECTS(storeItemsOrder, @0, @1, @2, @3, @4, nil);
...
[Leanplum onVariablesChanged:^(){
  for (int i = 0; i < storeItemsOrder.count; i++) {
    int item = [[storeItemsOrder objectAtIndex:i] intValue];
    NSLog(@"%i", item);
  }
}];
@Variable public static List<Integer> storeItemsOrder = Arrays.asList(1, 2, 3, 4);
Var<List<Object>> storeItemsOrder = Var<List<Object>>.Define("storeItemsOrder", new List<Object> { 0, 1, 2, 3, 4 });
Suggest Edits

Modeling structured data

 

Say you have a bunch of items in your app, and each item has properties. Leanplum gives you the flexibility to model one property of the object at a time, one object at a time, or the entire structure at once, depending on how you'd like to set up your code.

For example, if you want to create a structure like this:

Powerups: {
    Speed: {
        Price: 10,
        Duration: 5,
        OrderInStore: 0
    },
    Power: {
        Price: 15,
        Duration: 5,
        OrderInStore: 1
    }
}

You could model each individual field like so:

// Names or groups with a '.' are grouped automatically.
var speedPrice = LPVar.define("Powerups.Speed.Price", with:10)
var speedDuration = LPVar.define("Powerups.Speed.Duration", with:5)
var speedOrder = LPVar.define("Powerups.Speed.OrderInStore", with:0)

var powerPrice = LPVar.define("Powerups.Power.Price", with:15)
var powerDuration = LPVar.define("Powerups.Power.Duration", with:5)
var powerOrder = LPVar.define("Powerups.Power.OrderInStore", with:1)
// Names or groups with an '_' are grouped automatically.
DEFINE_VAR_FLOAT(Powerups_Speed_Price, 10);
DEFINE_VAR_FLOAT(Powerups_Speed_Duration, 5);
DEFINE_VAR_FLOAT(Powerups_Speed_OrderInStore, 0);

DEFINE_VAR_FLOAT(Powerups_Power_Price, 15);
DEFINE_VAR_FLOAT(Powerups_Power_Duration, 5);
DEFINE_VAR_FLOAT(Powerups_Power_OrderInStore, 1);
// Names or groups with a '.' are grouped automatically.
@Variable(name="Powerups.Speed.Price") double speedPrice = 10;
@Variable(name="Powerups.Speed.Duration") double speedDuration = 5;
@Variable(name="Powerups.Speed.OrderInStore") int speedOrder = 0;

@Variable(name="Powerups.Power.Price") double powerPrice = 15;
@Variable(name="Powerups.Power.Duration") double powerDuration = 5;
@Variable(name="Powerups.Power.OrderInStore") int powerOrder = 1;
// Names with a '.' are grouped automatically.
Var<int> speedPrice = Var<int>.Define("Powerups.Speed.Price", 10);
Var<int> speedDuration = Var<int>.Define("Powerups.Speed.Duration", 5);
Var<int> speedOrder = Var<int>.Define("Powerups.Speed.Order in Store", 0);

Var<int> powerPrice = Var<int>.Define("Powerups.Power.Price", 15);
Var<int> powerDuration = Var<int>.Define("Powerups.Power.Duration", 5);
Var<int> powerOrder = Var<int>.Define("Powerups.Power.Order in Store", 1);

Or you could model each object:

var powerUpsSpeed = LPVar.define("Powerups.Speed", with: [
  "Price": 10,
  "Duration": 5,
  "OrderInStore": 0
])
var powerUpsPower = LPVar.define("Powerups.Power", with: [
  "Price": 15,
  "Duration": 5,
  "OrderInStore": 1
])
DEFINE_VAR_DICTIONARY_WITH_OBJECTS_AND_KEYS(Powerups_Speed, @10, @"Price", @5, @"Duration", @0, @"OrderInStore", nil);
DEFINE_VAR_DICTIONARY_WITH_OBJECTS_AND_KEYS(Powerups_Power, @15, @"Price", @5, @"Duration", @1, @"OrderInStore", nil);
// Using the Google Guava library for brevity.
@Variable(group="Powerups") Map<String, Object> speed =
    ImmutableMap.of("Price", 10.0, "Duration", 5.0, "OrderInStore", 0);
@Variable(group="Powerups") Map<String, Object> duration =
    ImmutableMap.of("Price", 15.0, "Duration", 5.0, "OrderInStore", 1);
Var<Dictionary<string, object>> speed = Var<Dictionary<string, object>>.Define(
    "Powerups.Speed", new Dictionary<string, object>>() {
        { "Price", 10 },
        { "Duration", 5 },
        { "OrderInStore", 0 } });
Var<Dictionary<string, object>> power = Var<Dictionary<string, object>>.Define(
    "Powerups.Power", new Dictionary<string, object>>() {
        { "Price", 15 },
        { "Duration", 5 },
        { "OrderInStore", 1 } });

Or the entire structure:

var powerups = LPVar.define("Powerups", with: [
  "Speed": [
    "Price": 10,
    "Duration": 5,
    "OrderInStore": 0
  ],
  "Power": [
    "Price": 15,
    "Duration": 5,
    "OrderInStore": 1
  ]
])
LPVar* powerups;
static void __attribute__((constructor)) initObjects() {
    @autoreleasepool {
        powerups = [LPVar define:@"Powerups" withDictionary:@{
            @"Speed": @{@"Price" : @10, @"Duration": @5, @"OrderInStore": 0},
            @"Power": @{@"Price" : @15, @"Duration": @5, @"OrderInStore": 1}
        }];
    }
}
@Variable Map<String, Object> powerups = ImmutableMap.of(
    "Speed", ImmutableMap.of("Price", 10.0, "Duration", 5.0, "OrderInStore", 0),
    "Power", ImmutableMap.of("Price", 15.0, "Duration", 5.0, "OrderInStore", 1));
Var<Dictionary<string, Dictionary<string, object>>> speed = Var<Dictionary<string, Dictionary<string, object>>>.Define(
    "Powerups", new Dictionary<string, Dictionary<string, object>>() {
        { "Speed", new Dictionary<string, object>() {
            { "Price", 10 },
            { "Duration", 5 },
            { "Order in Store", 0 } } },
        { "Power", new Dictionary<string, object>() {
            { "Price", 15 },
            { "Duration", 5 },
            { "Order in Store", 1 } } }
        });

All of the above declarations will show up identically on our dashboard. Leanplum understands to group variables that use underscores (ObjC) or dots (Swift) in their names. The last method is convenient because instead of specifying the JSON data in code, you could potentially load it from a file and then convert it to a dictionary.

When the variable values are ready, you can get different slices of the variables using objectForKey[Path].

Using objectForKey:

NSDictionary* allPowerups = [powerups objectForKeyPath:nil];
NSDictionary* speedPowerup = [powerups objectForKey:@"Speed"];
float speedPrice = [[powerups objectForKeyPath:@"Speed", @"Price", nil] floatValue];
Map<String, Object> allPowerups = powerups.objectForKeyPath();
Map<String, Object> speedPowerup = powerups.objectForKeyPath("Speed");
float speedPrice = powerups.objectForKeyPath("Speed", "Price");
Suggest Edits

Callbacks

 

Because Leanplum variables and resources are retrieved from the server asynchronously after start, you need to wait for the values to be downloaded before using them in your code. The proper way to do this is to use one of the callbacks provided by our SDK.

The SDK will use locally-cached values, if available, and changes will only be synced on start or forceContentUpdate.

You can use callbacks multiple times across different classes in your app. However, where you place the callback may influence when it is executed. If you call one after the necessary variables (and/or files) for that callback have been synced, the code in the callback will just execute again immediately.

Timing

All callbacks are executed on start, regardless of whether the file(s) or variable(s) have changed. The distinction between our callbacks is their behavior on forceContentUpdate — namely, which files or variables will trigger the callback. You can watch a single variable, a single file, all variables, or all variables and all files.

You must be on version 1.3.0 or newer of our Javascript SDK for the forceContentUpdate method.

callback
executed when
  • start finishes.
  • start finishes.
  • forceContentUpdate finishes and a specific variable has changed.
  • start finishes.
  • forceContentUpdate finishes and any variable has changed.
  • start finishes.
  • forceContentUpdate finishes and a specific file has changed.
  • start finishes.
  • forceContentUpdate finishes and a file or variable has changed.

After Leanplum start

This callback is executed only when the start call finishes and all variables and files are returned from the Leanplum server. It will not be executed on forceContentUpdate.

You can use this callback with a splash screen to wait and then load a new view after start finishes, so you don't have to worry about checking when your variables have their values.

// Add a callback.
Leanplum.onStartResponse{ (success:Bool) in
  // Insert code here.
}
Leanplum.start()

// Or, add a responder that will be executed as a callback.
Leanplum.addStartResponseResponder(self, with: #selector(mySelector(success:)))

func mySelector(success:Bool){
  // Insert code here.
}
// Add a callback.
[Leanplum onStartResponse:^(BOOL success) {
  // Insert code here.
}];
[Leanplum start];

// Or, add a responder that will be executed as a callback.
[Leanplum addStartResponseResponder:self withSelector:@selector(mySelector:)];

- (void)mySelector:(BOOL) success {
  // Insert code here.
}
// Add a new callback.
Leanplum.addStartResponseHandler(new StartCallback() {
  @Override
  public void onResponse(boolean b) {
    // Insert code here.
  }
});
// Add a callback.
Leanplum.Started += delegate(bool success) {
  // Insert code here.
};
Leanplum.Start();
// Add a callback.
Leanplum.addStartResponseHandler(function(success) {
  // Insert code here.
});
Leanplum.start();

When a variable is ready

This callback is executed after start every time, but only after forceContentUpdate if a specific variable has changed (not supported on JavaScript).

// Define the variable with LPVar.define.
var startLabel = LPVar.define("startLabel", with: "Start")

// Then wrap your code in the callback.
startLabel?.onValueChanged({
  self.startButton.titleLabel.text = self.startLabel?.stringValue()
  // Insert code here.
})
// Define the variable with the correct macro.
DEFINE_VAR_STRING(startLabel, @"Start");

// Then wrap your code in the callback.
[startLabel onValueChanged:^{
  self.startButton.titleLabel.text = startLabel.stringValue;
  // Insert code here.
}];
// Define the file variable with Var.define.
Var<String> startLabel = Var.define("welcomeMessage", "Start");

// Then add a handler and pass it a new callback.
startLabel.addValueChangedHandler(new VariableCallback<String>() {
  @Override
  public void handle(Var<String> var) {
    // Insert code here.
  }
});
// Define the variable.
Var<string> startLabel = Var<string>.Define("startLabel", "Start");  

// Then, insert your code in a delegate added to ValueChanged.
startLabel.ValueChanged += delegate {
  // Insert code here.
};

This callback does not wait for files to finish downloading. If you are using file variables, see below.

When all variables are ready

This callback is executed after start every time, but only after forceContentUpdate if any variable has changed.

You can use forceContentUpdate (except in JavaScript) to re-sync with Leanplum during an active session.

Leanplum.onVariablesChanged { () in
  // Insert code here.
}
[Leanplum onVariablesChanged:^() {
  // Insert code here.
}];
Leanplum.addVariablesChangedHandler(new VariablesChangedCallback() {
  @Override
  public void variablesChanged() {
    // Insert code here.
  }
});
Leanplum.VariablesChanged += delegate {
  // Insert code here.
};
Leanplum.addVariablesChangedHandler(function(success){
  // Insert code here.
});

This callback does not wait for files to finish downloading. If you are using file variables, see below.

When a file is ready

This callback will execute after start every time, but only after forceContentUpdate when the file has changed. If the file is unchanged, no download will occur and the callback will not be executed.

// Define the file variable with LPVar.define.
var goldstarImage = LPVar.define("goldStar", withFile: "gold_star.png")

goldStar?.onFileReady { () in
  goldStarImage = UIImage.init(contentsOfFile: (goldStar?.fileValue())!)
}
// Define the file variable with the correct macro.
DEFINE_VAR_FILE(goldStar, @"gold_star.png");

[goldStar onFileReady:^() {
  goldStarImage = [UIImage imageWithContentsOfFile:[goldStar fileValue]];
}];
// Define the file variable with defineAsset.
Var<String> kitten = Var.defineAsset("kitten", "kitten.jpg");

kitten.addFileReadyHandler(new VariableCallback<String>() {
  @Override
  public void handle(Var<String> variable) {
    // Insert code here.
  }
});

When all variables and files are ready

You can also wait for all variable changes and file downloads. This callback will execute after start, but only after forceContentUpdate if any of your Leanplum variables or files have changed.

// Add a callback.
Leanplum.onVariablesChangedAndNoDownloadsPending { () in
  // Insert code here.
}

// Or, add a responder to be executed as a callback.
Leanplum.addVariablesChangedAndNoDownloadsPendingResponder(self, with: #selector(self.customResponder))

func customResponder() {
  // Insert code here.
}
// Add a callback.
[Leanplum onVariablesChangedAndNoDownloadsPending:^() {
  goldStarImage = [UIImage imageWithContentsOfFile:[goldStar fileValue]];
}];
  
// Or, add a responder to be executed as a callback.
[Leanplum addVariablesChangedAndNoDownloadsPendingResponder:self withSelector:@selector(customResponder)];

- (void)customResponder {
  // Insert code here.
}
// Add a callback.
Leanplum.addVariablesChangedAndNoDownloadsPendingHandler(new VariablesChangedCallback() {
    @Override
    public void variablesChanged() {
        // Insert code here.
    }
});
// Add a callback.
Leanplum.VariablesChangedAndNoDownloadsPending += delegate {
  // Insert code here.
};

Testing callbacks in development mode

When you're testing your app, it's often useful to tweak values and see the result instantly. If you use Variable callbacks, your variables will change immediately after you change them in the Leanplum dashboard.

If you want to mimic your users' experience and don't want to see real-time changes when testing, use the start callback, which is only triggered the first time variables receive their values on start.

Leanplum will tell you if it couldn't connect to the server, in which case the values will be whatever they were the last time the app was run (or their default values set in the code if the app hasn't been run yet).

Suggest Edits

Syncing with Leanplum mid-session

Use forceContentUpdate to sync during a user's session, instead of just at session start.

 

Leanplum’s SDK is designed to sync variables, user attributes, messages, and A/B tests on Leanplum.start, at the beginning of a new session. This ensures users receive the latest updates and messages, and that they are entered into latest A/B tests.

A session starts when a unique user has opened the app and initialized Leanplum (calling Leanplum.start). The session end is defined by 30 minutes or more inactivity after the app is backgrounded. A session will also end if the app remains open but inactive for two or more hours. A force quit of the app (killing the app) also counts as a session end.

By default, we do not sync these values in the middle of a user’s session (after the initial call to start). Our SDK was designed this way to keep it as efficient as possible, requiring only one call to Leanplum’s servers for an entire session, and to keep your app as stable as possible by not altering the app as your users use it.

For most cases, syncing on start is the easiest and best way to keep variables, message targeting and A/B test segments up-to-date.

Using forceContentUpdate

However, there may be some cases where you want to update your messaging or A/B tests mid-session, to be sure a user is appropriately targeted and/or included in a test.

Some examples might be:

  • when a user comes back from backgrounding the app (and something may have changed server-side)
  • when a user levels up in a game (State or Event change)
  • when a user goes from a silver member to gold (User Attribute change)

For these cases, you can force a content update by calling Leanplum.forceContentUpdate(), which syncs variables, user attributes, messages, and A/B tests. Any callbacks you have set up, like onVariablesChanged, will be invoked again automatically.

Calling forceContentUpdate will update all of your variables, user attributes, messages and A/B tests, so it can (depending on how your app is set up to work with Leanplum) affect the functionality and UI of your app. Make sure you consider this when implementing forceContentUpdate.

Suggest Edits

Visual editor (UI)

Set up and use the Visual Editor in Leanplum

 

You can edit your app's user interface (UI) using the Leanplum Visual Editor in the dashboard. You only need to add com.leanplum:UIEditor as a dependency. It is activated by including the package in your build.gradle (module) file, without the need for calling any method.

You can edit your app's user interface (UI) and even create new Events using the Leanplum Visual Editor. To do so, you'll need to add the following dependency to your podfile (iOS) or build.gradle (Android).

//Add this to your pod file:
pod 'Leanplum-iOS-UIEditor'

//Also, be sure to include the package in your AppDelegate.
import LeanplumUIEditor

//Then, add a single line of code before [Leanplum start].
LeanplumUIEditor.shared().allowInterfaceEditing()
//Add this to your podfile:
pod 'Leanplum-iOS-UIEditor'

//Also, be sure to include the package in your AppDelegate.
#import <LeanplumUIEditor/LeanplumUIEditor.h>

//Then, add a single line of code before [Leanplum start].
[[LeanplumUIEditor sharedEditor] allowInterfaceEditing];
//Add this to your build.gradle's dependencies:
com.leanplum:UIEditor

//The final product should look something like this:
dependencies {

  ...
  compile 'com.leanplum:Leanplum:2.+'
  compile 'com.leanplum:UIEditor:2.+'
  ...

}

Older versions of our SDK (< 2.0.0) included the UI Editor in the Leanplum package. If you are using one of these versions, you need to call Leanplum.allowInterfaceEditing() before Leanplum.start() to activate the UI Editor.

Then, run your app in development mode, and click the UI tab in the Dashboard.

UI Editor

To create a new interface, click the New button.

  1. Navigate and scroll to any screen in your app you would like to change
  2. Click any element in the Editor to start editing.
  3. Turn your device sideways to see landscape view.

Once you select an element, like a button, you can edit its properties on the right side of the Editor.

To create your interface, click Save & Exit.

This will load the saved interface to the UI Dashboard, where you can target the new interface to select users or A/B test it.

To publish the interface, click the circle next to your interface name and click Active.

Visual events

Create a new event

To create a new event, run your device in development mode. Then, from the Events tab in the Leanplum dashboard, click Create Visual Event.

  1. Follow the instructions to select a view or element to attach an event.
  1. Give your event a name and click Save & Exit.

View results for an event (visual events)

You can track the occurrences of this event in Analytics.

  1. In the Analytics sidebar, click Developer Activity.
  2. Under Daily Breakdown section, click the + tile to create a new metric.
  3. Under Events, select the visual event you created and choose which metrics you wish to track.
  1. To ensure your event tracking is working, run your app in developer mode and perform the event that you chose in step 4. You should see the value on your tile increase to 1.

To track the metric on a release build, wait about 2 hours after creating your event, then create your event-based metric by following steps 2 and 3 in the "User Activity" tab of the Analytics sidebar.

Suggest Edits

Event and parameter tracking

 

Events allow you to track user activity in your app. You can also use events to target users for certain messages, tests, or other content changes. You can verify when an event is tracked in the Debugger or the Events tab in the Leanplum dashboard.

An event is anything that can occur in your app. Events include clicking on a link, sharing, purchasing, killing enemies, etc. All events are timestamped according to when they occur. Thus, it is not advisable to log too many events, as each one will have to be sent to our server.

500 event limit

Note that there is a limit of 500 events per app in Leanplum. Since events are not unlimited, it's best to track more general events, and use parameters to track specific information associated with the event.

For example, you should use a simple name for a purchase event, such as LP_PURCHASE_EVENT and pass a purchase ID or item ID as a parameter.

A parameter is a piece of data associated with an event or state. You can supply parameters as a dictionary along with events and states. Here are some reports you can run with parameters:

  • Filter reports by event parameter values
  • Group metrics by distinct event parameter values (creates a bar graph + table).
    • Example: Show me my top purchased items.
  • Group metrics by ranges of event parameter values (creates a histogram + table).
    • Example: Show me the distribution of purchase prices. Example: Show me the distribution of points scored.
  • Create custom metrics for numeric parameter values, like totals and averages.
    • Example: For a purchase event, track the average revenue and the amount of currency bought per user.

Parameter limitations

Parameters and Event Values are not available in Developer activity analytics, but you can verify your parameters are being tracked correctly in the Debugger console.

Also, with the out-of-box Leanplum SDK, parameters cannot be used as a criteria to target users. For example, if you have an event "Favorite_Color_Selected" with parameters for each color, you would not be able to target users who completed the Favorite color select event and chose the color blue.

Events and states accumulate over time, and we send events in batches periodically to minimize network usage and maximize battery life.

Tracking an event

Add the following lines of code to track an event. You can place the Leanplum track call anywhere as long as it executes after start (examples below):

//This example tracks the event "Launch" after defining the variable "welcomeMessage". 
import UIKit
import Foundation

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow?
    var welcomeMessage = LPVar.define("welcomeMessage", withString: "Welcome to Leanplum!")

    func application(application: UIApplication!, didFinishLaunchingWithOptions launchOptions: NSDictionary!) -> Bool {
        ...
        Leanplum.onVariablesChanged({
            NSLog((self.welcomeMessage?.stringValue())!)
            Leanplum.track("Launch")
        })
        ...
        return true
    }
...
//This example tracks the event "Launch" after defining the variable "welcomeMessage". 
#import <Leanplum/Leanplum.h>

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{ ...
  [Leanplum onVariablesChanged:^{
    NSLog(@"%@", welcomeMessage.stringValue);
    [Leanplum track:@"Launch"];
  }];
  return YES;
}
...
@end
//This example tracks the event "Launch" after defining the variable "welcomeMessage".
import com.leanplum.annotations.Variable;
import com.leanplum.annotations.Parser;

public class ApplicationClass extends Application {

  @Variable public static String welcomeMessage = "Welcome to Leanplum!";

  @Override
  public void onCreate() {
    ...
    Parser.parseVariables(this);

    Leanplum.addVariablesChangedHandler(new VariablesChangedCallback() {
      @Override
      public void variablesChanged() {
        Log.i("Test", welcomeMessage);
        Leanplum.track("Launch");
      }
    });
    ...

    Leanplum.start();
  }
}
//This example tracks the event "Launch".
using LeanplumSDK;

public class LeanplumWrapper : MonoBehaviour
{   ...
    void Start()
    {   ...
      Leanplum.Track("Launch");
    }
}
//Tracks view cart event for a user.
Leanplum.track("View Cart");

Here are some more examples:

// User killed an enemy.
Leanplum.track("Kills")

// User completed a challenge.
Leanplum.track("Score", withValue: 1)
Leanplum.track("Challenges")

// User liked a post.
Leanplum.track("Likes", withInfo: post.id)

// Or, you can supply a dictionary with up to 200 numerical or string parameters.
Leanplum.track("Likes", withParameters:["post":post.id])
// User killed an enemy.
Leanplum.track("Kills")

// User completed a challenge.
Leanplum.track("Score", withValue: 1)
Leanplum.track("Challenges")

// User liked a post.
Leanplum.track("Likes", withInfo: post.id)

// Or, you can supply a dictionary with up to 200 numerical or string parameters.
Leanplum.track("Likes", withParameters:["post":post.id])
// User killed an enemy.
Leanplum.track("Kills");

// User completed a challenge.
Leanplum.track("Score", challengeValue);
Leanplum.track("Challenges");

// User liked a post.
Leanplum.track("Likes", post.id());

// Or, you can supply a dictionary with up to 200 numerical or string parameters.
Map<String, Object> params = new HashMap<String, Object>();
params.put("post", post.id());
Leanplum.track("Likes", params);
// User killed an enemy.
Leanplum.Track("Kills");

// User completed a challenge.
Leanplum.Track("Score", challengeValue);
Leanplum.Track("Challenges");

// User liked a post.
Leanplum.Track("Likes", post.id());

// Or, you can supply a dictionary with up to 200 numerical or string parameters.
Dictionary<string, object> params = new Dictionary<string, object>();
params.Add("post", post.id());
Leanplum.Track("Likes", params);

// You can also pass a value and parameters.
// User made a purchase. Use Leanplum.PURCHASE_EVENT_NAME to indicate a purchase.
Dictionary<string, object> item = new Dictionary<string, object>();
params.Add("itemCategory", "Apparel");
Leanplum.Track(Leanplum.PURCHASE_EVENT_NAME, 19.99, item);
// Tracks view cart event for a user.
Leanplum.track("View Cart");

// Tracks view cart event with numeric event parameter, itemsInCart.
Leanplum.track("View Cart", {itemsInCart: 4});

// Tracks an event with a value and two event parameters.
Leanplum.track("Purchase", 4.99, {itemCategory: 'Apparel', itemName: 'Shoes'});

Tracking purchase and monetization events

You can track purchases or other monetization events in Leanplum, which will provide you with revenue metrics in your Analytics reports.

In-app purchases

Leanplum supports receipt validation with the App Store and Google Play. On iOS, you can track in-app purchases automatically. Simply add this line of code before Leanplum starts:

Leanplum.trackInAppPurchases()
[Leanplum trackInAppPurchases];
//For iOS
Leanplum.TrackIOSInAppPurchases();

//For Android see Android-specific instructions below.

Leanplum will also convert all purchases to USD. To require valid receipts upon purchase or change your preferred currency, update your preferences in App settings in the dashboard.

To reach your currency settings, click your name in the upper right corner of the dashboard , then select App settings. Next, select "Keys & Settings" next to your app to open this dialogue.

To reach your currency settings, click your name in the upper right corner of the dashboard , then select App settings. Next, select "Keys & Settings" next to your app to open this dialogue.

Android in-app purchases

If your app uses Google Play In-App Billing, Leanplum can automatically track those purchases and validate receipts with the Google Play store. First, provide us with your Google Play license key. Next, add the following code sample in your class that implements ``com.android.vending.billing.util.IabHelper.OnIabPurchaseFinishedListener:

import org.json.JSONException;
import org.json.JSONObject;

import android.util.Log;

import com.android.vending.billing.util.IabHelper.QueryInventoryFinishedListener;
import com.android.vending.billing.util.IabResult;
import com.android.vending.billing.util.Inventory;
import com.android.vending.billing.util.Purchase;
import com.android.vending.billing.util.SkuDetails;

import com.leanplum.Leanplum;
...
@Override
public void onIabPurchaseFinished(IabResult result, Purchase info) {
  final Purchase purchase = info;
  billingHelper.queryInventoryAsync(new QueryInventoryFinishedListener() {
    @Override
    public void onQueryInventoryFinished(IabResult result, Inventory inv) {
      // Track in-app purchase.
      SkuDetails skuDetails = inv.getSkuDetails(purchase.getSku());
      try {
        JSONObject skuData = new JSONObject(skuDetails.toString()
            .substring(skuDetails.toString().indexOf(":") + 1));
        Leanplum.trackGooglePlayPurchase(
            skuData.getString("title"), // Alternatively, skuData.getString("productId"), if you like.
            skuData.getLong("price_amount_micros"),
            skuData.getString("price_currency_code"),
            purchase.getOriginalJson(), purchase.getSignature()
            /* optionally supply event parameters as an additional argument */);
      } catch (JSONException e) {
        Log.e("Leanplum", "Cannot get purchase price from improperly formatted SKU");
      }

      // Code to consume purchase.
      // It's important that you do not consume while querying inventory, or you'll receive
      // an IllegalStateException.
      // billingHelper.consumeAsync(purchase, null);
    }
  });
}

Manually tracking monetization events

You can manually track your monetization event within the app. To do so you have to pass a purchase event name, a purchase value, the currency code, and parameters with info about the purchase event with each purchase (all the parameters are required).

The purchase event name is defined by default as “Purchase”. Based on the currency code being passed, the value will be converted to USD automatically in the Dashboard.

Leanplum.trackPurchase(LP_PURCHASE_EVENT, withValue: 5.0, andCurrencyCode: "EUR", andParameters: ["serial" : 12345, "name":"coffee"])
[Leanplum trackPurchase:LP_PURCHASE_EVENT withValue:5.0 andCurrencyCode:@"EUR" andParameters:@{@"serial": @12345, @"name": @"coffee"}];
Map<String, Object> purchaseParams = new HashMap<String, Object>();
...
purchaseParams.put("Item code", 12345);
purchaseParams.put("Name", "Coffee");
Leanplum.trackPurchase(Leanplum.PURCHASE_EVENT_NAME, 5, "EUR", purchaseParams);

Other monetization events

You can also use the standard event tracking for monetization events as well. It works like any other event — just use "Purchase" as the event name and a value.

The only difference is that unlike using trackPurchase, the normal Leanplum.track call will not automatically convert different currencies to USD.

Leanplum.track(LP_PURCHASE_EVENT, withValue:19.99)
[Leanplum track:LP_PURCHASE_EVENT withValue:19.99];
Leanplum.track(Leanplum.PURCHASE_EVENT_NAME, 19.99, item);

The value should be the revenue for the transaction in a common currency.

If you prefer to use a different event name than "Purchase", you can choose a different name. Select the + tile on the Analytics page for a new metric. In the dialogue box that opens, select the Monetization category and edit the purchase event. The changes will be applied retroactively.

Editing the purchase event in Analytics.

Editing the purchase event in Analytics.

Whether you choose your own name for purchase events or use the default LP_PURCHASE_EVENT, make sure to stay consistent and always use the same event name.

Suggest Edits

State tracking

 

A state is any part of your app a user can be in. For example, some states can include being in a particular level, watching a video, or browsing an in-app store.

All states have a time and a duration. The duration is set automatically — when one state begins, the previous one ends.

Advancing to a state

This example is called when the user advances to the next level.

advance(to: "Level", withInfo:level.name)
[Leanplum advanceTo:@"Level" withInfo:level.name];
Leanplum.advanceTo("Level", level.name());
Leanplum.AdvanceTo("Level", level.Name);
// Tracks a state with a numeric parameter.
Leanplum.advanceTo("Cart", {numItems: 2});

Pausing and resuming

This is useful if your game has a "pause" mode. You shouldn't call it when someone switches out of your app because that's done automatically.

Leanplum.advance(to:nil)
[Leanplum advanceTo:nil];
Leanplum.pauseState();
Leanplum.resumeState();
Leanplum.PauseState();
Leanplum.ResumeState();
Leanplum.pauseState();
Leanplum.resumeState();

The nil / null state

This state causes the user to leave the current state and not enter another one.

Leanplum.advance(to:nil)
[Leanplum advanceTo:nil];
Leanplum.advanceTo(null);
Leanplum.AdvanceTo(null);
Leanplum.advanceTo(null);

Automatically track states for each view

// Automatically track states for each view controller - this currently requires the UIEditor module.
// This code should appear before you display any view controllers in your app.
Leanplum.trackAllAppScreens()
//Automatically track states for each view controller - this currently requires the UIEditor module.
// This code should appear before you display any view controllers in your app.
[Leanplum trackAllAppScreens];
// This code should appear before you display any views in your app.
// Place in the application class before calling Leanplum.start().
Leanplum.trackAllAppScreens();
Suggest Edits

User and device tracking

 

When Leanplum starts for the first time in your app, it creates a new user profile or User ID. Unless you set up your own concept of User IDs, the UserID value will be identical to the DeviceID value, and Leanplum will start tracking sessions for this user.

Sessions are how Leanplum organizes each user's events, states, and other general activity.

See below for more on handling user IDs, devices, and sessions.

Suggest Edits

Device IDs

 

The device ID uniquely identifies the devices and is determined automatically by the SDK. See below for details on iOS and Android device IDs.

If you plan on using external attribution services, make sure the device ID you set matches the device ID sent by your attribution provider (e.g. IDFV -> IDFV). See How to integrate external Attribution services for more.

iOS device ID

On iOS, by default, we use the identifierForVendor. If the device is pre-iOS 6, we use a hash of the MAC address, and in development mode, we use the advertising identifier.

You can choose how the device ID is set the first time start is called on that device by calling one of these before start:

  • LEANPLUM_USE_ADVERTISING_ID: a macro that uses the advertising identifier.
  • [Leanplum setDeviceId:@"customAndUniqueId"]: Sets the device ID to a custom ID. Make sure that your custom ID is unique per device.

The deviceId is set when Leanplum start runs for the first time on that device. After this, it cannot be changed unless the user completely uninstalls and reinstalls your app.

Android device ID

On Android, by default, we use an MD5 hash of the MAC address if the user is on a version prior to Marshmallow (Android 6) and if your app has ACCESS_WIFI_STATE permissions. Otherwise, we use the ANDROID_ID.

You can choose how the device ID will be set the first time start is called on that device by calling one of these before start:

  • Leanplum.setDeviceIdMode(LeanplumDeviceIdMode.ANDROID_ID) Uses the ANDROID_ID.
  • Leanplum.setDeviceIdMode(LeanplumDeviceIdMode.ADVERTISING_ID) Uses advertising ID if available; otherwise, uses the MD5 hash of the MAC address if the user is on a version prior to Marshmallow (Android 6) and your app has ACCESS_WIFI_STATE permissions. Otherwise, we use the ANDROID_ID.
  • Leanplum.setDeviceId("customAndUniqueId") Sets the device ID to a custom ID. Make sure that your custom ID is unique per device.

The deviceId is set when Leanplum start runs for the first time on that device. After this, it cannot be changed unless the user completely uninstalls and reinstalls your app.

Whether or not you set a DeviceIdMode, the SDK uses the following logic to set the deviceId (unless you use setDeviceId):

  1. If DeviceIdMode is set to ADVERTISING_ID, use ADVERTISING_ID if available. Otherwise, continue.
  2. If DeviceIdMode is set to ANDROID_ID, use ANDROID_ID if available. Otherwise, continue.
  3. If a MAC address is available (Android < 6.0 and ACCESS_WIFI_STATE permission), use a hash of the MAC address. Otherwise, continue.
  4. If ANDROID_ID is available, use ANDROID_ID. Otherwise, continue.
  5. Otherwise, use a randomly generated device ID.

You can view the source code here.

Unity device ID

The device ID uniquely identifies the devices and is determined automatically by the SDK. On Unity, we use SystemInfo.deviceUniqueIdentifier to get the device ID. Refer to the Unity documentation to learn more.

JavaScript (HTML5) device ID

The device ID uniquely identifies the devices and is determined automatically by the SDK. In the JavaScript SDK, we generate a unique device ID that persists using localStorage. You can set a custom device ID instead using Leanplum.setDeviceId.

 

When Leanplum start is called for the first time on a device, a new user profile is created and Leanplum starts tracking activity and sessions for this user. If no custom User ID is sent with the start call, the User ID value is set to the Device ID.

If you have your own concept of User IDs, you can pass a User ID in the start call. This way, if the user has multiple devices, we will count them as the same user and merge their profiles.

Leanplum.start(withUserId: "user1234")
[Leanplum startWithUserId:@"user1234"];
Leanplum.start(this, "user1234");
Leanplum.Start("user1234");
Leanplum.start('user1234');

// Start with user ID and attributes.
Leanplum.start('user1234', {'gender': 'Female'});

In some cases, you can also set the User ID after start. See more below:

Logins

Passing a user ID with start may not work well if you have a login system. You should still call start early on to track user activity, then set the user ID later on with setUserId when the user logs in.

Leanplum.setUserId("user1234")
[Leanplum setUserId:@"user1234"];
Leanplum.setUserId("user1234");
Leanplum.SetUserId("user1234");
Leanplum.setUserId("user1234");

// Set user attributes and ID at the same time.
Leanplum.setUserAttributes('user1234', {'gender': 'Female'});

When the user ID is set for the first time on a device, the existing profile in Leanplum is updated with that user ID and all previously tracked data remains.

After the first setUserId call, each subsequent call that includes a different ID will end the current User session, and create a new session for the new User. If the new User ID doesn't exist, a new User Profile will be created in Leanplum.

Here's how setting the user ID with setUserId works with typical registration and login scenarios:

  • Register: If a user ID has not been set on this device yet and the supplied user ID does not exist, Leanplum will update the current user profile (created on start) with the supplied user ID (replacing the device ID).
  • Login: If a user ID has not been set on this device yet and the supplied user ID does exist, the current and existing user profiles will be merged. This ensures that users with multiple devices are tracked as one user. If the same user logs back in on this device, no changes will be made to their profile since their user ID is already set.
  • Switch user: If a user ID has been set on this device and the supplied user ID is different, the current session will be ended and a new session will be started for the supplied user ID. A user with the supplied user ID will be created if one does not already exist.

Logouts

Leanplum will not end the session after a user logs out and does not include any methods to do so. All user activity is tracked and attributed to the last logged-in user (set by the setUserId call). This allows you to track activity in your app even while the user is logged out.

If you want to keep track of which users are logged in and which are logged out, set a user attribute (e.g. logged_in).

Do not set a different user ID to handle logouts. This will create a new user profile in Leanplum and start a new session for them, which will skew your analytics.

Suggest Edits

User attributes

 

A user attribute is any piece of data associated with a user that you provide to the SDK. Each session has its own user attributes, but they get copied from one session to the next. This is in contrast to event parameters, which may take on different values per event. For this reason, you generally use user attributes for things that do not change much within the session, or with which you want the entire session associated.

Uses:

  • Personalizing content (variables, messages, resources, and interfaces) to different types of users.
  • Targeting an A/B test.
  • Filtering reports by a particular user attribute, like only looking at data for "whales".
  • Grouping reports (constructing a bar graph or histogram), by different attribute values. E.g. Create a histogram of average session length by number of friends.

Examples:

  • Gender
  • Age
  • Number of friends
  • User interests

Constraints:

  • Up to 200 attributes can be defined for your app.
  • Attribute names must be strings, and values must be strings or numbers.
  • Attribute values will be the same across all events and states in a particular session.
// Passing attributes at session start allows us to target content based on the attributes.
Leanplum.start(userAttributes: ["gender":"Female", "age": 29])

// You can also pass them later on in the session, but you won't be able to
// target variables or messages at these for that session.
Leanplum.setUserAttributes(["gender":"Female", "age": 29])

// Clear an attribute.
Leanplum.start(userAttributes: ["gender":NSNull()])
// Passing attributes at session start allows us to target content based on the attributes.
[Leanplum startWithUserAttributes:@{@"gender": @"Female", @"age": @29}];

// You can also pass them later on in the session, but you won't be able to
// target variables or messages at these for that session.
[Leanplum setUserAttributes:@{@"gender": @"Female", @"age": @29}];

// Clear an attribute.
[Leanplum startWithUserAttributes:@{@"gender": [NSNull null]}];
// Passing attributes at session start allows us to target content based on the attributes.
Map<String, Object> attributes = new HashMap<String, Object>();
attributes.put("gender", "Female");
attributes.put("age", 29);
Leanplum.start(this, attributes);

// You can also pass them later on in the session, but you won't be able to
// target variables or messages at these for that session.
Leanplum.setUserAttributes(attributes);

// Clear the attributes.
attributes.put("gender", null);
attributes.put("age", null);
Leanplum.setUserAttributes(attributes);
// Passing attributes at session start allows us to target content based on the attributes.
Dictionary<string, object> attributes = new Dictionary<string, object>();
attributes.Add("gender", "Female");
attributes.Add("age", 29);
Leanplum.Start(attributes);

// You can also pass them later on in the session, but you won't be able to
// target variables or messages at these for that session.
Leanplum.SetUserAttributes(attributes);

// Clear the attributes.
attributes.Add("gender", null);
attributes.Add("age", null);
Leanplum.SetUserAttributes(attributes);
// Passing attributes at session start allows us to target content based on the attributes.
var attributes = {'gender': 'Female', 'age': 29};
Leanplum.start(attributes);

// You can also pass them later on in the session, but you won't be able to
// target variables or messages at these for that session.
Leanplum.setUserAttributes(attributes);

// Clear the attributes.
Leanplum.setUserAttributes({'gender': null, 'age': null});
 

Leanplum automatically keeps track of when a user's session is active as long as all of your activities extend LeanplumActivity. This session information is important when calculating time spent in app and other metrics.

If for some reason you can't extend the Leanplum activity class, you'll have to include some extra code so that the session lifecycle is tracked correctly.

Apps targeting Android OS 4.0 and higher do not need to implement these lifecycle callbacks. Instead, using a LeanplumApplication superclass or adding this line of code is sufficient:

LeanplumActivityHelper.enableLifecycleCallbacks(this);

If you don't want to extend the LeanplumApplication class, you can use this code in your own application class to implement the same functionality.

@Override
public void onCreate() {
  Leanplum.setApplicationContext(this);
  Parser.parseVariables(this);
  LeanplumActivityHelper.enableLifecycleCallbacks(this);
  super.onCreate();
}

HTML5
Doesnt automatically end/track session - how long to automatically end session?

  • start from cache is to keep it from duplicating a session, but it won't ever end unless you make it/

Starts Leanplum by simply loading the cached variables, and doesn't log a new session. Useful for subsequent page loads inside the app.

Leanplum.startFromCache('mike3958');

How to track the session lifecycle.

Leanplum.pauseSession();  // Pauses the current session.
Leanplum.resumeSession();  // Resumes the current session.
Leanplum.stop();  // Ends the current session. Sessions will automatically timeout after 2 hours if stop isn't called explicitly (30 minutes if paused).
Suggest Edits

In-app messaging

 

Leanplum comes with a number of in-app message templates, including alerts, confirmation messages, popups, and full-screen interstitials. They are all open source, so you can customize them however you want, and you can even create your own templates.

To enable in-app messaging, you'll need to integrate the Leanplum SDK and run your app at least once in development mode.

Once you finish the SDK setup, you can trigger in-app messages to send after an event or when the app starts. Any trigger events must be tracked with our SDK, but there's no additional coding needed.

Suggest Edits

Customizing in-app message templates

 

Our in-app messaging templates are open-source, which means you can modify them, delete them, or create your own. The Leanplum dashboard will reflect your new templates the next time you run your app.

Once the templates are created or customized, they can be synced with Leanplum, just like Variables, by running the app in Development mode on a registered test device. The process of customizing these templates differs slightly depending on the platform:

iOS custom templates

The files LPMessageTemplates.h and LPMessageTemplates.m come with the SDK. Just download the SDK, unzip, and put the template files in your project. Then, initialize them before the [Leanplum start] call with:

[LPMessageTemplates sharedTemplates];

Take a look at LPMessageTemplates.m to see how the messages are implemented.

To define a new template, use the method:

[Leanplum defineAction:ofKind:withArguments:withResponder:]

Here's how it works:

  • defineAction: The name of the action or message type you are defining.
  • ofKind: One or more action kinds OR'ed together. kLeanplumActionKindMessage will appear in the Message Type list for creating message campaigns. kLeanplumActionKindAction will appear in the dropdown when choosing an action within a message.
  • withArguments: A list of LPActionArg objects, with each one being an argument that the marketer can fill out on the dashboard. For example, Title, Accept action, or Color.
  • withResponder: A block that accepts an LPActionContext and returns a BOOL whether the action was handled or not. You may decide not to handle the action based on some additional logic defined in the responder. From the context, you can access the values for any argument you defined in the template, as well as some other special methods:
    • [LPActionContext runActionNamed:]: Runs another action when this action is done. The action name should correspond to a named LPActionArg of kind Action.
    • [LPActionContext runTrackedActionNamed:]: Runs another action and tracks an event that the action occurred.
    • [LPActionContext track:withValue:andParameters:]: Tracks an event associated with the current action.
    • [LPActionContext muteFutureMessagesOfSameKind]: Don't show the current message campaign again on this device. For example, if you have a survey popup every 10th session, you may want the ability for the user to decide to remind them later, which simply dismisses the message, or the option to never see this survey again.

iOS sample project: custom template

Take a look at the sample project here.

In this sample, we are adding a new in-app message template — specifically, a three-button Confirm message.

First, open the AppDelegate.m and import the LPMessageTemplate class. Then put [LPMessageTemplates sharedTemplates] before [Leanplum start];

OpenLPMessageTemplates.m and check in the sample where the "#### example" comments are placed — you'll find the code parts being added to create the new in-app message template and comments describing each code part being added.

Next, build and run the project. If the device is registered as a Test Device, the three-button message will be added to the available in-app templates in the Dashboard. You may also have to hit the 'sync templates' button in the dashboard to see the final template.

Updates from your connected development device.

Updates from your connected development device.

Android custom templates

First, download the Leanplum Android SDK zip archive, if you haven't already.

Unzip the archive and look for src/com/leanplum/customtemplates. Add all of these files to your project, preserving the directory structure com/leanplum/customtemplates.

Initialize them in your Application class (and before calling Leanplum.start()):
com.leanplum.customtemplates.MessageTemplates.register(getApplicationContext());

Look at the provided files to see how the messages are implemented. To define a new template, use the method Leanplum.defineAction(). Here's how it works:

  • name: The name of the action or message type you are defining.
  • kind: One or more action kinds OR'ed together. Leanplum.ACTION_KIND_MESSAGE will appear in the Message Type list for creating message campaigns. Leanplum.ACTION_KIND_ACTION will appear in the dropdown when choosing an action within a message.
  • args: An ActionArgs instance, defining the options that the marketer can fill out on the dashboard. For example, Title, Accept action, or Color.
  • responder: A callback that accepts an ActionContext and returns a boolean whether the action was handled or not. You may decide not to handle the action based on some additional logic defined in the responder. From the context, you can access the values for any argument you defined in the template, as well as some other special methods:
    • ActionContext.runActionNamed(): Runs another action when this action is done. The action name should correspond to a named action argument defined within ActionArgs.
    • ActionContext runTrackedActionNamed(): Runs another action and tracks an event that the action occurred.
    • ActionContext.track(): Tracks an event associated with the current action.
    • ActionContext.muteFutureMessagesOfSameKind(): Don't show the current message campaign again on this device. For example, if you have a survey popup every 10th session, you may want the ability for the user to decide to remind them later, which simply dismisses the message, or the option to never see this survey again.

Android sample project: custom template

The project sample can be found here.

In this sample we are also adding a new In-App message — specifically, a three-button Confirm message.

Download the Android SDK from the Leanplum SDK Setup page and extract the archive. com/leanplum/customtemplates has been copied from the Android SDK folder and added to the project and in the Application class. Before Leanplum.start, com.leanplum.customtemplates.MessageTemplates.register(getApplicationContext()); is placed.

Unlike the iOS Message Templates, every template is included in its own class in Android.

Create a new class specific to the new message template. In the sample, we've called it 'Confirm3Buttons'. The class name will also be the new template's name in the Leanplum dashboard.

Open the Confirm3Buttons class and check for the "#### example" comments — you'll find the code parts being added to create the new in-app message template and comments describing each code part being added.

The last step is to register the newly added in-app message. Open the MessageTemplates class and add Confirm3Buttons.register(currentContext); in the 'register' function.

To sync the new template to the Leanplum dashboard, run the project on a registered test device. You may also have to hit the 'sync templates' button in the dashboard to see the final template.

Updates from your connected development device.

Updates from your connected development device.

Suggest Edits

Sending iOS 10.3+ app review requests

 

With iOS 10.3, Apple changed how apps can request reviews from users. Per their release notes, developers must now use the SKStoreReviewController API to ask users to rate or review the app while they're using it, without being redirected to the App Store. This is part of a larger overhaul of Apple's ratings and reviews.

To send an app review request on Android or iOS 10.2-, see Send an app review request (Android or iOS 10.2 and earlier).

You can now control when in your app to present the review prompt by calling the API in your app's code, or by using Leanplum's in-app messaging templates — follow the steps below to set up the new App review request.

Update Xcode and your pods/dependencies

Before you can take advantage of the new features in iOS 10.3, you'll need to update Xcode and update your pods/dependencies to get our latest SDK version (requires 1.7.0+).

  1. Update Xcode to version 8.3.
  2. Update your pods to Leanplum iOS SDK 1.7.0+. From the terminal or command prompt, go to your project's root directory and run: pod update
  3. Confirm in the pod notes that Leanplum SDK 1.7.0+ has been installed.
  4. Build and run your app using a registered test device.

If you do not see the "Request App Rating" under In-App Actions, you may need to click the refresh button at the top of the In-app templates dropdown menu, or refresh the page in your browser.

Our dashboard will not show the new in-app message template for app reviews until you run a test device built from Xcode 8.3 with the Leanplum iOS SDK 1.7.0+. If your test devices use older versions of our SDK, the dashboard will not display features exclusive to 1.7.0+.

Resubmit your app to the App Store

Once you've finished making the above changes and testing locally, you'll need to resubmit your app to the App Store. You can then start testing App Review prompts using Leanplum.

Suggest Edits

Push notifications

 

Setting up push notifications with Leanplum allows you to send notifications through the Leanplum dashboard or with the API. In the dashboard, you'll be able to customize the content of your push notifications and create campaigns that combine push with other messaging channels.

Select your OS or language below for specific instructions on setup and other push-related features.

iOS

More on setup, iOS notification types, badge counts, and more.

Android

More on setup and customizing android notifications.

Unity

More on setup for iOS and Android notifications.

JavaScript

More on web push notifications using our HTML5 SDK.

Suggest Edits

iOS push notifications

iOS push setup, categories, badge counts, alerts, and testing

 

To enable Push Notifications on iOS, you need to upload your certificates to Leanplum and register for remote notifications in your app.

iOS push setup

  1. Login to the iOS provisioning portal.
  2. In the Identifiers > App IDs, select your app, click Edit, and enable Push Notifications.
  3. Click Create Certificate for each of the Development and Production certificates and follow the onscreen instructions. You should not reuse existing certificates so that we can track delivery failures properly.
  4. Download your new certificate files from your browser. Open the files on your computer, which will launch Keychain.
  5. In Keychain, select the new certificates, expand them to view the private key, and then right click to export them as .p12 files. You must enter a password.
  6. In Leanplum, go to your app's Keys & Settings (App Settings > {Your app} > Keys & Settings). Under Push Notifications, upload your .p12 files to Leanplum and enter your passphrase from step 5 above.
  7. Configure your app to use push notifications in your app delegate's applicationDidFinishLaunching method. Example:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {

    //iOS-10
    if #available(iOS 10.0, *){
        let userNotifCenter = UNUserNotificationCenter.current()

        userNotifCenter.requestAuthorization(options: [.badge,.alert,.sound]){ (granted,error) in
            //Handle individual parts of the granting here.
        }
        UIApplication.shared.registerForRemoteNotifications()
    }
    //iOS 8-9
    else if #available(iOS 8.0, *){
        let settings = UIUserNotificationSettings.init(types: [UIUserNotificationType.alert,UIUserNotificationType.badge,UIUserNotificationType.sound],
                                        categories: nil)
        UIApplication.shared.registerUserNotificationSettings(settings)
        UIApplication.shared.registerForRemoteNotifications()
    }
    //iOS 7
    else{
        UIApplication.shared.registerForRemoteNotifications(matching:
            [UIRemoteNotificationType.alert,
             UIRemoteNotificationType.badge,
             UIRemoteNotificationType.sound])
    }
    //Other code.
}
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

    id notificationCenterClass = NSClassFromString(@"UNUserNotificationCenter");
    if (notificationCenterClass) {
        // iOS 10.
        SEL selector = NSSelectorFromString(@"currentNotificationCenter");
        id notificationCenter =
        ((id (*)(id, SEL)) [notificationCenterClass methodForSelector:selector])
        (notificationCenterClass, selector);
        if (notificationCenter) {
            selector = NSSelectorFromString(@"requestAuthorizationWithOptions:completionHandler:");
            IMP method = [notificationCenter methodForSelector:selector];
            void (*func)(id, SEL, unsigned long long, void (^)(BOOL, NSError *__nullable)) =
            (void *) method;
            func(notificationCenter, selector,
                 0b111, /* badges, sounds, alerts */
                 ^(BOOL granted, NSError *__nullable error) {
                     if (error) {
                         NSLog(@"Leanplum: Failed to request authorization for user "
                               "notifications: %@", error);
                     }
                 });
        }
        [[UIApplication sharedApplication] registerForRemoteNotifications];
    } else if ([[UIApplication sharedApplication] respondsToSelector:
                @selector(registerUserNotificationSettings:)]) {
        // iOS 8-9.
        UIUserNotificationSettings *settings = [UIUserNotificationSettings
                                                settingsForTypes:UIUserNotificationTypeAlert |
                                                UIUserNotificationTypeBadge |
                                                UIUserNotificationTypeSound categories:nil];
        [[UIApplication sharedApplication] registerUserNotificationSettings:settings];
        [[UIApplication sharedApplication] registerForRemoteNotifications];
    } else {
        // iOS 7 and below.
        #pragma clang diagnostic push
        #pragma clang diagnostic ignored "-Wdeprecated-declarations"
        [[UIApplication sharedApplication] registerForRemoteNotificationTypes:
        #pragma clang diagnostic pop
         UIUserNotificationTypeSound | UIUserNotificationTypeAlert | UIUserNotificationTypeBadge];
    }

    // Other code.
}

Note: You can choose any combination of formats — this is just an example.

If you are implementing application:didReceiveRemoteNotification:fetchCompletionHandler in your code, you should call the completion handler yourself.

Push categories

iOS 8 supports push notification categories, which allow you to provide interactivity to your notifications with custom actions. To use this, define categories in your code — check out Apple's dev docs.

Leanplum allows you to choose the category of your notifications from the dashboard, track each custom action, and even define the logic for what happens on each action. To use categories with Leanplum, you'll need additional calls to Leanplum to handle custom actions in your app delegate. If you call [Leanplum handleActionWithIdentifier], do not call completionHandler as Leanplum will call this internally when it's ready.

- (void)application:(UIApplication *)application handleActionWithIdentifier:(NSString *)identifier
    forRemoteNotification:(NSDictionary *)notification completionHandler:(void (^)())completionHandler
{
    [Leanplum handleActionWithIdentifier:identifier
                   forRemoteNotification:notification
                       completionHandler:completionHandler];
}

- (void)application:(UIApplication *)application handleActionWithIdentifier:(NSString *)identifier forLocalNotification:(UILocalNotification *)notification completionHandler:(void (^)())completionHandler
{
    [Leanplum handleActionWithIdentifier:identifier
                    forLocalNotification:notification
                       completionHandler:completionHandler];
}
let generalCategory = UNNotificationCategory(identifier: "GENERAL",
                                             actions: [],
                                             intentIdentifiers: [],
                                             options: .customDismissAction)
 
// Register the category.
let center = UNUserNotificationCenter.current()
center.setNotificationCategories([generalCategory])

It's a good practice to show additional information or navigate to the correct part of your app when users open your push notifications. You can do that using Leanplum's in-app messaging, which integrates nicely with push notifications. There's no additional coding needed.

Badge counts

The app icon badge is meant to display a count of unread items that await the user's attention. By design, this relies entirely on a remote server to be the system of record; each push notification can set the count with a badge attribute in the payload. If the value is 0, iOS will clear the count and remove the badge. If a value is not set in the payload, the count remains the same.

For example, this payload sets the badge to 9.

{
    "aps" : {
        "alert" : "You got your emails.",
        "badge" : 9
    },
    "acme1" : "bar",
    "acme2" : 42
}

This payload clears the badge, even if the user does not open the notification. A silent push works the same way, but would not include an alert value.

{
    "aps" : {
        "alert" : "You got your emails.",
        "badge": 0
    },
    "acme1" : "bar",
    "acme2" : 42
}

In the Composer, you can set the badge value in your push notification to any number. Leaving the field blank will do nothing (i.e. maintain the current badge count), and setting it to zero will clear the count.

You cannot increment the existing badge count directly from Leanplum's dashboard, but you can add some code to your app to increment and clear the badge count.

To increment the badge whenever a push is received in the background, add the following to didReceiveRemoteNotification in your delegate:

func application(_ application: UIApplication,
                          didReceiveRemoteNotification userInfo: [AnyHashable : Any],
                          fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {

  // Only increment badge if in background.
  if application.applicationState == .background {
    UIApplication.shared.applicationIconBadgeNumber += 1
  }

  completionHandler(.newData)
}
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {

  // Only increment badge if in background.
  if(application.applicationState == UIApplicationStateBackground) {
    NSInteger badge = [[UIApplication sharedApplication] applicationIconBadgeNumber];
    [[UIApplication sharedApplication] setApplicationIconBadgeNumber: badge + 1];
  }

  completionHandler(UIBackgroundFetchResultNewData);
}

To clear the count on app start or resume, you could implement the following in your applicationDidBecomeActive delegate method. However, this would clear the count even if they open the app by some means other than opening the push notification.

func applicationDidBecomeActive(_ application: UIApplication) {
    // Clear app badge on start or resume.
    UIApplication.shared.applicationIconBadgeNumber = 0
}func applicationDidBecomeActive(_ application: UIApplication) {
    // Clear app badge on start or resume.
    UIApplication.shared.applicationIconBadgeNumber = 0
}
func applicationDidBecomeActive(_ application: UIApplication) {
    // Clear app badge on start or resume.
    UIApplication.shared.applicationIconBadgeNumber = 0
}

Custom alert sounds

You can set a custom alert sound for a push notification via the Leanplum Message Composer. However, before doing so, you must include the sound file in your app, following Apple's guidelines for file type, length and size. See Preparing Custom Alert Sounds.

Once the file is available in your app, simply enter the filename with the extension for the iOS push option sound for the message.

Testing

Once you've set up push notifications, test that it is working properly. Send a push notification to your development devices. Run your app, wait a few seconds, and then press the home button.

Troubleshooting

  1. On the device, verify the app is configured to enable pushes: Settings -> Notification Center -> {Your app name}
  2. Recreate the provisioning profile. See iOS provisioning portal.
Suggest Edits

Android push notifications

Android push setup, push services, notification channels, and customization

 

See more on push notification services, Android Notification Channels, and customizing push notifications:

Using push notification services (Android)

Generally, you can configure your Android project to use Leanplum push services with other custom or third-party push notification services by creating custom classes that extend the correct Leanplum push messaging classes.

Leanplum supports both Firebase Cloud Messaging (FCM) and Google Cloud Messaging (GCM), but you can only use one of them at a time to deliver push notifications from Leanplum.

Create a custom class to receive push messages

Regardless of whether you are using GCM or Firebase, you will need to create a custom class (if you haven't already) to define the behavior for your project after receiving a Push Message. The only difference (between GCM and Firebase) is which class you should extend.

For GCM, the new class .Custom_PushListener must extend the LeanplumPushListenerService class (which is extending GcmListenerService).

public class Custom_PushListener extends LeanplumPushListenerService {
// ...
    @Override
    public void onMessageReceived(String var, Bundle notificationPayload) {
        // This ensures the Leanplum code is executed once a Push Notification message is received
        super.onMessageReceived(var, notificationPayload);
        // The remaining code will be executed in addition to the Leanplum default behavior
        Log.i("### ", "Push received");
    }
}

For Firebase, the new class .Custom_FirebaseMessagingService must extend the LeanplumPushFirebaseMessagingService class (which is extending FirebaseMessagingService).

public class Custom_FirebaseMessagingService extends LeanplumPushFirebaseMessagingService {
    @Override
    public void onMessageReceived(RemoteMessage remoteMessage) {
       super.onMessageReceived(remoteMessage);
        Log.i("### ", "Firebase message received");
    }
}

For both GCM and Firebase, your custom class must include the onMessageReceived method, which should override its parent method but still call super.onMessageReceived(). This will make sure the Leanplum code in the extended class is executed when the push notification is received. You can place any custom code within this method after this call.

We will invoke this custom class later with a service in the Android Manifest.

Create a custom class to handle push token refreshes (Firebase only)

Because Leanplum needs to monitor any changes to the push token with Firebase, you must register a service around the com.google.firebase.INSTANCE_ID_EVENT intent. To do that, you first must create a .Custom_PushFcmListenerService class that extends the LeanplumPushFcmListenerService class (which is extending FirebaseInstanceIdService).

Note: This class must have an onTokenRefresh method that overrides its parent and also calls super.onTokenRefresh() to fetch the updated Instance ID token and notify Leanplum app's server of any changes.

public class Custom_PushFcmListenerService extends LeanplumPushFcmListenerService {
    @Override
    public void onTokenRefresh() {
        super.onTokenRefresh();
    }
}

Invoke the custom class(es) in your Manifest

Assuming you have already implemented our SDK and modified your Application class and AndroidManifest.xml file as documented in the Android setup, you will just need to make a few modifications to your Manifest in order to use the push services.

For GCM, you'll only need to modify a single service for the com.google.android.c2dm.intent.RECEIVE intent so that it will invoke the .Custom_PushListener class (created above).

Change the android:name attribute to point to your custom class.

<service
    <!-- android:name="com.leanplum.LeanplumPushListenerService" -->
    android:name=".Custom_PushListener"
    android:exported="false" >
    <intent-filter>
        <action android:name="com.google.android.c2dm.intent.RECEIVE" />
    </intent-filter>
</service>

For Firebase, you will need to edit two services for the com.google.firebase.MESSAGING_EVENT and com.google.firebase.INSTANCE_ID_EVENT intents so that they invoke the .Custom_FirebaseMessagingService and .Custom_PushFcmListenerService classes respectively.

Change the android:name attributes to point to your custom classes.

<service
    <!-- android:name="com.leanplum.LeanplumPushFirebaseMessagingService" -->
    android:name=".Custom_FirebaseMessagingService"
    android:exported="false">
    <intent-filter>
        <action android:name="com.google.firebase.MESSAGING_EVENT" />
    </intent-filter>
</service>
<service
    <!-- android:name="com.leanplum.LeanplumPushFcmListenerService" -->
    android:name=".Custom_PushFcmListenerService"
    android:exported="false">
    <intent-filter>
        <action android:name="com.google.firebase.INSTANCE_ID_EVENT" />
    </intent-filter>
</service>

Sample Projects for push services on Github

A sample GCM project demonstrating multiple push services is available here, and you can see its manifest file here.

A sample Firebase project is available here, and you can see its manifest file here.

Android Notification Channels

Introduced as part of Android 8.0 (Oreo), notification channels give developers more control over push notification customization and management.

If your audience includes Android 8 users, you must implement one or more notification channels in order to send notifications to your users. Sending a push notification to Android 8 users without specifying a valid notifications channel will cause the message to fail to post, and the system will log an error.

Notification channels allow app developers to categorize their push notifications based on the type of content. With channels, you can modify the color of the notification, the sound and vibration pattern it makes, how prominently the notification appears on the user's device, and more. See Android's documentation for more info.

1. Set up Android Notification Channels in Leanplum

Developers can add, delete, or modify notification channels via our API.

See our API docs for more on the methods addAndroidNotificationChannel and deleteAndroidNotificationChannel.

2. Send a push notification with Android Notification Channels

Once a developer adds a notification channel via our API, your new channel should be accessible for use in the Campaign Composer.

Select your desired channel from the dashboard to send a push notification. The Notification channel setting should be in Advanced options in the push notifiction's settings.

This is in the Edit window of the push notification action.

This is in the Edit window of the push notification action.

Make sure you test any new channels on a real device before sending notifications out to users.

3. See all notification channels defined in Leanplum

To see all the notification channels defined in Leanplum, see our API docs for more information on the getAndroidNotificationChannels API call.

These channels are also visible in the Leanplum Campaign Composer — just click the current Notification channel under Advanced Options to reveal a dropdown with all of your available Android notification channels.

Customizing push notifications 🎨

You can customize the appearance of notifications using LeanplumPushService.setCustomizer in your Application class's onCreate method. From there, you can perform any customizations you want to the NotificationCompat object. You can also use the customizer to easily be notified of incoming pushes from Leanplum. You can access some of the notification's properties, like the message, using bundle.getString("lp_message"), and any custom values you defined in Advanced Options > Data in the message config through the dashboard.

For a detailed example, see our guide on Customizing push notifications.

It's a good practice to show additional information or navigate to the correct part of your app when users open your push notifications. You can do that using Leanplum's in-app messaging, which integrates nicely with push notifications.

Suggest Edits

Unity push notifications

Unity push notifications setup

 

To setup push notification support, Leanplum provides a couple of built-in methods that will help you.

iOS setup for push

On iOS, use the following code to register your app for remote notifications after Leanplum starts. This simply registers through the iOS framework for alerts, badges, and sounds.

Leanplum.RegisterForIOSRemoteNotifications();
Alternatively, if you want to register in a custom way, you can add the registration code in your Objective-C code.

For iOS, you'll also need to upload your certificates to Leanplum. Refer to the iOS SDK docs for instructions.

Android setup for push

On Android, you need to setup your Google Cloud Messaging sender ID. You can do this in C# or in Java. Leanplum provides a built-in sender ID, or you can use your custom ID.

Make sure that the sender ID or IDs you pass to Leanplum are consistent with those used anywhere else in your app, including with other third-party SDKs. Inconsistent IDs could prevent your users from receiving some notifications. Use one of the following before Leanplum starts:

// Use the built-in sender ID.
Leanplum.SetGcmSenderId(Leanplum.LeanplumGcmSenderId);

// Use your own sender ID.
Leanplum.SetGcmSenderId("123456790abcdef");

// Use both sender IDs, for ex. if you want Leanplum to send notifications through Leanplum's ID
// and your own server to send notifications through your own ID.
Leanplum.SetGcmSenderIds("123456790abcdef", Leanplum.LeanplumGcmSenderId);

If you're using your own sender ID, you need to give Leanplum permission to send notifications on your behalf. Simply paste your Google API key (this is different from your sender ID) in your app's Push Notification settings.

On Android, you'll also need to add some items to your manifest. Refer to the Android SDK setup for the appropriate code.

It's a good practice to show additional information or navigate to the correct part of your app when users open your push notifications. You can do that using Leanplum's in-app messaging, which integrates nicely with push notifications. There's no additional coding needed.

Test Push Notifications

Once you've set up push notifications, test that it is working properly by sending a push notification to your development devices.

Suggest Edits

JavaScript push notifications

Web push notifications (HTML5)

 

Leanplum supports web push notifications (Contact your CSM to activate this feature). This is currently the only messaging channel for our Javascript SDK.

Supported browsers

Web Push is currently in beta and available for select browsers.

Due to an iOS limitation, we do not support web push on any mobile browsers on iOS, including Safari and Chrome.

Browser
Android
iPhone
Mac OSX
Windows PC

Chrome v52+

Yes

No

Yes

Yes

Firefox v46+

Yes

No

Yes

Yes

Opera v46+

Yes

No

No

No

Safari

No

No

No

No

Edge

No

No

No

No

Samsung Internet Browser

No

No

No

No

MacOS supports icons but does not support images. The push notification will still display, but the image will be ignored. See Google's developer docs for more.

New methods

Four public methods have been added to the HTML5 SDK to support web push.

Method
Description

isWebPushSupported

Determines if web push is supported by the user's browser. Returns a boolean of True or False.

isWebPushSubscribed

Determines if the user is subscribed for web push. Returns a boolean of True or False.

registerForWebPush

Registers the user's browser for web push.

unregisterFromWebPush

Unsubscribes the user and removes the push token. (Does not unregister the service worker registration.)

These can be used to prompt the user to register for web push. We have provided a sample implementation where a toggle registers and unregisters a user for web push. Specifically, see implementation for toggle initialization and toggle switching.

Enabling Web Push

To enable web push, you first need to include the Service Worker file in your root directory and register it in your code, so the browser can use it to run the necessary background processes.

Our SDK has a method that handles the Service Worker registration for you; you just need to pass the filepath to registerForWebPush. The Leanplum SDK also includes a fully working sw.min.js file that you can use as your Worker.

For security reasons, service workers only run over HTTPS.

Before registering the device for push, we recommend checking that the device and browser support web push, and that the device has not already been registered. You can do this with isWebPushSupported and isWebPushSubscribed, both of which return a boolean.

import leanplum from `leanplum-sdk`

let isSubscribedToWebPush = false;
let isWebPushSupported = leanplum.isWebPushSupported();
if(isWebPushSupported){
  leanplum.isWebPushSubscribed().then(subscriptionStatus => {
      isSubscribedToWebPush = subscriptionStatus;
  });
}

Then, you can register the device for push:

if(isWebPushSupported && !isSubscribedToWebPush){
  // Register by passing SW filepath (which is in our root directory).
  leanplum.registerForWebPush('/sw.min.js', subscriptionStatus => {
    console.log('Subscription status: %s', subscriptionStatus);
  });
}

After registering successfully, the device will be able to receive web push notifications, and the browser will handle displaying the messages themselves. The notification includes the title, message, icon, and push image (beta). However, Firefox and Opera do not support push images on any platform.

You can customize how your notification is displayed via the showNotification function.

  1. Title is required. If the push notification does not include a title, the showNotification function will drop the push on the SDK side.
  2. We only support Open URL as the action. The SDK will ignore other actions.

For more information on sending a web push from Leanplum, see how to Send a web push notification.

Suggest Edits

App inbox

iOS and Android instructions

 

App Inbox is a standalone messaging channel that doesn't require push certificates and can store messages for long periods of time.

There is no default UI for the inbox, so you can code your inbox to fit your app's branding and goals. Many Leanplum users make their inbox messages lead to a full-screen message when tapped, with a Back button that leads users back to the inbox.

There is no default UI for the inbox, so you can code your inbox to fit your app's branding and goals. Many Leanplum users make their inbox messages lead to a full-screen message when tapped, with a Back button that leads users back to the inbox.

To enable Inbox messaging, you'll need to integrate Leanplum iOS SDK version 1.6.0 or higher (previous versions use Newsfeed) in your app. After that, you can instantiate the LPInbox (iOS) or LeanplumInbox (Android) object by calling:

Leanplum.inbox()
[Leanplum inbox]
Leanplum.getInbox();

Getting data from Leanplum

Messages and Inbox data are retrieved from Leanplum on Leanplum.start(). The start method returns data asynchronously, so you should use the provided callback (onChanged for iOS and InboxChangedCallback for Android), which will be called automatically when updates to the inbox are finished loading from Leanplum.

Here is a simple example of how you can use the callback to update the number of unread messages:

Leanplum.inbox().onChanged({
    unreadCountLabel.text = String(Leanplum.inbox().unreadCount())
})
[[Leanplum inbox] onChanged:^() {
    unreadCountLabel.text = [NSString stringWithFormat:@"%@", @([[Leanplum inbox] unreadCount])];
}];
Leanplum.getInbox().addChangedHandler(new InboxChangedCallback() {
  @Override
  public void inboxChanged() {
    unreadCount.setText(Integer.toString(Leanplum.getInbox().unreadCount()));
  }
});

Because messages are only retrieved on start, a user will not receive a new message until they begin a new session. You can, however, use forceContentUpdate to re-sync with Leanplum mid-session, which will fetch any new App Inbox messages, and automatically invoke callbacks you have registered.

forceContentUpdate will also update all of your variables, user attributes, messages and A/B tests, so depending on how your app is set up to work with Leanplum, it can affect the functionality and UI of your app. For more on forceContentUpdate, including some precautions, see Syncing with Leanplum mid-session.

Inbox message counts

After data is finished loading from Leanplum, you can get the total and unread count of messages using the LPInbox (iOS) or LeanplumInbox (Android) object:

let inbox: LPInbox = Leanplum.inbox()
let count: UInt  = inbox.count()
let unreadCount: UInt = inbox.unreadCount()
LPInbox *inbox = [Leanplum inbox]; // get the shared Inbox object
NSUInteger count = [inbox count];
NSUInteger unreadCount = [inbox unreadCount];
LeanplumInbox inbox = Leanplum.getInbox(); // instantiate new Inbox object
int unread = inbox.unreadCount();
int total = inbox.count();

Inbox messages

After data is finished loading from Leanplum, you can use the following LPInbox (iOS) or LeanplumInbox (Android) methods to get a list of messages.

// Use the LPInbox instance inbox to get messages. You'll get an NSArray of message objects - either all or just the user's unread messages.
let allMessages: [LPInboxMessage] = inbox.allMessages() as! [LPInboxMessage]
let unreadMessages: [LPInboxMessage] = inbox.unreadMessages() as! [LPInboxMessage]
// Use the LPInbox instance inbox to get messages. You'll get an NSArray of message objects - either all or just the user's unread messages.
NSArray *allMessages = [inbox allMessages];
NSArray *unreadMessages = [inbox unreadMessages];
//This method currently returns a list of NewsfeedMessage objects, which you'll need to cast to the new InboxMessage objects.
List all = inbox.allMessages();
List<LeanplumInboxMessage> messages = (List<LeanplumInboxMessage>) all;
// Do stuff with messages.

Alternatively, you could use messagesIds to get an NSArray or list of all the message IDs, then loop through the returned items and call messageForId with each messageId to fetch each message:

// Use the LPInbox instance inbox to get message Ids.
let messageIds = inbox.messagesIds()
for messageId in messageIds! {
    let message: LPInboxMessage = inbox.message(forId: messageId as! String)
    // Do stuff with message.
}
// Use the LPInbox instance inbox to get message Ids.
NSArray *messageIds = [inbox messagesIds];
for(int i = 0; i < [messageIds count]; i++){
  LPInboxMessage *message = [inbox messageForId: messageIds[i]];
  // Do stuff with message.
}
LeanplumInbox inbox = Leanplum.getInbox(); // instantiate new Inbox object
List<String> messagesIds = inbox.messagesIds(); // get all message IDs
for (String messageId : messagesIds) {
    LeanplumInboxMessage message = inbox.messageForId(messageId);
    // Do stuff with the message.
}

Message attributes

Once you have the Message object, you can access its title, subtitle, and deliveryTimestamp for display.

let message: LPInboxMessage = Leanplum.inbox().message(forId: messageId)
let title: String = message.title()
let subtitle: String = message.subtitle()
let timestamp: Date = message.deliveryTimestamp()
LPInboxMessage *message = [[Leanplum inbox] messageForId: messageId];
NSString *title = [message title];
NSString *subtitle = [message subtitle];
NSDate *timestamp = [message deliveryTimestamp];
LeanplumInboxMessage message = inbox.messageForId(messageId);
String title = message.getTitle();
String subtitle = message.getSubtitle();
Date timestamp = message.getDeliveryTimestamp();

You can also easily test if an inbox message is read:

if(message.isRead()){
  // Do something if the message has been read.
}
if([message isRead]){
  // Do something if the message has been read.
}
if (message.isRead()) {
  // Do something if the message has been read.
}

Message image

We also support sending an image with Inbox messages, although the feature is currently in beta (contact your Customer Success Manager for details on getting access to this feature).

If you haven't disabled automatic image downloads (image prefetching), you can get the image path on the device:

let image: UIImage = UIImage.init(contentsOfFile: message.imageFilePath())
UIImage *image = [UIImage imageWithContentsOfFile:[message imageFilePath]];
String imageFilePath = message.getImageFilePath();
Bitmap bitmap = BitmapFactory.decodeFile(imageFilePath);

If you want to disable automatic image downloads on sync (image prefetching), you can do so with the LPInbox method disableImagePrefetching before calling start.

Leanplum.inbox().disableImagePrefetching()
Leanplum.start()
[[Leanplum inbox] disableImagePrefetching];
[Leanplum start];
LeanplumInbox.disableImagePrefetching();
Leanplum.start();

If you do so, you'll need to get the image URL for each message. For iOS, use LPInboxMessage method imageURL. For Android, use LeanplumInboxMessage method getImageUrl. Then download the files yourself later, or use a third-party solution to manage this for you.

If prefetch is enabled or the image has already been downloaded, imageURL(iOS) or getImageUrl(Android) will return the URI to the file on the device.

// Get the Image URL for a single LPInboxMessage.
let url: URL = message.imageURL()
// Use the URL to download the image.
// Get the Image URL for a single LPInboxMessage.
NSURL *url = [message imageURL];
// Use the URL to download the image.

Handling user interactions

After a user reads the message, you need to explicitly set the inbox message as read. You'll also need to remove the message if the user deletes it.

//Mark message as read.
message.read()

//Delete inbox message.
message.remove()
//Mark message as read.
[message read];

//Delete inbox message.
[message remove];
//Mark message as read.
message.read();

//Delete inbox message.
message.remove();

Implementing Inbox in your app (iOS only)

A natural UIView for App Inbox is UITableView because table cells have title, subtitle and image properties.

You can see our example implementation of App Inbox in a TableView in Objective C and in Swift.

Be sure to use onChanged to handle asynchronous changes from Leanplum.

Updating from newsfeed

In previous versions of our SDK (iOS SDK >= 1.3.8 < 1.6.0, Android SDK >= 1.2.17 < 2.1.0), App Inbox is called Newsfeed. We renamed the classes (and added a bit more functionality to the new classes) in iOS SDK 1.6.0 and Android 2.1.0.

Since the new classes have the same methods as the previous Newsfeed and NewsfeedMessage classes, actions like getting messages, getting message counts, marking messages as read, removing messages, etc. can be done as before using the same methods on the new classes.

iOS classes

Newsfeed is now LPInbox and NewsfeedMessage is now LPInboxMessage.

To update your code, you simply need to instantiate the Inbox with the new class and update your object types.

Android classes

Newsfeed is now LeanplumInbox and NewsfeedMessage is now LeanplumInboxMessage.

To update your code, you simply need to instantiate the Inbox with the new class and update your object types. For handling updates, you also need to switch to the new addChangedHandler method with an InboxChangedCallback for callbacks (these replace addNewsfeedChangedHandler and NewsfeedChangedCallback).

Suggest Edits

Geofencing and location-based messaging

Using location tracking with Leanplum

 

You can set up geofence and iBeacon regions as criteria to trigger in-app messages and push notifications, right from the dashboard.

To enable this functionality in your app, follow the setup instructions below:

iOS location services

Setting up iBeacons and location services

Android location services

Setting up location services

How it works

  • By default, Leanplum uses IP-based geolocation for all users. The Leanplum SDK also captures GPS/cell-based geolocation from the user's device when available.

  • GPS/cell-based information is always trusted more — when available, we use the latitude/longitude coordinates from the device and use reverse-geocoding to determine the name of the Country, Region, and City.

  • Geolocation is gathered only on app start or resume, so a user's location is based on their most recent session.

  • We provide methods to disable automatic collection of GPS/cell-based geolocation (not IP), as well as a method to set user location manually, which allows you to truncate the lat/long to a custom number of decimal points, ultimately limiting the precision of geolocation and protecting user privacy. You could, for example, truncate to two decimal places, blurring the accuracy to about 1 kilometer. See our iOS and Android location docs for more on these methods.

If you set up a message or campaign with a geofence region that has a radius smaller than 20km, we only include users with CELL or GPS Location accuracy. (Because this kind of campaign is very location-specific, we require a high degree of confidence to run it.) If the geofence radius is 20km or larger, we will also include users with IP Location accuracy.

Suggest Edits

iOS location services

Setting up geolocation regions and location-based messaging in Leanplum

 

Set up location services in Leanplum

To set up location services for iOS, you'll have to add our location framework to your Podfile, or as an additional linked framework:

pod 'Leanplum-iOS-Location'
pod 'Leanplum-iOS-LocationAndBeacons'

If you need iBeacons as well, include our Location and Beacons framework instead.

If you did a manual install, add CoreLocation to Build Phases -> Link Binary With Libraries.

Geolocation is only available on iOS SDK 1.4+.

Get permission from users

On iOS, your app must get permission from a user to access their location while using your app. Our SDK automatically asks a user for permission on your behalf. You simply need to import the Location library into your AppDelegate, and add NSLocationWhenInUseUsageDescription to your info.plist file.

import LeanplumLocation
#import <LeanplumLocation/LPLocationManager.h>

You can disable the automatic iOS prompt by setting the authorizeAutomatically property of LPLocationManager to false before calling start.

LPLocationManager.shared().authorizeAutomatically = false;
Leanplum.start()
[LPLocationManager sharedManager].authorizeAutomatically = NO;
[Leanplum start];

If you've disabled automatic authorization, you can request permission using the authorize method. Optionally, you can check if the user has already given permission with needsAuthorization.

if(LPLocationManager.shared().needsAuthorization) {
  LPLocationManager.shared().authorize()
}
LPLocationManager * LPLocation = [[LPLocationManager alloc] init];
if(LPLocation.needsAuthorization){
  [LPLocation authorize];
}

iOS will only allow you to request access to a user's location once. After that, the user must navigate to the privacy settings for your app in Settings.

Disabling location collection

If you do not want to send GPS/Cell location to Leanplum, then do not include either of the location frameworks above. Alternatively, you can include the frameworks and call disableLocationCollection before start.

Leanplum.disableLocationCollection()
[Leanplum disableLocationCollection];

Manually set user location (iOS SDK 1.4.3+)

Our SDK now allows you to set user location by calling setDeviceLocationWithLatitude after start. You should call disableLocationCollection before setting the user location.

Leanplum.setDeviceLocationWithLatitude(40.748817, longitude: -73.985428)

Set up location-based messaging

To trigger messages and push notifications based on geofence and iBeacon regions, you'll have to follow the setup instructions above, then add a few keys in your info.plist file:

  1. Add the key NSLocationWhenInUseUsageDescription: This text will appear to the user when prompting for permissions to enable location monitoring in the foreground on iOS 8+. (Required for in-app messages)
  2. Add the key NSLocationAlwaysUsageDescription: This text will appear to the user when prompting for permissions to enable location monitoring in the background on iOS 8+. (Required for push notifications)
  3. Add the key NSLocationUsageDescription: This text will appear to the user when prompting for permissions to enable location monitoring in the foreground or background on iOS 7. (Optional for in-app messaging and push notifications)
  4. Add the key Required background modes if it does not already exist. Within it, add a background mode App registers for location updates. (Required for push notifications)

iOS limits the number of locations that an app can save to 20, however, our SDK manages this for you by only storing the nearest 20 locations to each user's device at any given time. This way, you can have more than 20 locations saved in Leanplum, but your users will only have the 20 most relevant to them (i.e. the closest).

Region monitoring is available in iOS 7 and higher.

Suggest Edits

Android location services

Setting up geolocation regions and location-based messaging in Leanplum

 

In Android, our SDK (v1.3+) automatically tracks GPS/cell-based location if available to your app.

Disable location collection

If you do not want to send GPS/Cell location to Leanplum, you can call disableLocationCollection beforestart.

Leanplum.disableLocationCollection();

Manually set user location (Android SDK 2.0.0)

Our SDK allows you to set user location by calling setDeviceLocation with two arguments (see below) after calling start. You should call disableLocationCollection before setting the location.

Argument
Type
Description

location

android.location.Location

The location object representing the user's current location.

type

LeanplumLocationAccuracyType

The type of geolocation. Either CELL (default) or GPS (more precise).

setDeviceLocation(location, type);

Set up location-based messaging

To use geofence regions to trigger messages and push notifications in your app, you must add a few keys in your AndroidManifest.xml file:

  1. Add the permission <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/> (Required for geofencing)
  2. Link the Google Play services library to your project and add the metadata in the application tag. <meta-data android:name="com.google.android.gms.version" android:value="@integer/google_play_services_version" /> (Required for geofencing)

Due to a limitation with Android, you can only have 100 regions active for your app at any given time. Leanplum optimizes usage by not monitoring regions for messaging campaigns that don't target particular users.

Suggest Edits

How to integrate external Attribution services (App setup)

 

Integration

Leanplum integrates with many third-party attribution providers. The providers send Leanplum a postback that contains all of the publisher information, which in turn allows you to view the marketing channels in Leanplum, as well as target by them for A/B tests or marketing campaigns.

Before you turn the integration on with your specific partner, you need to confirm that your Leanplum integration is using the same device ID as the third-party you're hoping to integrate with. This is important because Leanplum matches the user install with the third-party postback using the device ID, so if they do not match Leanplum cannot report the data.

For example, Adjust sends IDFV device IDs for iOS, so in order for Leanplum to work with Adjust, you'll have to set your Leanplum device ID to IDFV as well. See Device IDs for more detail.

Once the device ID is confirmed, you can contact your third-party provider or log into their portal, and select Leanplum as the partner to send the postback to. You should then provide the App ID and Client Key specific to your Leanplum dashboard. These keys can be found in the Keys & Settings next to the app name in question.

To reach Keys & Settings, go to App Settings either by clicking on your name in the upper right-hand corner, or by clicking Manage Apps in the app selection bar at the top of the dashboard.

Device IDs in Leanplum

In Leanplum, the device IDs are captured automatically, but can vary depending on the version of the OS the device is running. Our SDK sets the device ID to the ANDROID_ID on newer versions (Android 6+), and an MD5 hash of the MAC address on older versions. The same is true for iOS: new versions (iOS 6+) use identifierForVendor while older versions use a hash of the MAC address.

You can, however, choose to set the device ID mode or the device ID yourself. See Device IDs for more detail.

Suggest Edits

Segment integration [iOS]

How to integrate the Leanplum/Segment SDK

 

iOS

To set up the segment-integrated Leanplum SDK, see the setup instructions in Segment's documentation, then follow the steps below.

CocoaPods is the dependency manager for Objective-C projects.

Note:

If you already have CocoaPods installed and have a podfile, please skip to step 3.

  1. Install CocoaPods by running the following command:

    $ sudo gem install cocoapods
    

    For issues with installing CocoaPods, please refer here.

  2. Add a Podfile. In terminal, navigate to your app's directory. Add a podfile to your app by running the following command:

    $ pod init
    
  3. Open your podfile by running the following command:

    $ open -a Xcode Podfile
    
  4. Insert the following line of code into your Podfile:

    pod 'LeanplumSegment', '~> 1.0.1'
    

Your podfile should look like this:

  1. Now, install the SDK by running the following command:
$ pod install
  1. Import the LeanplumSegment integration:
    #import <LeanplumSegment/SEGLeanplumIntegrationFactory.h>
    

Add the following lines into your AppDelegate:

NSString *const SEGMENT_WRITE_KEY = @" ... ";
SEGAnalyticsConfiguration *config =
    [SEGAnalyticsConfiguration configurationWithWriteKey:SEGMENT_WRITE_KEY];
[config use:[SEGLeanplumIntegrationFactory instance]];
[SEGAnalytics setupWithConfiguration:config];

Make sure to place your Segment Write key within the code. This block of code also calls for Leanplum start.

  1. Make some track calls:

To use the integration, use the following line of code to properly track events within the App:

[[SEGAnalytics sharedAnalytics] track:@" ... "];
  1. Push notifications

In addition to that you can also use the advanced features of Leanplum. Once the Leanplum SDK is successfully registered, Segment posts a NSNotification, hence register to it:

- (BOOL)application:(UIApplication *)application
    didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[...]
  [[NSNotificationCenter defaultCenter]
      addObserver:self
         selector:@selector(segmentIntegrationDidStart)
             name:SEGAnalyticsIntegrationDidStart
           object:LPLeanplumSegmentKey];
}

- (void)segmentIntegrationDidStart {
  [Leanplum onVariablesChanged:^{
      [...]
  }];
}

If you would like more information about the integration, as well as an example project, please refer Leanplum-Segment-iOS Github. As always, feel free to reach out to support@leanplum.com with any other questions.

Suggest Edits

Segment integration [Android]

 

Installation

To install the Leanplum SDK through Segment, make sure to follow the setup instructions in Segment's documentation.

In addition to the standard Segment integration dependencies, the following also needs to be added in order to get the Leanplum SDK:

compile 'com.leanplum.segment:LeanplumIntegration:+'

Usage

This is an example of how to use Leanplum once is integrated through Segment.

Make sure to place the initialization part in your project Application class:

private static final String SEGMENT_WRITE_KEY = " ... ";

Analytics analytics = new Analytics
  .Builder(getApplicationContext(), SEGMENT_WRITE_KEY)
  .use(LeanplumIntegration.FACTORY)
  .build();

Now you can use Segment as you are used to, e.g.:

analytics.track(" ... ", ... );

Note: There is no need to explicitly call Leanplum.start, as it is called within the LeanplumIntegration.

In addition to that you can also use the advanced features of Leanplum. Once the Leanplum SDK is successfully registered, Segement executes a callback:

analytics.onIntegrationReady(LeanplumIntegration.LEANPLUM_SEGMENT_KEY,
    new Analytics.Callback() {
      @Override
      public void onReady(Object instance) {
        Leanplum.addVariablesChangedHandler( ... );
      }
    });

Sample

An Android sample project is available here.

Suggest Edits

mParticle integration [Android - Gradle]

 

This article will provide guidance on how to integrate Leanplum in your mobile project using mParticle.

For mParticle Dashboard setup and information on which Leanplum features are supported by mParticle visit mParticle's docs.

Adding the integration

The Leanplum Kit requires that you add Leanplum's Maven server to your buildscript:

repositories {
    maven { url "http://www.leanplum.com/leanplum-sdks/" }
    ...
}

Add the kit dependency to your app's build.gradle:

dependencies {
    compile 'com.mparticle:android-leanplum-kit:4+'
}

Follow the mParticle Android SDK quick-start for any additional dependency to be added to your project.

Add the following to your Gradle dependecies necessary to collect the Android Advertisting ID:

compile 'com.google.android.gms:play-services-ads:9.0.0'

Add the following in your AndroidManifest Application class as well:

<receiver android:name="com.mparticle.ReferrerReceiver" android:exported="true">
    <intent-filter>
        <action android:name="com.android.vending.INSTALL_REFERRER"/>
    </intent-filter>
</receiver>

For Leanplum, you will need Google Play Services in order to use Leanplum Push Services and Leanplum localization services. If you need those services, include also the following in your Gradle dependecies:

compile 'com.google.android.gms:play-services-gcm:9.0.0'
compile 'com.google.android.gms:play-services- location:9.0.0'

Rebuild and launch your app, and verify that you see"LeanplumKit detected" in the output of 'adb logcat'

Android mParticle sample project

Android sample project is available here.

Leanplum support for mParticle

The mParticle SDK supported Leanplum features are:

  • Marketing Automation (In-App messages)
  • A/B Testing (Messages)
  • Analytics (Tracking events)

Along with the mParticle SDK, the Leanplum SDK would also be accessible for using all the other Leanplum features not available out of the box through mParticle (for example setting Variables or Customizing Push Notifications).

Events in mParticle

To track events through mParticle, the suggested approach is to define a Custom Event. In that way also the parameters can be properly passed to Leanplum.

See the sample project.

Map<String, String> eventInfo = new HashMap<String, String>(2);
eventInfo.put("spice", "hot");
eventInfo.put("menu", "weekdays");

MPEvent event = new MPEvent.Builder("Food Order", MParticle.EventType.Transaction)
        .duration(100)
        .info(eventInfo)
        .build();

MParticle.getInstance().logEvent(event);

Event name is in this case "Food Order" string.
The event parameters are passed as an argument of info().

Suggest Edits

mParticle integration [iOS]

 

To integrate with mParticle via CocoaPods, the following steps will need to be taken.

1. Add a Podfile
In terminal, navigate to your app's directory. Add a podfile to your app by running the following command:

$ pod init

Open your podfile by running the following command:

$ open -a Xcode Podfile

2. Inserting and Installing the mParticle-Leanplum

Insert the following line of code into your Podfile:

pod 'mParticle-Apple-SDK'
pod 'mParticle-Leanplum'

You will also need to include:

source 'https://github.com/CocoaPods/Specs.git'

inhibit_all_warnings!

Your podfile should look like the following:

Now, install the Pods by running the following command:

$ pod install

3. Setting up AppDelegate
Then, to appropriately run mParticle, you will need to set your AppDelegate as follows:

You will need to include:

#import <Foundation/Foundation.h>

#if defined(__has_include) && __has_include(<mParticle_Apple_SDK/mParticle.h>)

#import <mParticle_Apple_SDK/mParticle.h>

#else

#import "mParticle.h"

#endif

In your AppDelegate.h

Then, in your AppDelegate.m, you will need to add:

# import <Leanplum/Leanplum.h>

In order to call any Leanplum advance feature. Additionally, you will need to include:

[[MParticle sharedInstance] startWithKey:@"KEY_GOES_HERE"
                                      secret:@"SECRET_GOES_HERE"];

In didFinishLaunchingWithOptions.

This call automatically calls Leanplum Start. After this call, you can call Leanplum calls such as [Leanplum setUserId:@"exampleUser"];

For reference, your AppDelegate.m could appear as follows:

If you have any questions, please feel free to email support@leanplum.com.

Suggest Edits

Branch.io

Set up multi-platform deep links for push and email using Branch.io and Leanplum

 

Branch.io allows you to automatically convert your email links into multi-platform deep links that take app users directly to content in your mobile app, while maintaining the same web experience for desktop and mobile users without the app. You can also use Branch links with Leanplum push notifications, so that tapping a push takes the user to a specific screen in your app.

When a user who has your app clicks the link, it will direct that user into the relevant in-app content regardless of platform or email client.

When a user without the app clicks a link, it will route that user to the original web URL (including on desktop).

To set up multi-platform deeplinks, it must be possible to map your web URL content (e.g. a page with brown loafers at https://shop.com/shoes/brown-loafers) into a working deep link that takes users to brown loafers in the app. Branch's Deep Linked Email setup flow will attempt to automatically detect this mapping for you, but if you don't want to set this up, you can also choose to have your links open to app homepage.

Set up deep links with Branch.io and Leanplum

See here for the full guide on setting up Branch deep links with Leanplum.

Suggest Edits

Appsflyer integration

 

You can integrate with Appsflyer by sending Leanplum a postback containing publisher information. This allows you to view attribution data in Leanplum analytics as well as use it for targeting in A/B tests or marketing campaigns, via Leanplum’s targeting and segmentation menu.

Before you activate the integration with Appsflyer, you first need to confirm that your Leanplum integration is using the same device ID as Appsflyer. This is important as Leanplum matches the user install in Leanplum with the postback data from Appsflyer using the device ID, so if they do not match Leanplum cannot report the data.

By default, Leanplum collects the IDFV for iOS and the MD5 hash of the MAC address for Android, but this can be easily changed to IDFA for iOS and GAID for Android with one line of code. For information about how to change the device ID format, see: Device IDs.

You also need to get your App ID and client keys to input into the Appsflyer system. To view your App Keys, do the following:

  1. Click on your name at the top right of the screen and select App Settings.
  1. Select an app and click Keys & Settings
  1. You will see a tab called API Keys. Here you will find the App ID and Production key.
  1. Configure Leanplum in AppsFlyer’s Dashboard.

  2. Click Integrated Partners in the left of the screen.

  1. Search for Leanplum:
  1. Click on the Leanplum logo to open the configuration window.
  1. Under Integration Parameters, check the Enable check box.

  2. Insert the Client Key and App id taken from Leanplum console (see Section 3).

  3. Click Save & Close.

Once you have saved the configuration, AppsFlyer sends the following data to Leanplum for every organic and non-organic install:

  • Device ID (IDFA / Google Advertising ID)
  • Media Source
  • Campaign name

Important note:

According to Facebook and Twitter T&C, Appsflyer is unable to share user level data with any 3rd party. As a result, all Facebook and Twitter installs are sent to Leanplum as organic.

Viewing User Attribution Data in Leanplum

Once you have set up the integration between Leanplum and Appsflyer, you can access the information by utilizing Leanplum’s targeting and segmentation menu:

This menu is available in the Analytics, Messages, A/B Tests, and Users sections of the Leanplum platform. You can filter by, group by, and cohort by this data in Analytics, filter by this data in the Users section, and target by this data in Analytics and A/B Tests.

Suggest Edits

Apteligent integration (crash reporting)

Sending a crash event to Leanplum

 

The Apteligent (formerly Crittercism) SDK will create a notification that fires when the SDK knows that a crash occurred. On iOS, when the user loads the app after a crash occurred, this notification will fire. The notification will contain three pieces of information (we may add more later):

  • Crash Name: The name of the crash (i.e., NSRangeException)
  • Crash Reason: More details on why the crash occurred (i.e., "* -[__NSArrayM objectAtIndex:]: index 18446744073709551615 beyond bounds for empty array")
  • Crash Date: The date and time at which the crash occurred

To send these crash events to Leanplum, add two lines of code:

  1. Register an Observer

    [[NSNotificationCenter defaultCenter] addObserver:self
    selector:@selector(crashDidOccur:)
    name:@"CRCrashNotification" object:nil];
    
    1. Send an Event Upon Notification
      ```
  2. (void) crashDidOccur:(NSNotification)notification {
    NSDictionary
    crashInfo = notification.userInfo;
    NSString crashName = crashInfo[@"crashName"]];
    NSString
    crashReason = crashInfo[@"crashReason"];
    NSDate *crashDate = crashInfo[@"crashDate"];
    // Leanplum
    [Leanplum track:@"ApteligentCrashEvent" withParameters:crashInfo];
    }
    ```

Use Case Examples

With crashes recorded as Apteligent events, mutual customers can be used to:

  • create audiences of app users to engage through in-app and push messages — eg, to apologize, let them know a fix is on the way.
  • detect is app is having an outage and don't send a push notification.
Suggest Edits

API Introduction

Welcome! See what you can do with the Leanplum API

 

Leanplum is designed to integrate with your app using our SDKs. If you need to supplement our SDKs with information from your backend systems, you can use our API. The Leanplum API is only available to customers on full-service accounts. We recommend you contact your customer success manager to discuss your API integration needs, so we can help review your plan and share some best practices.

Check out the sample uses of our API on Github.

Tracking analytics data

Leanplum organizes its data within sessions. A session is one use of an application by a user. To start a session, use the start API method. Sessions may be paused and resumed as users exit and re-enter the app, using pauseSession and resumeSession.

Sessions also include user activity, such as events (things the user does), and states (parts of the app the user is in). Send events and states using track and advance. User attributes may change within a session using setUserAttributes. Sessions time out after 2 hours of inactivity, or 30 minutes after being paused. To keep a session alive, use heartbeat.

Some things can happen outside of sessions as well. For example, a user may receive a notification or a friend request while they're not using the app. You can use track (with disposition=passive) and setUserAttributes outside of sessions.

Updating user information

Leanplum stores many things in a user's profile, including user attributes and behavioral data, such as the lifetime occurrences of a particular event. You can update both of these with setUserAttributes. To retrieve a user's profile, use exportUser.

Sending messages

Leanplum allows you to create messages that are triggered based on user activity, such as when an event fires or a user attribute changes. But in some cases, you may need to trigger messages based on information available on your own server. Use the sendMessage API to send a push notification, newsfeed message, or other types of messages to a user.

The Leanplum SDK will automatically collect push tokens from your users, but if you need to import older push tokens (from users before Leanplum), you can set them in setDeviceAttributes.

Accessing content

There are APIs for receiving the user's variables and files set in the Leanplum dashboard in the Variables and A/B Testing tabs. Whenever a request executes the start method, the list of variables is returned. You can also get the user's variables without starting a new session using getVars. To access the file referenced by the value of a file variable, use downloadFile.

Attribution

Use setTrafficSourceInfo to send attribution data for a user. You can also use setUserAttributes.

Data export

You can export raw user activity data using exportData, export lists of users that match certain criteria using exportUsers, or export analytics reports using exportReport. You can also add postbacks to stream data to another location when those events occur using addPostback.

Getting info about content in Leanplum

You may need to retrieve information about A/B tests or messages created in the Leanplum dashboard. To retrieve information about A/B tests, use getAbTests, getAbTest , or getVariant. To retrieve information about messages, use getMessage or getMessages.

Suggest Edits

Making requests

 

All API requests must be made to https://www.leanplum.com/api. The API is very flexible and supports GET and POST request formats. Our docs, generally, use POST examples for methods that might update/change Leanplum data (e.g. start or setUserAttributes), but both GET and POST request methods are acceptable.

Request formats

GET

The top-level arguments are sent as GET parameters in the request. As part of the HTTP specification, a URL must be at most 2,083 characters, so it's best for small API requests. All characters in the URL should be URL encoded.

Example:

https://www.leanplum.com/api?appId=APP_ID&clientKey=CLIENT_KEY&apiVersion=1.0.6&userId=USER_ID&action=setUserAttributes&userAttributes={"Interests":["Technology","Music"]}

Properly encoded this is:

https://www.leanplum.com/api?appId=APP_ID&clientKey=CLIENT_KEY&apiVersion=1.0.6&userId=USER_ID&action=setUserAttributes&userAttributes=%7B%27Interests%27%3A+%5B%27Technology%27%2C+%27Music%27%5D%7D

POST

The top-level arguments can be either in the URL or in the request body. Generally, our docs show the action argument set in the URL for POST requests, but this is not necessary; all arguments can be set in the POST body with the request sent to https://www.leanplum.com/api. Alternatively, more (even all) arguments can be placed in the URL. However, all characters in the URL should be URL encoded.

The Content-Type of the POST request must be JSON or multipart form data.

Example of a POST request with JSON:

POST https://www.leanplum.com/api?action=setUserAttributes

Content-Type: application/json
{
  "appId": "APP_ID",
  "clientKey": "CLIENT_KEY",
  "apiVersion": "1.0.6",
  "userId": "USER_ID",
  "userAttributes": {
    "Interests": [
      "Technology",
      "Music"
    ]
  }
}

Multiple actions can be batched together. It's highly recommended to batch API actions, especially for the same user. Do not make multiple concurrent API requests for the same user. See Batching requests for more.

Suggest Edits

Authentication

 

Client keys

Every Leanplum app you create will have multiple API keys (visible in App Settings > Keys & Settings). Set the clientKey parameter in the API request to the correct key for the associated API methods:

Production

track sessions, states, set user or device attributes, etc.

Development

import CSV data, delete users, set variables, etc.

Data Export

export user data, messaging and a/b test reports, etc.

Content Read-only

get message and a/b test information, etc.

The correct key for each API method is also listed in each method's description.

 

You should retry if and only if you receive an HTTP 5xx (internal server) error, and use exponential backoff, up to a maximum amount of retries. As a simple example, you could:

  1. retry after 2 +/- random(0, 1) seconds, then
  2. retry after 4 +/- random(0, 2) seconds, then
  3. retry after 8 +/- random(0, 4) seconds
  4. etc.
Suggest Edits

Selecting a user

 

For many API methods, you can pass a userId, a deviceId, or both userId and deviceId. Here's how these will affect the action, or execution of the API method:

  • userId only: The API action pertains to the user and not a particular device. In most cases, Leanplum will not associate any device with this action, which may cause device information to be excluded from analytics. In some cases, Leanplum may be able to infer the device. When using the sendMessage method for a push notification, passing a userId only would send a push notification to all devices associated with that user.
  • deviceId only: The API action pertains to a particular device without an associated user ID, for example, a logged out user. The user ID may be inferred by the API.
  • userId and deviceId: The API action pertains to a particular device associated to a particular user ID.

In many cases, you would only pass a userId and not a deviceId, because events coming from the API are not associated with a particular device. Events coming from a device are usually sent via the SDK.

// Example POST requests to 
// https://www.leanplum.com/api?action=sendMessage

// User only - sends message to all devices for that user
{
  "appId": "APP_ID",
  "clientKey": "PROD_KEY",
  "apiVersion": "1.0.6",
  "userId": "hfarnsworth@example.com",
  "messageId": 101001
}

// Device only - sends to a specific device
{
  "appId": "APP_ID",
  "clientKey": "PROD_KEY",
  "apiVersion": "1.0.6",
  "deviceId": "device1",
  "messageId": 101001
}

// User and device - sends to a specific device and user
{
  "appId": "APP_ID",
  "clientKey": "PROD_KEY",
  "apiVersion": "1.0.6",
  "userId": "hfarnsworth@example.com",
  "deviceId": "device1",
  "messageId": 101001
}

Additionally, getVars has an additional mode where neither a userId nor deviceId are provided, which will return the default variables that would be seen by a blank user.

Suggest Edits

Responses

 

All responses except for the downloadFile request are in JSON format, and include warning and error objects to indicate problems with your request, if any. The 200 status and success flag only indicate that the request was received, not that the provided API action was successful.

An API action is successful if all of these are true:

  • the response code is 200.
  • the success flag is true.
  • there is no error.message.
  • there is no warning.message.

A successful call will always result in a 200 status with success=true and no error.message or warning.message.

An HTTP response of 200 and a response of success=true do not indicate that the action was successful. You need to verify there are no error or warning messages.

Types of responses you can get:

HTTP 200

  • success=true (no warning or error objects): The request was received and the action taken successfully.
  • success=true and warning.message=“warning message": The request was received successfully but the action was likely skipped. See warning message for details.
  • success=true and error.message=“error message": The request was received successfully but the action was skipped. See error message for details.

HTTP 4xx or 5xx

  • success=false and error.message=“error message": The request was not received successfully. See error message for details.
{ 
  "response": [
    {
      "success": true
    }
  ]
}
{ 
  "response": [
    {
      "success": true,
      "warning": {
        "message": "User not found; request skipped."
      }
    }
  ]
}
{
  "response": [
    {
      "success": true,
      "error": {
        "message": "Error message provided here."
      }
    }
  ]
}
{
  "response": [
    {
      "success": false,
      "error": {
        "message": "Invalid access key"
      }
    }
  ]
}
 

Due to our system architecture, our costs increase for every user profile we need to retrieve in order to process an HTTP request to our API. As such, we bill server-side API calls based on the number of user lookups per HTTP request to our API, and not the number of HTTP requests or API actions. To be clear, for billing purposes, a server-side API call is one unique user lookup initiated by an HTTP request made to the Leanplum API from any source other than the Leanplum SDK.

One HTTP request can include multiple user lookups. multi allows you to batch multiple actions affecting up to 50 unique users in a single request. Therefore, the maximum number of billable API calls (user lookups) per HTTP request is 50, not 1.

We do, however, exempt all deleteUser actions from billing so you're free to clean up your data.

We also optimize how we handle multi requests to prevent duplicate user lookups (reducing both our and your costs). Because we do this, you can reduce the number of billable calls you make to the Leanplum API (while executing the same number of actions) by batching actions for the same user(s).

See Batching requests for more.

The multi action also allows you to import an external file containing a potentially large number of actions. This is billed by breaking the file into API requests that each contains a batch of 50 actions. Each of these API requests is then billed using the above definition.

Suggest Edits

Batching requests with multi

Use a multi call to batch multiple API requests

 

To improve performance and reduce your billable API calls, you should batch multiple API requests that affect the same users as much as possible (see more on Reducing billable requests).

While Leanplum processes a successful multi call, concurrent requests for these users (via the SDK or API) will be queued and completed after the multi batch completes.

Send the request

To batch API actions, make a post request to https://www.leanplum.com/api?action=multi with the following parameters in the request body:

param
description

appId

required
The application ID. To find yours, select your app in the navigation column, and click Edit Apps. Under Keys, click Show.

clientKey

required
The Production key for your Leanplum App.

apiVersion

required
The version of the Leanplum API to use. The current version is 1.0.6.

time

required
The time at which the request was issued (UNIX time). This is used to resolve the time difference between Leanplum and the API caller when computing the times of events.

data

required
A JSON-encoded list of API methods to execute. All methods must be for the same app referred to by the appId parameter. Each data object must include the required arguments for its API action.

Each nested object in the data array is an individual API action, and must include the required parameters for that method. You'll need to reference each nested API method's documentation for info on required parameters and options.

{
  "appId": "YOUR_APP_ID",
  "clientKey": "YOUR_PROD_KEY",
  "apiVersion": "1.0.6",
  "time": 1375295890,
  "data": [
    {
      "action": "start",
      "time": 1375295825,
      "userAttributes": {
        "Gender": "Male",
        "Age": 25
      },
      "userId": "user1"
    },
    {
      "action": "track",
      "time": 1375295830,
      "event": "Level Complete",
      "params": {
        "Level": 1,
        "Score": 100
      },
      "userId": "user1"
    }
  ]
}

Response

Each individual action will also have its own response; some may be successes, some may have warnings, and some may have errors. The index of the response will match the index of the request in the data array. For the example above, if we pass a bad string as the action in the second batched request, we get the following response:

{
  "response": [
    {
      "success": true
    },
    {
      "success": false,
      "error": {
        "message": "Action not found"
      }
    }
  ]
}

The 'multi' call method is limited to 50 users and/or 500 actions in a single call. All calls in a batch with more than this will be ignored and the server will return a 403 status. Each unique user lookup in a request is a billable API call. See billing and costs for more.

Suggest Edits

Reduce billable requests

 

Batching should first be done on a per-user basis, and then across users, with up to 50 users modified in a single multi request. For example, if you want to track an event and setUserAttributes for two users, the total billable calls is entirely dependent on how you setup your multi requests.

DO

Batch by user first. For example:

multi request 1:

  • track (user1)
  • setUserAttributes (user1)

multi request 2:

  • track (user2)
  • setUserAttributes (user2)

Each of these requests requires one user lookup, so the total billable API calls is two (despite executing four actions). In this case, however, you could combine these into a single multi request without using additional API calls:

multi request 1:

  • track (user1)
  • setUserAttributes (user1)
  • track (user2)
  • setUserAttributes (user2)

This single request still only requires two unique user lookups, so the total billable API calls remains two.

AVOID

Batching requests by action instead of by user.

multi request 1:

  • track (user1)
  • track (user2)

multi request 2:

  • setUserAttributes (user1)
  • setUserAttributes(user2)

In this case, each request requires two user lookups. Therefore, there are four billable API calls. Avoid this, as it is not an efficient use of multi.

Suggest Edits

Debugging

 

To debug an API request, set clientKey to your development key and devMode=true, and most importantly be sure to set the userId and/or deviceId to a test user/device. If you use a real user when debugging, Leanplum will convert that user profile to a developer account.

These requests will be visible in the Dashboard Debugger console.

All session and tracking info from these requests will not be tracked as real user data. The matching user/device will be set to a developer account, and all of their activity will be sent to a separate analytics section, Developer Activity.

Do not set devMode=true for any API request that involves a real device or user. Only use it with test devices or developer accounts.

Suggest Edits

API methods

 

See all of our API methods organized by section below. Make sure to use the best practices outlined under Making requests when working with these methods.

Not sure where to start?

See our API introduction for more on using Leanplum's API, or see our API guides for more specific applications.

Suggest Edits

User Behavior

 
Suggest Edits

advance

Advances a user to the next state. If the user/device does not exist, the API request is skipped and a warning will be returned. You can modify this behavior with the createDisposition option (see below). The state is the section of the app the user is currently in. States are like events with duration.

This method requires your production API clientKey.

 
posthttps://www.leanplum.com/api?action=advance

Body Params

appId
string
required

The application ID. To find yours, select your app in the navigation column, and click Manage Apps. Then click Keys & Settings.

clientKey
string
required

The Production key for your Leanplum App.

apiVersion
string
required

The version of the Leanplum API to use. The current version is 1.0.6.

userId
string
required

The current user ID. You can set this to whatever your company uses for user IDs. Leave it blank to use the device ID. For more info, see selecting a user.

state
string
required

The name of the state. Set to an empty string to leave the current state but not enter a new one.

deviceId
string

A unique ID for the device targeted by the request. You must provide a deviceId and/or a userId. See selecting a user.

createDisposition
string

The policy that determines whether users are created by the API. Possible values:

  • CreateIfNeeded creates a user with the given IDs if one does not already exist.
  • CreateNever requires that the user already exists, otherwise the API action is skipped and a warning will be returned.

The default value for this method is CreateNever.

devMode
boolean

Whether the user is in Development Mode, i.e. the user associated with the request is a developer and not a user. This is important for reporting purposes. Default: false.

info
string

Any info attached to the state.

params
object

A flat object of parameters as key-value pairs. Each key must be a string, and up to 50 parameters may be set. Example: {'gender':'F','age':21}.

Response

The default response for most API actions.

response[].successboolean

Whether the request was received. Verify that the response has neither warning or error objects to confirm the action was taken. See here for more.

response[].warning.messagestring

The warning message for the API action, if any.

response[].error.messagestring

The error message for the API action, if any.

Suggest Edits

pauseState

Pauses the current state, but not the session, for a user. If the user/device does not exist, the API request is skipped and a warning will be returned. You can modify this behavior with the createDisposition option (see below).

This method requires your production API clientKey.

 
posthttps://www.leanplum.com/api?action=pauseState

Body Params

appId
string
required

The application ID. To find yours, select your app in the navigation column, and click Manage Apps. Then click Keys & Settings.

clientKey
string
required

The Production key for your Leanplum App.

apiVersion
string
required

The version of the Leanplum API to use. The current version is 1.0.6.

userId
string
required

The current user ID. You can set this to whatever your company uses for user IDs. Leave it blank to use the device ID. For more info, see selecting a user.

deviceId
string

A unique ID for the device targeted by the request. You must provide a deviceId and/or a userId. See selecting a user.

devMode
boolean

Whether the user is in Development Mode, i.e. the user associated with the request is a developer and not a user. This is important for reporting purposes. Default: false.

createDisposition
string

The policy that determines whether users are created by the API. Possible values:

  • CreateIfNeeded creates a user with the given IDs if one does not already exist.
  • CreateNever requires that the user already exists, otherwise the API action is skipped and a warning will be returned.

The default value for this method is CreateNever.

Response

The default response for most API actions.

response[].successboolean

Whether the request was received. Verify that the response has neither warning or error objects to confirm the action was taken. See here for more.

response[].warning.messagestring

The warning message for the API action, if any.

response[].error.messagestring

The error message for the API action, if any.

Suggest Edits

resumeState

Resumes the current state for a user. If the user/device does not exist, the API request is skipped and a warning will be returned. You can modify this behavior with the createDisposition option (see below).

This method requires your production API clientKey.

 
posthttps://www.leanplum.com/api?action=resumeState

Body Params

appId
string
required

The application ID. To find yours, select your app in the navigation column, and click Manage Apps. Then click Keys & Settings.

clientKey
string
required

The Production key for your Leanplum App.

apiVersion
string
required

The version of the Leanplum API to use. The current version is 1.0.6.

userId
string
required

The current user ID. You can set this to whatever your company uses for user IDs. Leave it blank to use the device ID. For more info, see selecting a user.

deviceId
string

A unique ID for the device targeted by the request. You must provide a deviceId and/or a userId. See selecting a user.

devMode
boolean

Whether the user is in Development Mode, i.e. the user associated with the request is a developer and not a user. This is important for reporting purposes. Default: false.

createDisposition
string

The policy that determines whether users are created by the API. Possible values:

  • CreateIfNeeded creates a user with the given IDs if one does not already exist.
  • CreateNever requires that the user already exists, otherwise the API action is skipped and a warning will be returned.

The default value for this method is CreateNever.

Response

The default response for most API actions.

response[].successboolean

Whether the request was received. Verify that the response has neither warning or error objects to confirm the action was taken. See here for more.

response[].warning.messagestring

The warning message for the API action, if any.

response[].error.messagestring

The error message for the API action, if any.

Suggest Edits

pauseSession

Pauses the current session and state for a user. If the user/device does not exist, the API request is skipped and a warning will be returned. You can modify this behavior with the createDisposition option (see below).

This method requires your production API clientKey.

 
posthttps://www.leanplum.com/api?action=pauseSession

Body Params

appId
string
required

The application ID. To find yours, select your app in the navigation column, and click Manage Apps. Then click Keys & Settings.

clientKey
string
required

The Production key for your Leanplum App.

apiVersion
string
required

The version of the Leanplum API to use. The current version is 1.0.6.

userId
string
required

The current user ID. You can set this to whatever your company uses for user IDs. Leave it blank to use the device ID. For more info, see selecting a user.

deviceId
string

A unique ID for the device targeted by the request. You must provide a deviceId and/or a userId. See selecting a user.

devMode
boolean

Whether the user is in Development Mode, i.e. the user associated with the request is a developer and not a user. This is important for reporting purposes. Default: false.

createDisposition
string

The policy that determines whether users are created by the API. Possible values:

  • CreateIfNeeded creates a user with the given IDs if one does not already exist.
  • CreateNever requires that the user already exists, otherwise the API action is skipped and a warning will be returned.

The default value for this method is CreateNever.

Response

The default response for most API actions.

response[].successboolean

Whether the request was received. Verify that the response has neither warning or error objects to confirm the action was taken. See here for more.

response[].warning.messagestring

The warning message for the API action, if any.

response[].error.messagestring

The error message for the API action, if any.

Suggest Edits

resumeSession

Resumes the current session and state for a user. Use either after pauseSession, or start if the app started in the background. If the user/device does not exist, the API request is skipped and a warning will be returned. You can modify this behavior with the createDisposition option (see below).

This method requires your production API clientKey.

 
posthttps://www.leanplum.com/api?action=resumeSession

Body Params

appId
string
required

The application ID. To find yours, select your app in the navigation column, and click Manage Apps. Then click Keys & Settings.

clientKey
string
required

The Production key for your Leanplum App.

apiVersion
string
required

The version of the Leanplum API to use. The current version is 1.0.6.

userId
string
required

The current user ID. You can set this to whatever your company uses for user IDs. Leave it blank to use the device ID. For more info, see selecting a user.

deviceId
string

A unique ID for the device targeted by the request. You must provide a deviceId and/or a userId. See selecting a user.

devMode
boolean

Whether the user is in Development Mode, i.e. the user associated with the request is a developer and not a user. This is important for reporting purposes. Default: false.

createDisposition
string

The policy that determines whether users are created by the API. Possible values:

  • CreateIfNeeded creates a user with the given IDs if one does not already exist.
  • CreateNever requires that the user already exists, otherwise the API action is skipped and a warning will be returned.

The default value for this method is CreateNever.

Response

The default response for most API actions.

response[].successboolean

Whether the request was received. Verify that the response has neither warning or error objects to confirm the action was taken. See here for more.

response[].warning.messagestring

The warning message for the API action, if any.

response[].error.messagestring

The error message for the API action, if any.

Suggest Edits

heartbeat

Sends a pulse to indicate that the current session is still in progress, so as not to automatically end it. Sessions are automatically timed out after 2 hours of inactivity — or 30 minutes if the session was paused first. If the user/device does not exist, the API request is skipped and a warning will be returned. You can modify this behavior with the createDisposition option (see below).

This method requires your production API clientKey.

 
posthttps://www.leanplum.com/api?action=heartbeat

Body Params

appId
string
required

The application ID. To find yours, select your app in the navigation column, and click Manage Apps. Then click Keys & Settings.

clientKey
string
required

The Production key for your Leanplum App.

apiVersion
string
required

The version of the Leanplum API to use. The current version is 1.0.6.

userId
string
required

The current user ID. You can set this to whatever your company uses for user IDs. Leave it blank to use the device ID. For more info, see selecting a user.

deviceId
string

A unique ID for the device targeted by the request. You must provide a deviceId and/or a userId. See selecting a user.

devMode
boolean

Whether the user is in Development Mode, i.e. the user associated with the request is a developer and not a user. This is important for reporting purposes. Default: false.

createDisposition
string

The policy that determines whether users are created by the API. Possible values:

  • CreateIfNeeded creates a user with the given IDs if one does not already exist.
  • CreateNever requires that the user already exists, otherwise the API action is skipped and a warning will be returned.

The default value for this method is CreateNever.

Response

The default response for most API actions.

response[].successboolean

Whether the request was received. Verify that the response has neither warning or error objects to confirm the action was taken. See here for more.

response[].warning.messagestring

The warning message for the API action, if any.

response[].error.messagestring

The error message for the API action, if any.

Suggest Edits

start

Starts a new session and returns the variables that have changed for the user. If the user/device does not exist, a new user will be created (see the createDisposition option below). This method requires your production API clientKey.

 
posthttps://www.leanplum.com/api?action=start

Body Params

appId
string
required

The application ID. To find yours, select your app in the navigation column, and click Manage Apps. Then click Keys & Settings.

clientKey
string
required

The Production key for your Leanplum App.

apiVersion
string
required

The version of the Leanplum API to use. The current version is 1.0.6.

userId
string
required

The current user ID. You can set this to whatever your company uses for user IDs. Leave it blank to use the device ID. For more info, see selecting a user.

deviceId
string

A unique ID for the device targeted by the request. You must provide a deviceId and/or a userId. See selecting a user.

devMode
boolean

Whether the user is in Development Mode, i.e. the user associated with the request is a developer and not a user. This is important for reporting purposes. Default: false.

createDisposition
string

The policy that determines whether users are created by the API. Possible values:

  • CreateIfNeeded creates a user with the given IDs if one does not already exist.
  • CreateNever requires that the user already exists, otherwise the API action is skipped and a warning will be returned.

The default value for this method is CreateIfNeeded.

appVersion
string

The version of the app used on this device. E.g. 2.0.1.

systemName
string

The name of the OS the current device is running. E.g. iOS.

systemVersion
string

The version number of the OS the current device is running. E.g. 6.0.

browserName
string

The name of the browser the current device is running. E.g. Chrome.

browserVersion
string

The version number of the browser the current device is running. E.g. 17.0.

deviceName
string

A human-readable name representing the device.

deviceModel
string

The model name of the device. E.g. iPad.

iosPushToken
string

The token used for Apple iOS push notifications on this device.

gcmRegistrationId
string

The registration ID used for Google Cloud Messaging push notifications on this device.

webPushSubscription
string

The JSON-encoded subscription used for web push notifications on this device.

userAttributes
object

A map of user attributes as key-value pairs. Each key must be a string. Attributes are saved across sessions. Only supplied attributes will be updated (i.e., if you omit an existing attribute, it will be preserved). Example: {"gender":"F","age":21}.

locale
string

The current locale the user is in. E.g. en_US.

country
string

The country the user is in, specified by ISO 2-letter code. E.g. US for United States. Set to (detect) to detect the country based on the IP address of the user.

region
string

The region (state) the user is in. E.g. ca for California. Set to (detect) to detect the region based on the IP address of the user.

city
string

The city the user is in. E.g. San Francisco. Set to (detect) to detect the city based on the IP address of the user.

location
string

The location (latitude/longitude) of the user. E.g. 37.775,-122.4183. Set to (detect) to detect the location based on the IP address of the user.

locationAccuracyType
string

The type of location that is provided (IP, CELL, or GPS). Default: IP.

timezone
string

The timezone abbreviation for the user. See list of timezone abbreviations.

timezoneOffsetSeconds
integer

The timezone offset from GMT in seconds.

background
boolean

Whether the app started in the background. In this case, the session won't be counted until resumeSession is executed. Default: false.

includeDefaults
boolean

Whether to include default ("defaults in code") values in output. Default: true.

Response

A successful request will return a response array with an object that has a success value set to true, and no error or warning object. It will also include variables, messages and other details relevant to that user.

responsearray

Response object for the API action.

response[].successboolean

Whether the request was received. Verify that the response has neither warning or error objects to confirm the action was taken. See here for more.

response[].messagesobject

In-app messages targeted at this user.

response[].varsobject

Key/value pairs for variables.

response[].vars.varNamestring

The value of the variable varName.

response[].interfaceRulesarray

Custom visual events and UI settings from UI Editor.

response[].variantsarray

List of variants that the user belongs to.

response[].variants[].idnumber

ID of the variant.

response[].regionsobject
response[].interfaceEventsarray

Interface events information.

response[].tokenstring
Suggest Edits

stop

Ends the current session. If the user/device does not exist, the API request is skipped and a warning will be returned. You can modify this behavior with the createDisposition option (see below). This method requires your production API clientKey.

 
posthttps://www.leanplum.com/api?action=stop

Body Params

appId
string
required

The application ID. To find yours, select your app in the navigation column, and click Manage Apps. Then click Keys & Settings.

clientKey
string
required

The Production key for your Leanplum App.

apiVersion
string
required

The version of the Leanplum API to use. The current version is 1.0.6.

userId
string
required

The current user ID. You can set this to whatever your company uses for user IDs. Leave it blank to use the device ID. For more info, see selecting a user.

deviceId
string

A unique ID for the device targeted by the request. You must provide a deviceId and/or a userId. See selecting a user.

devMode
boolean

Whether the user is in Development Mode, i.e. the user associated with the request is a developer and not a user. This is important for reporting purposes. Default: false.

createDisposition
string

The policy that determines whether users are created by the API. Possible values:

  • CreateIfNeeded creates a user with the given IDs if one does not already exist.
  • CreateNever requires that the user already exists, otherwise the API action is skipped and a warning will be returned.

The default value for this method is CreateNever.

Response

The default response for most API actions.

response[].successboolean

Whether the request was received. Verify that the response has neither warning or error objects to confirm the action was taken. See here for more.

response[].warning.messagestring

The warning message for the API action, if any.

response[].error.messagestring

The error message for the API action, if any.

Suggest Edits

track

Tracks one occurrence of an event for a user. If the user/device does not exist, a new user will be created (see the createDisposition option below). This method requires your production API clientKey.

 
posthttps://www.leanplum.com/api?action=track

Body Params

appId
string
required

The application ID. To find yours, select your app in the navigation column, and click Manage Apps. Then click Keys & Settings.

clientKey
string
required

The Production key for your Leanplum App.

apiVersion
string
required

The version of the Leanplum API to use. The current version is 1.0.6.

userId
string
required

The current user ID. You can set this to whatever your company uses for user IDs. Leave it blank to use the device ID. For more info, see selecting a user.

deviceId
string

A unique ID for the device targeted by the request. You must provide a deviceId and/or a userId. See selecting a user.

devMode
boolean

Whether the user is in Development Mode, i.e. the user associated with the request is a developer and not a user. This is important for reporting purposes. Default: false.

createDisposition
string

The policy that determines whether users are created by the API. Possible values:

  • CreateIfNeeded creates a user with the given IDs if one does not already exist.
  • CreateNever requires that the user already exists, otherwise the API action is skipped and a warning will be returned.

The default value for this method is CreateIfNeeded.

event
string
required

The name of the event. Use "Purchase" to identify a monetization event, with the event value being the revenue. You can change the default monetization event name in Analytics by going to the metric chooser and clicking the Monetization metric category.

value
float

The event value. For example, for a purchase event, this would be the purchase price.

currencyCode
string

The ISO 4217 currency code associated with value. Leanplum will automatically convert value into your preferred currency, while retaining the original price and currency code as event parameters localCurrency and localPrice. Currency conversion rates are updated every hour.

info
string

Any info attached to the event.

time
float

Option to provide the UNIX timestamp for when the event occurred, which may be different from the current time.

params
object

A flat object of parameters as key-value pairs. Each key must be a string, and up to 50 parameters may be set. Example: {"gender":"F","age":21}.

messageId
integer

The message ID this event is associated with. Set this to track a user's interaction with a message. To track a message Send or a View, set the event argument to an empty string. For other interactions, set the event argument to the type of action (example values include Open, Cancel, Accept). The Leanplum SDK does this automatically, so this should be used for advanced use cases only.

disposition
string

Determines how tracked events affect sessions and user activity. If present, disposition must have one of the following values:

  • active (default): Used for events reflect user activity. Active events should mark the user as active, and should be tracked within a session. (Replaces the deprecated option allowOffline: false.)
  • passive: Used for events that do not correspond to user activity. These events do not need to occur within a session, and do not mark a user as active. For example, sending a user a message would be tracked passively, since it affects a user, but does not represent user activity. (Replaces the deprecated option allowOffline: true.)
  • requireActive: Used for events that must only be tracked within a session. These events are rejected, and return a warning response with ignored: true if the user does not have an active session. Clients should detect the warning by the ignored field, as warning messages may change.

Response

The default response for most API actions.

response[].successboolean

Whether the request was received. Verify that the response has neither warning or error objects to confirm the action was taken. See here for more.

response[].warning.messagestring

The warning message for the API action, if any.

response[].error.messagestring

The error message for the API action, if any.

Note that parameters and Event Values are not available in Developer activity analytics, but you can verify your parameters are being tracked correctly in the Debugger console.

Suggest Edits

User Information

 
Suggest Edits

setUserAttributes

Sets user attributes for the user given by userId and/or deviceId. If the user has an open session, the attributes for the current session will also be updated. Attributes will then propagate on data going forward. User properties not supplied in this method will not be affected. If the user/device does not exist, a new user will be created (see the createDisposition option below).

This method requires your production API clientKey.

 
posthttps://www.leanplum.com/api?action=setUserAttributes

Body Params

appId
string
required

The application ID. To find yours, select your app in the navigation column, and click Manage Apps. Then click Keys & Settings.

clientKey
string
required

The Production key for your Leanplum App.

apiVersion
string
required

The version of the Leanplum API to use. The current version is 1.0.6.

userId
string
required

The current user ID. You can set this to whatever your company uses for user IDs. Leave it blank to use the device ID. For more info, see selecting a user.

deviceId
string

A unique ID for the device targeted by the request. You must provide a deviceId and/or a userId. See selecting a user.

createDisposition
string

The policy that determines whether users are created by the API. Possible values:

  • CreateIfNeeded creates a user with the given IDs if one does not already exist.
  • CreateNever requires that the user already exists, otherwise the API action is skipped and a warning will be returned.

The default value for this method is CreateIfNeeded.

userAttributes
object

A map of user attributes as key-value pairs. Each key must be a string. Attributes are saved across sessions. Only supplied attributes will be updated (i.e., if you omit an existing attribute, it will be preserved). Example: {"gender":"F","age":21}.

userAttributeValuesToAdd
object

A map of values to add to existing user attribute sets. For example, supply {"Interests":"Sports"} to add Sports to the existing set of Interests.

userAttributeValuesToRemove
object

A map of values to remove from existing user attribute sets. For example, supply {"Interests":"Sports"} to remove Sports from the existing set of interests.

userAttributeValuesToIncrement
object

A map of values to increment onto existing user attributes. The existing attribute value and the increment must both be integers or the operation will be skipped. If the existing attribute is not set, its value will be inferred as 0.

For example, supply {"unreadMessages":1} to add 1 to the number of unread messages.

unsubscribeCategoriesToAdd
array of integers

A list of email categories to unsubscribe a user from.

unsubscribeCategoriesToRemove
array of integers

A list of email categories to re-subscribe a user to.

unsubscribeChannelsToAdd
string

A messaging channel (e.g. Email) to unsubscribe the user from. Use this to unsubscribe a user from all marketing email categories.

unsubscribeChannelsToRemove
string

A messaging channel (e.g. Email) to re-subscribe the user to. Use this to re-subscribe a user to all marketing email categories (except any categories they have unsubscribed from).

newUserId
string

If supplied, updates the user of the current session with newUserId. This can have certain effects:

  • Login: If the current user has no user ID and the user given by newUserId already exists, the current and existing user profiles will be merged, and the current profile will be deleted.
  • Register: If there is no current user ID and the user given by newUserId does not exist, the current user will be simply assigned newUserId as its user ID.
  • Switch user: If the current user has a user ID, the current session will be ended and a new session will be started with the user given by newUserId. A user with newUserId will be created if one does not already exist.
events
object

A map of event data to update for the current user. The keys are the event names, each should have a nested object with at least one of the following attributes:

  • count: New lifetime count of this event for the current user.
  • countIncrement: Amount to increment the lifetime count of this event.
  • value: New lifetime value of this event for the current user.
  • valueIncrement: Amount to increment the lifetime value of this event.
  • firstTime: Time that this event first occurred, in seconds since midnight UTC on January 1, 1970.
  • lastTime: Time that this event last occurred, in seconds since midnight UTC on January 1, 1970.

Example: Here's how to set the lifetime count for an event called "myEvent":

{ "myEvent": { count: 1 } }

states
object

A map of state data to update for the current user. The keys are the state names, and each should have a nested object with at least one of the following attributes:

  • count: New lifetime count of this state for the current user.
  • countIncrement: Amount to increment the lifetime count of this state.
  • firstTime: Time that this state first occurred, in seconds since midnight UTC on January 1, 1970.
  • lastTime: Time that this state last occurred, in seconds since midnight UTC on January 1, 1970.

Example: Here's how to set the lifetime count for a state called "splashPage":

{ "splashPage": { count: 23 } }

created
float

The time at which the user was created, in seconds since midnight UTC on January 1, 1970.

lastActive
float

The time at which the user was last active, in seconds since midnight UTC on January 1, 1970.

totalSessions
integer

The total number of sessions that a user has had in their lifetime.

timeSpentInApp
float

The total number of seconds spent in the app in the user's lifetime.

locale
string

The current locale the user is in. E.g. en_US.

country
string

The country the user is in, specified by ISO 2-letter code. E.g. US for United States. Set to (detect) to detect the country based on the IP address of the user.

region
string

The region (state) the user is in. E.g. ca for California. Set to (detect) to detect the region based on the IP address of the user.

city
string

The city the user is in. E.g. San Francisco. Set to (detect) to detect the city based on the IP address of the user.

location
string

The location (latitude/longitude) of the user. E.g. 37.775,-122.4183. Set to (detect) to detect the location based on the IP address of the user.

locationAccuracyType
string

The type of location that is provided (IP, CELL, or GPS). Default: IP.

timezone
string

The timezone abbreviation for the user. See list of timezone abbreviations.

timezoneOffsetSeconds
integer

The timezone offset from GMT in seconds.

devices
array of objects

A list of device objects associated with this user.

devMode
boolean

Whether the user is in Development Mode, i.e. the user associated with the request is a developer and not a user. This is important for reporting purposes. Default: false.

Response

The default response for most API actions.

response[].successboolean

Whether the request was received. Verify that the response has neither warning or error objects to confirm the action was taken. See here for more.

response[].warning.messagestring

The warning message for the API action, if any.

response[].error.messagestring

The error message for the API action, if any.

Suggest Edits

setDeviceAttributes

Sets attributes for the current device. If the device is shared between multiple users, pass a userId with the deviceId to update the device for each user. (Passing just the deviceId will only update it once). If the device already exists, the attributes will be updated. If the device and user do not exist, a new user will be created along with this device (see the createDisposition option below). See selecting a user for more.

This method requires your production API clientKey.

At least one of the following must be set to create/update a device: appVersion, systemName, systemVersion, browserName, browserVersion, deviceName, deviceModel, iosPushToken, gcmRegistrationId, or webPushSubscription.

 
posthttps://www.leanplum.com/api?action=setDeviceAttributes

Body Params

appId
string
required

The application ID. To find yours, select your app in the navigation column, and click Manage Apps. Then click Keys & Settings.

clientKey
string
required

The Production key for your Leanplum App.

apiVersion
string
required

The version of the Leanplum API to use. The current version is 1.0.6.

deviceId
string
required

The unique ID for the device.

userId
string

The current user ID. You can set this to whatever your company uses for user IDs. Leave it blank to use the device ID. For more info, see selecting a user.

createDisposition
string

The policy that determines whether users are created by the API. Possible values:

  • CreateIfNeeded creates a user with the given IDs if one does not already exist.
  • CreateNever requires that the user already exists, otherwise the API action is skipped and a warning will be returned.

The default value for this method is CreateIfNeeded.

devMode
boolean

Whether the user is in Development Mode, i.e. the user associated with the request is a developer and not a user. This is important for reporting purposes. Default: false.

appVersion
string

The version of the app used on this device. E.g. 2.0.1.

systemName
string

The name of the OS the current device is running. E.g. iOS.

systemVersion
string

The version number of the OS the current device is running. E.g. 6.0.

browserName
string

The name of the browser the current device is running. E.g. Chrome.

browserVersion
string

The version number of the browser the current device is running. E.g. 17.0.

deviceName
string

A human-readable name representing the device.

deviceModel
string

The model name of the device. E.g. iPad.

iosPushToken
string

The token used for Apple iOS push notifications on this device.

gcmRegistrationId
string

The registration ID used for Google Cloud Messaging push notifications on this device.

webPushSubscription
string

The JSON-encoded subscription used for web push notifications on this device.

Response

The default response for most API actions.

response[].successboolean

Whether the request was received. Verify that the response has neither warning or error objects to confirm the action was taken. See here for more.

response[].warning.messagestring

The warning message for the API action, if any.

response[].error.messagestring

The error message for the API action, if any.

Suggest Edits

setTrafficSourceInfo

Sets traffic source information for the current session of a user. If the user/device does not exist, a new user will be created (see the createDisposition option below). This method requires your production API clientKey.

 
posthttps://www.leanplum.com/api?action=setTrafficSourceInfo

Body Params

appId
string
required

The application ID. To find yours, select your app in the navigation column, and click Manage Apps. Then click Keys & Settings.

clientKey
string
required

The Production key for your Leanplum App.

apiVersion
string
required

The version of the Leanplum API to use. The current version is 1.0.6.

userId
string
required

The current user ID. You can set this to whatever your company uses for user IDs. Leave it blank to use the device ID. For more info, see selecting a user.

deviceId
string

A unique ID for the device targeted by the request. You must provide a deviceId and/or a userId. See selecting a user.

createDisposition
string

The policy that determines whether users are created by the API. Possible values:

  • CreateIfNeeded creates a user with the given IDs if one does not already exist.
  • CreateNever requires that the user already exists, otherwise the API action is skipped and a warning will be returned.

The default value for this method is CreateIfNeeded.

trafficSource
object

An object of traffic source parameters.

trafficSource.publisherId
string
required

ID of the publisher used to refer the user. Example: 1001.

trafficSource.publisherName
string
required

Name of the publisher used to refer the user. Example: Big Fish Games.

trafficSource.publisherSubPublisher
string
required

Name of the developer used to refer the user. Example: GameDeveloper1.

trafficSource.publisherSubSite
string
required

Name of the app or website used to refer the user. Example: MyLittleApp.

trafficSource.publisherSubCampaign
string
required

Name of the campaign used to refer the user. Example: US CPI.

trafficSource.publisherSubAdGroup
string
required

Name of the ad group used to refer the user. Example: banners.

trafficSource.publisherSubAd
string
required

Name of the ad used to refer the user. Example: blue1.

time
float

The time at which the session started, in seconds since midnight UTC on January 1, 1970. This should be no more than 2 minutes after the session started. If not provided, uses the current time.

devMode
boolean

Whether the user is in Development Mode, i.e. the user associated with the request is a developer and not a user. This is important for reporting purposes. Default: false.

Response

The default response for most API actions.

response[].successboolean

Whether the request was received. Verify that the response has neither warning or error objects to confirm the action was taken. See here for more.

response[].warning.messagestring

The warning message for the API action, if any.

response[].error.messagestring

The error message for the API action, if any.

Suggest Edits

registerDevice

Registers the current device for development. This method requires your development API clientKey.

 
posthttps://www.leanplum.com/api?action=registerDevice

Body Params

appId
string
required

The application ID. To find yours, select your app in the navigation column, and click Manage Apps. Then click Keys & Settings.

clientKey
string
required

The Development key for your Leanplum App.

apiVersion
string
required

The version of the Leanplum API to use. The current version is 1.0.6.

deviceId
string
required

A unique ID for the device to be registered by the request.

email
string
required

The email address corresponding to the Leanplum user account to which the device belongs.

Response

Returns the status of the request and device registration.

response[].successboolean

Whether the request was received. Verify that the response has neither warning or error objects to confirm the action was taken. See here for more.

response[].registeredboolean

Whether the device was just registered. If the device has already been registered, this will be false.

Suggest Edits

deleteUser

Permanently removes all of a user’s attribute information from our database. To erase a user’s data entirely — including attribute, analytics, and sessions data — set the fullErasure flag to true. You can bulk delete users with multi (import mode) or by contacting your CSM. deleteUser calls are exempt from API billing.

This method requires your development API clientKey.

 
posthttps://www.leanplum.com/api?action=deleteUser

Body Params

appId
string
required

The application ID. To find yours, select your app in the navigation column, and click Manage Apps. Then click Keys & Settings.

clientKey
string
required

The Development key for your Leanplum App.

apiVersion
string
required

The version of the Leanplum API to use. The current version is 1.0.6.

userId
string
required

The user ID to delete. Required unless using deviceId.

deviceId
string

Required if no userId. The deviceId to delete. Only use this if there is no userId set. Note that deviceId will only delete data from devices where a user has never logged-in. If a logged-in user has been on the device, you must call the deleteUser API with the userId.

fullErasure
boolean

Deletes all session and analytics data for the selected user. This may take up to 15 days to process fully. Defaults to false — should be set to true for GDPR-related deletion requests.

Response

The default response for most API actions.

response[].successboolean

Whether the request was received. Verify that the response has neither warning or error objects to confirm the action was taken. See here for more.

response[].warning.messagestring

The warning message for the API action, if any.

response[].error.messagestring

The error message for the API action, if any.

Suggest Edits

block

Stops all data collection for a user going forward. block also erases any data previously associated with that user, including all of their attribute and analytics data. The block will take effect as soon as the “success” response is returned. It may take up to 15 days to delete the user’s data completely.

Note that the block call deletes a user's past data, but does not delete the user entirely. This allows you to use the unblock call to resume data collection.

 
posthttps://www.leanplum.com/api?action=block

Body Params

appId
string
required

The application ID. To find yours, select your app in the navigation column, and click Manage Apps. Then click Keys & Settings.

clientKey
string
required

The Development key for your Leanplum App.

apiVersion
string
required

The version of the Leanplum API to use. The current version is 1.0.6.

userId
string
required

The userId to block data collection for. Required unless you use deviceId. See below for details.

deviceId
string

The deviceId to block data collection for. Required if no userId.
A deviceId block will only block data from devices where a user has not logged-in on the device. If a user has logged-in on the device before, you must call the block API with the userId.

devMode
boolean

Whether the user is in Development Mode, i.e. the user associated with the request is a developer and not a user. This is important for reporting purposes. Default: false.

Response

The default response for most API actions.

response[].successboolean

Whether the request was received. Verify that the response has neither warning or error objects to confirm the action was taken. See here for more.

response[].warning.messagestring

The warning message for the API action, if any.

response[].error.messagestring

The error message for the API action, if any.

Suggest Edits

unblock

Resumes data collection for a specific user, and ends a previous block on data collection. This will not restore any of data that was deleted by the previous block call.

 
posthttps://www.leanplum.com/api?action=unblock

Body Params

appId
string
required

The application ID. To find yours, select your app in the navigation column, and click Manage Apps. Then click Keys & Settings.

clientKey
string
required

The Development key for your Leanplum App.

apiVersion
string
required

The version of the Leanplum API to use. The current version is 1.0.6.

userId
string
required

The userId to unblock data collection for. Required unless you use deviceId. See below for details.

deviceId
string

The deviceId to unblock data collection for. Required if no userId.
A deviceId block or unblock call will only work for devices where a user has not logged-in on the device. If a user has logged-in on the device before, you must use userId with the block or unblock API calls.

devMode
boolean

Whether the user is in Development Mode, i.e. the user associated with the request is a developer and not a user. This is important for reporting purposes. Default: false.

Response

The default response for most API actions.

response[].successboolean

Whether the request was received. Verify that the response has neither warning or error objects to confirm the action was taken. See here for more.

response[].warning.messagestring

The warning message for the API action, if any.

response[].error.messagestring

The error message for the API action, if any.

 
Suggest Edits

getMessage

Gets information about a message. This method requires your content read-only API clientKey.

 
gethttps://www.leanplum.com/api?action=getMessage

Query Params

appId
string
required

The application ID. To find yours, select your app in the navigation column, and click Manage Apps. Then click Keys & Settings.

clientKey
string
required

The Content Read-only key for your Leanplum App.

apiVersion
string
required

The version of the Leanplum API to use. The current version is 1.0.6.

id
integer
required

The numeric message ID.

includeDrafts
boolean

Include drafts and unpublished changes. Default: false.

Response

A successful response will return details about a message.

responsearray
response[].successboolean

Whether the request was received. Verify that the response has neither warning or error objects to confirm the action was taken. See here for more.

response[].messageobject

A message object.

response[].message.idinteger

The message ID.

response[].message.namestring

The name of the message.

response[].message.activeboolean

Whether the message is running in production.

response[].message.creatednumber

Unix timestamp of when the message was created.

response[].message.finishednumber

Unix timestamp of when the message was finished (optional).

response[].message.segmentsstring

The segment of users that the message applies to. Omitted for all users.

response[].message.messageTypestring

The type of the message. (e.g. Push Notification, Interstitial, etc.)

Suggest Edits

getMessages

Gets information about all the messages for a given app. This method requires your content read-only API clientKey.

 
gethttps://www.leanplum.com/api?action=getMessages

Query Params

appId
string
required

The application ID. To find yours, select your app in the navigation column, and click Manage Apps. Then click Keys & Settings.

clientKey
string
required

The Content Read-only key for your Leanplum App.

apiVersion
string
required

The version of the Leanplum API to use. The current version is 1.0.6.

includeDrafts
boolean

Include drafts and unpublished changes. Default: false.

recent
boolean

Only return information about active or recently finished messages. Default: true.

Response

A successful response will return a list of messages.

responsearray
response[].successboolean

Whether the request was received. Verify that the response has neither warning or error objects to confirm the action was taken. See here for more.

response[].messagesarray

A list of message objects.

response[].messages[]object

A message object.

response[].messages[].idinteger

The message ID.

response[].messages[].namestring

The name of the message.

response[].messages[].activeboolean

Whether the message is running in production.

response[].messages[].creatednumber

Unix timestamp of when the message was created.

response[].messages[].finishednumber

Unix timestamp of when the message was finished (optional).

response[].messages[].segmentsstring

The segment of users that the message applies to. Omitted for all users.

response[].messages[].messageTypestring

The type of the message. (e.g. Push Notification, Interstitial, etc.)

Suggest Edits

getUnsubscribeCategories

Gets information about all the email subscription categories for a given app. This method requires your content read-only API clientKey.

 
gethttps://www.leanplum.com/api?action=getUnsubscribeCategories

Query Params

appId
string
required

The application ID. To find yours, select your app in the navigation column, and click Manage Apps. Then click Keys & Settings.

clientKey
string
required

The Content Read-only key for your Leanplum App.

apiVersion
string
required

The version of the Leanplum API to use. The current version is 1.0.6.

Response

A successful response will return a list of email subscription categories.

responsearray
response[].successboolean

Whether the request was received. Verify that the response has neither warning or error objects to confirm the action was taken. See here for more.

response[].categoriesarray

A list of email subscription categories.

response[].categories[]object
response[].categories[].idinteger

The email category ID. Can be passed to setUserAttributes as the unsubscribeCategoriesToAdd parameter to unsubscribe a user or unsubscribeCategoriesToRemove parameter to re-subscribe a user from that category.

response[].categories[].namestring

The name of the email category.

response[].categories[].descriptionstring

The description of the email category.

Suggest Edits

sendMessage

Sends a message (typically a push notification) to one device or user. You must provide a deviceId and/or a userId. If deviceId is provided, the message will be sent to the corresponding device only; if only userId is provided, the message will be sent to all devices of the user with specified userId. If the user/device does not exist, the API request is skipped and a warning will be returned. You can modify this behavior with the createDisposition option (see below).

Messages are queued, so they will be sent after the request completes.

This method requires your production API clientKey.

 
posthttps://www.leanplum.com/api?action=sendMessage

Body Params

appId
string
required

The application ID. To find yours, select your app in the navigation column, and click Manage Apps. Then click Keys & Settings.

clientKey
string
required

The Production key for your Leanplum App.

apiVersion
string
required

The version of the Leanplum API to use. The current version is 1.0.6.

userId
string
required

The current user ID. You can set this to whatever your company uses for user IDs. Leave it blank to use the device ID. For more info, see selecting a user.

deviceId
string

A unique ID for the device targeted by the request. You must provide a deviceId and/or a userId. See selecting a user.

messageId
integer
required

The ID of the message, found in the URL when viewing a message (e.g. www.leanplum.com/dashboard#/{APP_ID}/messaging/{MESSAGE_ID}.

values
object

A JSON object of key-value pairs to override template variables used in the message. See below for example.

force
boolean

Whether to send the message regardless of whether the user meets the targeting criteria. Default: false.

devMode
boolean

Whether the user is in Development Mode, i.e. the user associated with the request is a developer and not a user. This is important for reporting purposes. Default: false.

createDisposition
string

The policy that determines whether users are created by the API. Possible values:

  • CreateIfNeeded creates a user with the given IDs if one does not already exist.
  • CreateNever requires that the user already exists, otherwise the API action is skipped and a warning will be returned.

The default value for this method is CreateNever.

Response

The default response for most API actions.

response[].successboolean

Whether the request was received. Verify that the response has neither warning or error objects to confirm the action was taken. See here for more.

response[].warning.messagestring

The warning message for the API action, if any.

response[].error.messagestring

The error message for the API action, if any.

sendMessage values example

If the message text is Hello {{'name'}}, you have {{'numMessages'}} new messages!, you can set values to {"name": "Bob", "numMessages": 5} to produce: Hello Bob, you have 5 new messages!

Suggest Edits

addAndroidNotificationChannel

Creates new notification channels and updates existing ones. Updateable parameters include channel name, description, and default. This method requires your development API clientKey.

Leanplum will not interfere with any channel defined directly in your app code or by other mobile marketing providers. For instance, if your app has both a “Promotions” channel and a “Transactional” channel, but your marketer should only have access to Promotions, then you should only send that channel to Leanplum.

 
posthttps://www.leanplum.com/api?action=addAndroidNotificationChannel

Body Params

appId
string
required

The application ID. To find yours, select your app in the navigation column, and click Manage Apps. Then click Keys & Settings.

clientKey
string
required

The Development key for your Leanplum App.

apiVersion
string
required

The version of the Leanplum API to use. The current version is 1.0.6.

id
string
required

The channel ID. Also used when updating existing channels.

name
string
required

The human-readable name that will appear on the Leanplum dashboard (e.g. Promotions, Transactional, etc.). Should be distinguishable from all other channel names.

importance
integer
required

Sets the importance of all notifications in the channel, which determines how much the channel can interrupt the user. The default is 3: notifications will show everywhere, make noise, but does not visually intrude. For more, see the Android documentation.

description
string

The user-visible description of this channel.

groupId
string

See Android docs here.

enableLights
boolean

Whether to enable lights.

lightColor
integer

See Android docs for available colors.

enableVibration
boolean

Whether to enable vibration.

vibrationPattern
array of numbers

See Android docs here.

lockscreenVisibility
integer

See Android documentation here.

bypassDnd
boolean

See Android docs here.

showBadge
boolean

Whether to show badge.

sound
string

URI of sound file, which must be stored locally on the device. See Andoroid Docs here.

default
boolean

This is a Leanplum parameter, indicating whether this channel should be the default channel referenced in the dashboard. Leanplum automatically defines the first channel you create as the “default” channel, preventing the dashboard user from having to manually choose a channel for every campaign.

Response

The response will indicate whether or not the channel was created successfully.

response[].successboolean

Whether the request was received. Verify that the response has neither warning or error objects to confirm the action was taken. See here for more.

response[].channelCreatedboolean

Whether or not channel creation was successful.

response[].channelIdstring

The channel ID. Same as the id passed in the call.

response[].channelUpdatedboolean

True if channel was updated successfully.

response[].namestring

The human-readable name that will appear on the Leanplum dashboard (e.g. Promotions, Transactional, etc.). Should be distinguishable from all other channel names.

response[].importanceinteger

The importance of all notifications in this channel.

Suggest Edits

getAndroidNotificationChannels

Gets all Android notification channels defined in Leanplum and their associated settings. No additional arguments are required. This method requires your production API clientKey.

This method requires your production API clientKey.

 
gethttps://www.leanplum.com/api?action=getAndroidNotificationChannels

Query Params

appId
string
required

The application ID. To find yours, select your app in the navigation column, and click Manage Apps. Then click Keys & Settings.

clientKey
string
required

The Production key for your Leanplum App.

apiVersion
string
required

The version of the Leanplum API to use. The current version is 1.0.6.

Response

Returns the Android notification channels you have defined in Leanplum and their associated settings. Note — an HTTP status of 200 does not guarantee the request was processed successfully. Pay close attention to `response[].warning` and `response[].error`; if returned with a message, the request may have been skipped or ignored.

response[]array

The response array.

response[].successboolean

Whether the request was received. Verify that the response has neither warning or error objects to confirm the action was taken. See here for more.

response[].notificationChannelsarray

Contains the name, importance, id, and other settings of all Android notification channels defined in Leanplum.

Suggest Edits

deleteAndroidNotificationChannel

Permanently removes an Android notification channel from Leanplum. This method requires your development API clientKey.

Note — You cannot delete the channel that is defined as default (unless it is the only channel). To delete the default channel, mark another channel as default first.

 
posthttps://www.leanplum.com/api?action=deleteAndroidNotificationChannel

Body Params

appId
string
required

The application ID. To find yours, select your app in the navigation column, and click Manage Apps. Then click Keys & Settings.

clientKey
string
required

The Development key for your Leanplum App.

apiVersion
string
required

The version of the Leanplum API to use. The current version is 1.0.6.

channelId
string
required

The ID of the channel you want to delete permanently. Note - this is the same as the id parameter in the addAndroidNotificationChannel method.

Response

Response indicates whether channel deletion was successful and returns the channel id of the deleted channel.

response[].successboolean

Whether the request was received. Verify that the response has neither warning or error objects to confirm the action was taken. See here for more.

response[].channelDeletedboolean

True if channel was deleted successfully.

response[].channelIdstring

The channel id. (Same as id parameter in addAndroidNotificationChannel method.)

Suggest Edits

A/B Tests

 
Suggest Edits

getAbTest

Gets information about an A/B test. This method requires your content read-only API clientKey.

 
gethttps://www.leanplum.com/api?action=getAbTest

Query Params

appId
string
required

The application ID. To find yours, select your app in the navigation column, and click Manage Apps. Then click Keys & Settings.

clientKey
string
required

The Content Read-only key for your Leanplum App.

apiVersion
string
required

The version of the Leanplum API to use. The current version is 1.0.6.

id
integer
required

The numeric A/B test ID.

includeDrafts
boolean

Include drafts and unpublished changes. Default: false.

Response

A successful response will return details about an A/B test.

responsearray
response[].successboolean

Whether the request was received. Verify that the response has neither warning or error objects to confirm the action was taken. See here for more.

response[].abTestobject

An A/B test object.

response[].abTest.idinteger

The A/B test ID.

response[].abTest.namestring

The name of the A/B test.

response[].abTest.activeboolean

Whether the A/B test is running in production.

response[].abTest.creatednumber

Unix timestamp of when the A/B test was created.

response[].abTest.updatednumber

Unix timestamp of when the A/B test was last updated.

response[].abTest.finishednumber

Unix timestamp of when the A/B test was finished (optional).

response[].abTest.segmentsstring

The segment of users that the test applies to. Omitted for all users.

response[].abTest.chosenVariantnumber

The id number of the variant you selected as the winner of the A/B test (optional).

response[].abTest.targetingStickyboolean

Whether the targeting for the test was sticky (magnet button on).

response[].abTest.statestring

The current status of the A/B test, e.g. active, inactive, finished.

response[].abTest.variantsarray

A list of variant objects for the A/B test.

response[].abTest.variants[].idinteger

The ID of the variant.

response[].abTest.variants[].namestring

The name of the variant.

response[].abTest.variants[].percentnumber

The percentage of new users to allocate.

response[].abTest.variants[].segmentsstring

The segment of users that the variant applies to. Omitted for all users.

response[].abTest.detailsobject

Contains info about the users who created/last updated the test.

response[].abTest.details.publishedBystring

The username or email address of the Leanplum user who published the test.

response[].abTest.details.createdBystring

The username or email address of the Leanplum user who created the test.

Suggest Edits

getAbTests

Gets information about A/B tests. This method requires your content read-only API clientKey.

 
gethttps://www.leanplum.com/api?action=getAbTests

Query Params

appId
string
required

The application ID. To find yours, select your app in the navigation column, and click Manage Apps. Then click Keys & Settings.

clientKey
string
required

The Content Read-only key for your Leanplum App.

apiVersion
string
required

The version of the Leanplum API to use. The current version is 1.0.6.

includeDrafts
boolean

Include drafts and unpublished changes. Default: false.

recent
boolean

Only return information about active or recently finished A/B tests. Default: true.

Response

A successful response will return a list of A/B tests.

responsearray
response[].successboolean

Whether the request was received. Verify that the response has neither warning or error objects to confirm the action was taken. See here for more.

response[].abTestsarray

A list of A/B test objects.

response[].abTests[]object

An A/B test object.

response[].abTests[].idinteger

The A/B test ID.

response[].abTests[].namestring

The name of the A/B test.

response[].abTests[].activeboolean

Whether the A/B test is running in production.

response[].abTests[].creatednumber

Unix timestamp of when the A/B test was created.

response[].abTests[].updatednumber

Unix timestamp of when the A/B test was last updated.

response[].abTests[].finishednumber

Unix timestamp of when the A/B test was finished (optional).

response[].abTests[].segmentsstring

The segment of users that the test applies to. Omitted for all users.

response[].abTests[].chosenVariantnumber

The id number of the variant you selected as the winner of the A/B test (optional).

response[].abTests[].targetingStickyboolean

Whether the targeting for the test was sticky (magnet button on).

response[].abTests[].statestring

The current status of the A/B test, e.g. active, inactive, finished.

response[].abTests[].variantsarray

A list of variant objects for the A/B test.

response[].abTests[].variants[].idinteger

The ID of the variant.

response[].abTests[].variants[].namestring

The name of the variant.

response[].abTests[].variants[].percentnumber

The percentage of new users to allocate.

response[].abTests[].variants[].segmentsstring

The segment of users that the variant applies to. Omitted for all users.

Suggest Edits

getVariant

Gets information about an A/B test variant. This method requires your content read-only API clientKey.

 
gethttps://www.leanplum.com/api?action=getVariant

Query Params

appId
string
required

The application ID. To find yours, select your app in the navigation column, and click Manage Apps. Then click Keys & Settings.

clientKey
string
required

The Content Read-only key for your Leanplum App.

apiVersion
string
required

The version of the Leanplum API to use. The current version is 1.0.6.

id
integer
required

The numeric variant ID.

includeDrafts
boolean

Include drafts and unpublished changes. Default: false.

Response

A successful response will return details about a variant.

responsearray
response[].successboolean

Whether the request was received. Verify that the response has neither warning or error objects to confirm the action was taken. See here for more.

response[].variantobject

A variant object.

response[].variant.idinteger

The ID of the variant.

response[].variant.namestring

The name of the variant.

response[].variant.percentnumber

The percentage of new users to allocate.

response[].variant.segmentsstring

The segment of users that the variant applies to. Omitted for all users.

Suggest Edits

Files and Variables

 
Suggest Edits

getVars

Gets the variable diff for the app or current device. If the user/device does not exist, the API request is skipped and a warning will be returned. You can modify this behavior with the createDisposition option (see below). If neither userId or deviceId are provided, it will return the default variables that would be seen by a blank user.

This method requires your production API clientKey.

 
gethttps://www.leanplum.com/api?action=getVars

Query Params

appId
string
required

The application ID. To find yours, select your app in the navigation column, and click Manage Apps. Then click Keys & Settings.

clientKey
string
required

The Production key for your Leanplum App.

apiVersion
string
required

The version of the Leanplum API to use. The current version is 1.0.6.

createDisposition
string

The policy that determines whether users are created by the API. Possible values:

  • CreateIfNeeded creates a user with the given IDs if one does not already exist.
  • CreateNever requires that the user already exists, otherwise the API action is skipped and a warning will be returned.

The default value for this method is CreateNever.

userId
string

The current user ID. You can set this to an email address or whatever you use at your company for user IDs. Leave it blank to use the device ID. If deviceId and userId are not specified, the default variables will be retrieved for the app. Developer mode permission is required.

deviceId
string

The device ID for which to retrieve the variables. If deviceId and userId are not specified, the default variables will be retrieved for the app. Developer mode permission is required.

devMode
boolean

Whether the user is in Development Mode, i.e. the user associated with the request is a developer and not a user. This is important for reporting purposes. Default: false.

includeDefaults
boolean

Whether to include default ('defaults in code') values in output. Default: true.

Response

A successful request will return a response array with an object that has a success value set to true, and no error or warning object. It will also include variables, messages and other details relevant to that user.

responsearray

Response object for the API action.

response[].successboolean

Whether the request was received. Verify that the response has neither warning or error objects to confirm the action was taken. See here for more.

response[].varsobject

Key/value pairs for variables.

response[].vars.varNamestring

The value of the variable varName.

response[].variantsarray

List of variants that the user() belongs to.

response[].variants[].idnumber

ID of the variant.

Suggest Edits

setVars

Sets the list of variables to be used in the Leanplum content management system. This method requires your development API clientKey.

 
posthttps://www.leanplum.com/api?action=setVars

Body Params

appId
string
required

The application ID. To find yours, select your app in the navigation column, and click Manage Apps. Then click Keys & Settings.

clientKey
string
required

The Development key for your Leanplum App.

apiVersion
string
required

The version of the Leanplum API to use. The current version is 1.0.6.

vars
object
required

A JSON-encoded representation of the variables. Variable values can be strings, numbers, booleans, arrays, or objects.

Example: { "message": "hello world!" }

deviceId
string

If the deviceId is specified, file variables will be tagged with the current version of the app running on that device.

Response

The default response for most API actions.

response[].successboolean

Whether the request was received. Verify that the response has neither warning or error objects to confirm the action was taken. See here for more.

response[].warning.messagestring

The warning message for the API action, if any.

response[].error.messagestring

The error message for the API action, if any.

Suggest Edits

deleteVars

Deletes the list of variables from the Leanplum content management system. This method requires your development API clientKey.

 
posthttps://www.leanplum.com/api?action=deleteVars

Body Params

appId
string
required

The application ID. To find yours, select your app in the navigation column, and click Manage Apps. Then click Keys & Settings.

clientKey
string
required

The Development key for your Leanplum App.

apiVersion
string
required

The version of the Leanplum API to use. The current version is 1.0.6.

vars
array of strings
required

A list of variables to be removed.

Response

Returns the status and a list of variables that were deleted.

response[].successboolean

Whether the request was received. Verify that the response has neither warning or error objects to confirm the action was taken. See here for more.

response[].variablesRemovedarray

A list of variables that were removed.

Suggest Edits

downloadFile

Redirects to a file uploaded to the Leanplum dashboard (the File tab). Must be the only API method in a batch. This method requires your production API clientKey.

 
gethttps://www.leanplum.com/api?action=downloadFile

Query Params

appId
string
required

The application ID. To find yours, select your app in the navigation column, and click Manage Apps. Then click Keys & Settings.

clientKey
string
required

The Production key for your Leanplum App.

apiVersion
string
required

The version of the Leanplum API to use. The current version is 1.0.6.

filename
string
required

The name of the file to download.

Response

A successful request will redirect to the file and begin a download.

Suggest Edits

uploadFile

Uploads up to 16 files or 50 MB at a time to use in the File picker and File tab of the Leanlum dashboard. This method requires your development API clientKey.

 
posthttps://www.leanplum.com/api?action=uploadFile

Body Params

appId
string
required

The application ID. To find yours, select your app in the navigation column, and click Manage Apps. Then click Keys & Settings.

clientKey
string
required

The Development key for your Leanplum App.

apiVersion
string
required

The version of the Leanplum API to use. The current version is 1.0.6.

data
array of objects
required

A JSON array-encoded string representing each file's metadata. Used when uploading multiple files at once.

file{k}
binary
required

Supply if data is also supplied. The file data to be uploaded for file "k", where "k" is based on the order of the metadata in data[] (0-based). The first metadata item in data[] will be matched with file0, the second with file1, etc. There should be one file uploaded per entry in data.

filename
string

Supply if and only if data is not supplied. The filename of the file being uploaded relative to the application.

file
binary

Supply if and only if data is not supplied. The file data to be uploaded.

size
integer

Supply if and only if data is not supplied. The size of the file in bytes.

hash
string

Supply if and only if data is not supplied. The MD5 hash representing the file. Used to detect changes to files in the SDK in Development Mode.

Response

The default response for most API actions.

response[].successboolean

Whether the request was received. Verify that the response has neither warning or error objects to confirm the action was taken. See here for more.

response[].warning.messagestring

The warning message for the API action, if any.

response[].error.messagestring

The error message for the API action, if any.

Suggest Edits

Export Data

 
Suggest Edits

addPostback

Adds a postback rule to be triggered on incoming data. The maximum number of postbacks allowed is three per app. This method requires your data export API clientKey.
Note — We've updated our postbacks feature! See here for details on what's new.

 
posthttps://www.leanplum.com/api?action=addPostback

Body Params

appId
string
required

The application ID. To find yours, select your app in the navigation column, and click Manage Apps. Then click Keys & Settings.

clientKey
string
required

The Data Export key for your Leanplum App.

apiVersion
string
required

The version of the Leanplum API to use. The current version is 1.0.6.

type
string
required

The type of postback to add. The only value allowed is messageEvents, which will be triggered on message events for push notifications, in-app messages, and emails. See below for a list of all the message events that trigger postbacks.

channels
array

The messaging channels that will trigger postbacks — possible values include Push Notification, Email, and In-app Message. For example, this ...&channels=[Push Notification, In-app Message]... would activate postbacks for push notification and in-app message events. If no channels are set, all three channels will trigger postbacks by default.

See below for a list of all the events that will trigger postbacks (by channel).

  • Push Notification — Sent, Open, Held Back
  • Email — Sent, Deferred, Delivered, Bounce, Open, Click, Marked as spam, Unsubscribe, Held Back
  • In-app Message (events by template):
    • All templates — View, held back.
    • Center Popup, Confirm, Interstitial — Accept
    • Rich interstitial — Select Button 1, Select Button 2
    • Satisfaction Survey — Submit
    • Banner — Select
      Note that you cannot specify which specific events trigger postbacks, however, you can ignore certain events on your end if you prefer.
postbackUrl
string
required

The URL template to post after the trigger occurs. The template uses the same format as templated values on the dashboard. Possible values (See below for an example URL template with all possible values).

  • User ID — The user ID that triggered the postback.
  • Device ID — The device ID that triggered the postback.
  • Trigger time — The time in milliseconds at which the postback was triggered. The time can be a time in the past if the triggering event occurred in the past.
  • Message ID — The message ID that triggered the postback.
  • Message event — The message event that triggered the postback (e.g. Send, Open).
  • channel — The channel of the message (push, email, or in-app message).
  • template_name — The template name of the in-app message. Returns an empty string for non-in-app messages.
  • parameters — All the parameters associated with the event when it is triggered. For example, an email’s Click event will include the URL clicked and the index of the URL. parameters are in JSON format, and all parameter values are URL encoded.

Response

A successful response will return the ID of the new postback.

response[].successboolean

Whether the request was received. Verify that the response has neither warning or error objects to confirm the action was taken. See here for more.

response[].postbackIdinteger

The ID of the newly created postback.

https://api.service.com/v1/example?message_id={{Message ID}}&event={{Message event}}&device_id={{Device ID}}&user_id={{User ID}}&time={{Trigger time}}&channel={{Message channel}}&template_name={{Template name}}&parameters={{Parameters}}
Suggest Edits

listPostbacks

List current postback rules. This method requires your data export API clientKey.

 
gethttps://www.leanplum.com/api?action=listPostbacks

Query Params

appId
string
required

The application ID. To find yours, select your app in the navigation column, and click Manage Apps. Then click Keys & Settings.

clientKey
string
required

The Data Export key for your Leanplum App.

apiVersion
string
required

The version of the Leanplum API to use. The current version is 1.0.6.

Response

A successful response will return a list of postbacks.

responsearray
response[].successboolean

Whether the request was received. Verify that the response has neither warning or error objects to confirm the action was taken. See here for more.

response[].postbacksarray

The list of active postbacks for the given app.

response[].postbacks[]object
response[].postbacks[].postbackIdinteger

The ID of the postback.

response[].postbacks[].typestring

The type of the postback.

response[].postbacks[].postbackUrlstring

The URL template of the postback.

Suggest Edits

deletePostback

Deletes a particular postback. This method requires your data export API clientKey.

 
posthttps://www.leanplum.com/api?action=deletePostback

Body Params

appId
string
required

The application ID. To find yours, select your app in the navigation column, and click Manage Apps. Then click Keys & Settings.

clientKey
string
required

The Data Export key for your Leanplum App.

apiVersion
string
required

The version of the Leanplum API to use. The current version is 1.0.6.

postbackId
integer
required

The ID of the postback to delete.

Response

The default response for most API actions.

response[].successboolean

Whether the request was received. Verify that the response has neither warning or error objects to confirm the action was taken. See here for more.

response[].warning.messagestring

The warning message for the API action, if any.

response[].error.messagestring

The error message for the API action, if any.

Suggest Edits

exportData

Exports raw data to downloadable files. Data is split into roughly 256 MB files, and is not necessarily ordered. Exports can be made in JSON or CSV format. For JSON format, each file contains 1 line per session, with each session JSON-encoded. For CSV format, data is split into separate files for sessions, states, events, event parameters, and user attributes. Export files are automatically deleted 24 hours after export occurs. Data becomes available to export every 2 hours, and only for complete sessions. You cannot export data that has become available more than 60 days ago. You may only export data 24 times per day. Exports with invalid arguments do not count towards this limit.

This method requires your data export API clientKey.

Use getExportResults with the returned jobId to get the results.

 
gethttps://www.leanplum.com/api?action=exportData

Query Params

appId
string
required

The application ID. To find yours, select your app in the navigation column, and click Manage Apps. Then click Keys & Settings.

clientKey
string
required

The Data Export key for your Leanplum App.

apiVersion
string
required

The version of the Leanplum API to use. The current version is 1.0.6.

startDate
string
required

First date in range to include in PDT/PST (format: YYYYmmdd). Example: 20140223.

exportFormat
string

The format to export data. Can be either json or csv. Default: json.

endDate
string

Last date in range to include in PDT/PST (format: YYYYmmdd). Defaults to startDate if not provided. Example: 20140223.

startTime
number

First time (when data became available) to include (seconds since midnight UTC on January 1, 1970). If not provided, accepts all times before endTime, or all times if endTime is also not provided. The main use is to set this to the last time you exported data to only get the new data since your last export.

endTime
number

Last time (when data became available) to include (seconds since midnight UTC on January 1, 1970). If not provided, accepts all times after startTime, or all times if startTime is also not provided.

callbackUrl
string

URL to POST a response to when the export completes. The response is the response format of getExportResults.

s3BucketName
string

The name of an AWS S3 bucket to copy exported files to.

s3AccessId
string

The AWS Access ID used to authenticate to S3. Required if s3BucketName is set.

s3AccessKey
string

The AWS Secret Access Key used to authenticate to S3. Required if s3BucketName is set.

s3ObjectPrefix
string

An optional prefix of files to write to S3. Example: dirname/ to write files to a directory within the S3 bucket.

compressData
boolean

An option to compress the data. Only works when uploading to S3. If set to true, the files will be compressed using gzip before being uploaded.

Response

A successful response will return the ID of the export job.

response[].successboolean

Whether the request was received. Verify that the response has neither warning or error objects to confirm the action was taken. See here for more.

response[].jobIdstring

The job ID of the pending export job, if data matching the supplied arguments is available. Use getExportResults with this jobId to get the results.

See here for more on understanding the events and metrics in your data export.

Suggest Edits

exportData schema (JSON)

 

Our exportData API method by default a file where each row is a single JSON object representing a single user session.

Schema

Each row in the export will have a JSON object with the following attributes. Attributes marked as optional below may not be returned (if the value is null).

attribute
type
description

isSession

boolean

whether this data is counted towards a session

appVersion

string
optional

the version of the app used on this device (e.g. 2.0.1)

country

string
optional

the country the user is in, specified by ISO 2-letter code (e.g. US for United States)

timezone

string
optional

the timezone abbreviation for the user. See list of timezone abbreviations

region

string
optional

the region (state) the user is in (e.g. ca for California)

city

string
optional

user's current city

locale

string
optional

user's locale, includes language and country set on the device (e.g. "en_US")

deviceModel

string
optional

the model name of the device (e.g. iPad)

priorEvents

int64

the number of prior events

systemName

string
optional

the name of the OS the current device is running (e.g. iOS)

systemVersion

string
optional

the version number of the OS the current device is running (e.g. 6.0)

priorStates

int64

number of prior states

time

double

the time the session started in seconds (UTC)

deviceId

string
optional

the device ID for the user's device

firstRun

double

the time of the user's first session

sourcePublisherId

string
optional

ID of the publisher used to refer the user (e.g. 1001)

sourcePublisher

string
optional

name of the publisher used to refer the user (e.g. Big Fish Games)

sourceSubPublisher

string
optional

name of the developer used to refer the user (e.g. GameDeveloper1)

sourceSite

string
optional

name of the app or website used to refer the user (e.g. MyLittleApp)

sourceCampaign

string
optional

name of the campaign used to refer the user (e.g. US CPI)

sourceAdGroup

string
optional

name of the ad group used to refer the user (e.g. banners)

sourceAd

string
optional

name of the ad used to refer the user (e.g. blue1)

userId

string

the user ID defined by your app. See more on user IDs in iOS and Android.

client

string
optional

the type of client (e.g. js)

browserName

string
optional

the name of the browser the current device is running (e.g. Chrome)

browserVersion

string
optional

the version number of the browser the current device is running (e.g. 17.0)

sdkVersion

string

the SDK version running on the user's device

sessionId

string

the unique session ID for the current session

lat

double
optional

latitude of user's current location

lon

double
optional

the longitude of the user's current location

duration

double
optional

the duration of the current session in seconds (e.g. 19.254)

priorTimeSpentInApp

double

the total time of previous session(s) in seconds

timezoneOffsetSeconds

int32
optional

the offset of user's timezone in seconds

priorSessions

int64

the number of prior sessions

userBucket

int32

the user bucket assigned to this user (0-999)

isDeveloper

boolean
optional

whether the user is a developer and not a user

experiments

array

see experiments

states

array

see states

userAttributes

object

an object with key/value pairs based on the attributes you define.

Experiments array

Each object within the experiments array follows this schema:

attribute
type
description

id

int64

the ID of the A/B test the user is enrolled in

variantId

int64

the ID of the variant the user is placed within the test

impressed

boolean
optional

whether the user has seen the test after being assigned to it.

States array

Each object within the states array follows this schema:

attribute
type
description

stateId

integer

the ID for the state

info

string
optional

any info attached to the state

time

double
optional

the time in seconds (UTC) the user reached the state

duration

double
optional

the duration of the state in seconds (UTC)

name

string
optional

the name of the state

timeUntilFirstForUser

double
optional

the time the user spent in the app (in seconds) before reaching the state for the first time. If this is not the first occurrence, this will be null.

parameters

object

key/value pairs for any parameters you passed (in your code) with the state

events

array

an array of events triggered while user was in this state

events[].eventId

int64

the ID for the event

events[].value

double

the value passed to the event (within your code)

events[].info

string
optional

any info attached to the event.

events[].time

double

the time in seconds (UTC) the event occurred

events[].name

string

the name of the event (defined in your code)

events[].timeUntiFirstForUser

double
optional

the time the user spent in the app (in seconds) before triggering the event for the first time. If this is not the first occurrence, this will be null.

events[].parameters

object

key/value pairs for any parameters you passed (in your code) with the event

Example

The following is a single line from an export.

{
  "country": "US",
  "firstRun": 1499847141.448,
  "priorStates": 0,
  "city": "toledo",
  "experiments": [
    {
      "id": 4848982474358784,
      "variantId": 5318562523119616
    }
  ],
  "lon": "83.5552",
  "locale": "en_US",
  "isSession": false,
  "deviceId": "aUsersDeviceId",
  "states": [
      {
      "stateId": -8299958977733658706,
      "events": [
        {
          "eventId": 6467624121712405504,
          "timeUntilFirstForUser": 7191.943,
          "name": "addToCart",
          "time": 1506574496.416,
          "value": 0.0,
          "parameters": {
            "productId": "10248"
        }
      ]
    }
  ],
  "duration": 0.0,
  "systemName": "Windows",
  "browserVersion": "61",
  "client": "js",
  "browserName": "Chrome",
  "lat": "41.66",
  "priorSessions": 166,
  "userAttributes": {},
  "priorEvents": 4652,
  "sessionId": "5116700603679946752",
  "userId": "hubert.farnsworth@planetexpress.net",
  "timezoneOffsetSeconds": 0,
  "priorTimeSpentInApp": 316959.844,
  "deviceModel": "Web Browser",
  "sdkVersion": "1.1.7",
  "time": 1506575007.376,
  "region": "oh",
  "userBucket": 133
}

Note: An actual export will have multiple lines of these JSON-formatted objects, separated by a new line (not a comma). See the example below, but note that I added the ellipses to represent attributes removed. These would never appear in an actual export.

{"country":"SG","firstRun":1.488267623088E9, ... "userBucket":725}
{"country":"ID","firstRun":1.499847141448E9, ... "userBucket":540}
{"country":"US","firstRun":1.984714144849E9, ... "userBucket":430}
Suggest Edits

exportData schema (csv, S3 bucket)

 

Our