Users and Devices

User IDs

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, however, 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(this, "user1234");
[Leanplum startWithUserId:@"user1234"];
Leanplum.start(withUserId: "user1234")

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

You can also set the User ID after start. See more below.


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, but then set the user ID later on with setUserId when the user logs in.

[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 this 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.


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.

Device IDs

The device ID uniquely identifies each device and is determined automatically by the SDK. 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.

Note: The deviceId is set when Leanplum.start runs for the first time on a 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 & 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.

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.


  • 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.


  • Gender
  • Age
  • Number of friends
  • User interests


  • Up to 200 attributes may 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.
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.

// Clear the attributes.
attributes.put("gender", null);
attributes.put("age", null);

User Location

By default, Leanplum uses IP-based geolocation for all users. In addition, the Leanplum SDK also captures GPS/Cell-based geolocation from the user's device if 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 2 decimal places, blurring the accuracy to about 1 kilometer.

Note: If you setup 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.

In Android, our SDK automatically tracks GPS/Cell-based location if available to your app.

However, if you plan to use location-based messaging, you'll need to make some changes to your AndroidManifest. See messaging for more info.

Geolocation is available on Android SDK 1.3+.

Disabling location collection

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


Manually set user location

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

locationandroid.location.Locationthe location object representing the user's current location
typeLeanplumLocationAccuracyTypethe type of geolocation. Either CELL (default) or GPS (more precise)
setDeviceLocation(location, type);

Setting device location is available on Android SDK 2.0.0+.