Getting started with SDKs


Countly provides various functionality in different SDKs targeted for mobile, web, desktop, server to server use cases. For a feature comparison in all SDKs, please check this table.

There are common concepts in all Countly SDKs and this document is intended to be a universal getting started guide without getting into the implementation details of individual SDKs. In order to get more information on platform specific implementation, please refer to the documentation of your SDK of choice.

User/device identification

By default, Countly generates an anonymous identifier to uniquely identify a device or browser. Total users metric for any period is based on unique number of device ids Countly Server receives requests from. Similarly, users list in User Profiles section is a list of anonymous devices Countly Server is receiving data from. All data originating from a single device, including sessions, events, views and crashes, are grouped under these individual profiles since all the data is tagged with the originating device id.

Most Countly SDKs including, iOS, Android, React Native, FlutterWeb offer a mechanism to change/update this default device id for cases where you already have a better identifier such as an email address or account id or you get this information at some point in user journey such as after user logs into your application. For an in depth analysis of different device/user identification strategies please check out this post.

Deciding on custom user properties

User properties play an important role not only in reporting but also in various other cases such as personalizing push notifications and creating conditional remote configuration variables.

Most Countly SDKs send some user properties together with the session request  which is triggered automatically when the app is launched, user lands on a website, or manually in some cases such as server to server SDK usage. These properties, which we call default user properties, are metadata including but not limited to app version, device, platform, platform version. 

Furthermore, there are some reserved user properties that you can choose to set, including name, email, organization, gender and age if you choose to store PII (personally identifiable information) in Countly.

Custom user properties are similar in logic to default and reserved user properties, in the sense that this information is stored in user profile level. All the data (sessions, events, views, crashes etc.) originating from a user will get tagged with a historical snapshot of default, reserved and custom user properties and will be available to be used in reporting and features such as Cohorts, Funnels, Drill, Retention and Formulas.

Custom user properties consist of key value pairs, where value can be a string, number, boolean, or an array. There are various modifiers available in the SDKs such as set, set once, push unique, increment, multiply in order to update these as you need. For example, you can store account levels of your users in an accountType custom user property that can take values Basic or Premium to later on filter & segment all reports based on the account type of your customers.


An "event" in Countly generally represents one of the following:

  • An action of the user such as an interaction with a single UI element, or set of elements
  • An important milestone the user reaches after completing other actions, such as completing an application or on-boarding process 
  • A transaction that takes place after one or more actions of the user, such as a backend API returning a result

It is important to note that events aren't designed to only track simple user interactions such as "user clicked this button". The way you define events in your app determines the depth of insights you can get from Countly. Tracking everything you possibly can or tracking very little are equally bad. An ideal strategy is collecting the needs of various departments in your organization that'll take advantage of Countly. As a common example;

  • Product team will want to check feature usage, they'll need multiple events that show how users interact with various application features
  • Customer experience & success team will want to understand paths users go through (such as during on-boarding) and get stuck in, and will need customized events as milestone indicators
  • Engineering team will want to get transactions & statutes that are created after users' interaction with the UI layer thus they'll need events or event segments that they can take advantage of
  • CXOs and managers will want to see higher level metrics or KPIs, thus this higher level data should exist either as dedicated events or individual ones to be used while constructing complex metrics using Formulas

In its most complex form (there can of course be additional segments), an event's JSON representation looks like below. Only mandatory fields are key and count which are set when you call the recordEvent function in any given SDK. Optional sum property is useful when you would like to store an extra numerical value for an event, in the below example we used it to store kilometers for a journey. Duration property represented as dur can be explicitly set, or you can take advantage of the timed events concept available in most SDKs.

"key": "Journey",
"count": 1,
"sum": 100,
"dur": 3600,
"segmentation": {
"Route Type": "Fastest"

Now let's dive into event segments and strategies you can follow.

Deciding on event segments

Segments are properties that add further detail and meaning to an event. Segments are important since most of the time you aren't only interested in how many times some general action happened but also will have the need to dig deeper, filter certain cases or group occurrences by different nuances of the action.

From our event sample in the above section, thanks to the Route Type event segment, you can not only see overall journeys taking place, but also see how many of the journeys were planned with a fastest, shortest or eco route types offered in the app. Furthermore, in plugins like Cohorts, Funnels, Drill and Formulas these event segments will be available for use cases such as;

  • Filter events where Route Type = Eco using Drill
  • Construct 3 different funnels where final step is the Journey event in all but filtered to be Route Type = Eco, Route Type = Fastest and Route Type = Shortest
  • Create a behavioral cohort of users who did have a Journey with Route Type = Eco at least 2 times in the last 30 days (these are our eco friendly personas which we can target using remote config and automated push notifications)
  • Construct 2 formulas in which you calculate average kilometers driven per journey for Route Type = Shortest and Route Type = Fastest

As you can tell from the above reporting examples, event segment selection is an important part of your success with reporting & visualization in Countly.

Acquiring your application key and server url

Acquiring the application key

Also called "appKey" as shorthand. The application key is used to identify for which application this information is tracked. You receive this value by creating a new application in your Countly dashboard and accessing it in its application management screen.

Note: Ensure you are using the App Key (found under Management -> Applications) and not the API Key. Entering the API Key will not work.

Acquiring the server URL

If you are using Countly Enterprise Edition trial servers, use, or It is basically the domain from which you are accessing your trial dashboard.

If you use both Community Edition and Enterprise Edition, use your own domain name or IP address, such as or https://IP (if SSL has been set up).

Handling login/logout in your app

For a lot of apps, there is a login option. This allows you to confirm the identity of your users by cross-referencing them with your own systems. That also adds two complications. First, multiple users can use the same app on the same device. The generated data would need to be assigned to the relevant user, therefore the device ID needs to be changed. Second, the same user can log in to multiple devices. Therefore you need to use the same device ID on all of that user's devices. To achieve that you would have an internal ID of your own system or a derivative value of it that you can reliably generate.

The first time you initialize a Countly SDK, you would allow the SDK to generate the device ID. When the user logs in to your app, you would change the device ID to the new ID that you generate. If this is the first time the user logs in, you would change the device ID with merging. On any other follow-up logins, you would change the device ID without merging. This way you can assign the events generated by the user before the first login to the user that logs in.

When a user logs out, you have 2 options. First, you would not change the device ID. This way you would also assign any follow-up events to the user that was last signed in, and those events would be sent as they happen. Second, if the SDK supports temporary ID mode, you can enter that when logout happens. This way you would assign any follow-up events to the user that would sign in next. The downside to the temporary ID approach is that no events would be sent while the user is not logged in. Both of these approaches not only solve a server-side performance issue but also eliminates the issue with inflated user counts. We recommend you choose the first logout option.

A key SDK feature that allows you to do this is the ability to see the device ID type. The 2 important things that you want to differentiate is if the ID is generated by the SDK or if it's a custom ID provided by you. If the ID is generated by the SDK then you can assume that the user has not logged in before and when changing the device ID, you need to do that with merging. If the device ID is a custom one then you can assume that you have already changed the ID before and need to perform the current change without merging.

Here are a few sample login implementations of this flow:


public void Login() {
String newId = "SomeValue";
if (Countly.sharedInstance().getDeviceIDType() == DeviceId.Type.DEVELOPER_SUPPLIED) {
// an ID was provided by the host app previously
// we can assume that a device ID change with merge was executed previously
// now we change it without merging
Countly.sharedInstance().changeDeviceIdWithoutMerge(DeviceId.Type.DEVELOPER_SUPPLIED, newId);
} else {
// SDK generated ID
// we change device ID with merge so that data is combined


public static void login()
       DeviceId.Type type = Countly.sharedInstance().getDeviceIDType();

Using Countly SDK's with iOS and Android widgets and watches

With mobile devices, there are 3 different modalities that a user can interact with: phone app, phone widget, and watch app. When designing a product that spans all three worlds, the goal is usually to track the users lifecycle across all of them.

To perform this cross-modality tracking, care must be given that tracking is performed with the same device ID across all of them. If the device ID, to which the event or session is attributed, would not be the same across all devices then the same user would be counted as a separate person on one of the devices.

This also means that if the users device ID would change, this change needs to be synchronized across all modalities/apps.

This can be achieved in 2 general approaches:

  1. Performing data recording at each location separately - each modality integrates, configures, and initializes the Countly SDK separately. Device ID synchronization needs to be performed manually across all modalities. Alternatively, every modality needs a way to create the same device ID without cross-synchronization.
  2. Performing data recording at a central location and proxying data recording from each non-app modality - eliminates the need for synchronization as there is only one instance of the SDK initialized and configured. Device ID changes are immediately taken into account when they happen. Since cross-device recording is centralized, views and sessions need to be recorded manually. Another potential issue is that sometimes the main app might be out of reach for proxy recording.
Was this article helpful?
0 out of 0 found this helpful

Looking for help?