cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Segmentation and Levels (Date-Range Reports) in API Reporting

Segmentation and Levels (Date-Range Reports) in API Reporting

Report data may be segmented in up to 3 levels. Each level represents a property. Using multi-level segmentation, you can create hierarchical reports that are used to drill down based on the property values. For example, you can create a report that splits all the users based on which edition they are using. Then, you can split the user counts for each edition based on product version on level 2. Finally, the user counts for each product version can be split up by product build on level 3.

Such multi-level reporting is available only when not splitting by date. Splitting by date is meant to be used in timeline reports, and creating such a hierarchy for each date would result in a huge data set which would only have limited use. When date splitting is used, segmentation with 1 level is still allowed, however. This allows creating timeline reports where each line represents a property value, such as comparing usage trend for version 1 vs version 2.

Segmentation is optional. In order not to split data by any property, you may either not include a levels property in the request object, or else leave the levels object empty. The following examples show the difference between not requesting any segmentation, requesting a single level, and requesting 2 levels:

Number of Levels Description
0 Levels
  • New Users: 30
  • Active Users: 100
  • Lost Users: 20
 
1 Level

PRODUCT VERSIONS

Version 1:

  • New Users: 10
  • Active Users: 30
  • Lost Users: 8

Version 2:

  • New Users: 20
  • Active Users: 70
  • Lost Users: 12
 
2 Levels

PRODUCT VERSIONS

Version 1:

  • New Users: 10
  • Active Users: 30
  • Lost Users: 8

PRODUCT EDITIONS

Premium:

  • New Users: 4
  • Active Users: 13
  • Lost Users: 1

Standard:

  • New Users: 6
  • Active Users: 17
  • Lost Users: 7
 

PRODUCT VERSIONS

Version 2:

  • New Users: 20
  • Active Users: 70
  • Lost Users: 12

PRODUCT EDITIONS

Premium:

  • New Users: 5
  • Active Users: 40
  • Lost Users: 4

Standard:

  • New Users: 15
  • Active Users: 30
  • Lost Users: 8

In the above examples, the first example, 0 Levels, is showing a case where no segmentation is being applied.

The second example, 1 Level, is showing a response where a single level of segmentation has been requested. In this case, segmentation is being done based on product versions. For each product version, one can see the number of new, active, and lost users within the specified date range. Segmenting by 1 level is also possible in reports that use date splitting, so, in a similar example, one would be able to see how many users were using a specific version on each day within the date range.

The third example, 2 Levels, shows 2 levels of segmentation. In this example, one can see how many new, active, and lost users were using each version, and then, that data is further split by product edition. A further level is also allowed, so, for example one may choose to segment each product edition by product language.

The properties that are available for segmentation are the same ones that are used for Global Filters in API Reporting. There are 4 properties that require special formatting. These are described below.

Segment levels are to be defined in a property inside the main JSON object named “levels”. This property should contain a JSON object which contains the following members:

  • property (string)—The name of the property by which to segment. Note that in case of os, geography, licenseStatus and gpu, a special format is used.
  • segments (array)—An array containing a number of JSON objects. The format of these object is described in the Level Segments Format section below.
  • sort (string)—Optional property to specify how the segments in this level are to be sorted. Possible values are alpha, new, active, and lost. alpha refers to alphabetical sorting which is based on the segment label. The other 3 are based on the client statuses. Note that if sorting by new, active, or lost users, that particular client status must be included in the clientStatus array. If this property is not included, the data is sorted alphabetically by default.
  • sortDirection (string)—Optional property to specify whether to sort in ascending or descending order. Possible values are asc and desc. If not specified, data is sorted in ascending order by default.

For more information, see:

Level Segments Format

Segments are defined as JSON objects. A single JSON object may create a single item on a table (or a single series on a timeline chart), or it may create a number of items/series if splitting is enabled. Each object should contain the following:

  • type (string)—The data type of the value. Can be string, stringArray, regex, number or numberRange based on whether the property is string-based or numeric. For more information, see Global Filters in API Reporting.
  • value (string/array/number)—An exact string, an array of strings, a regular expression or a numeric value. This property should not be used if type is numberRange. Format is based on whether the property is string-based or numeric. For more information, see Global Filters in API Reporting
  • min (number)—Used only if the type is numberRange. Contains the minimum numeric value to include in this segment. May be combined with max.
  • max (number)—Used only if the type is numberRange. Contains the maximum numeric value to include in this segment. May be combined with min.
  • split (boolean)—Used only if the type is stringArray or regex. This specifies whether to split the returned data based on each different value matched by the regular expression or array (true), or to join all the clients that match the value as 1 table value or series (false).
  • segmentLabel (string)—Used only if split is false or if type is numberRange. This is required to give a name to a series when not splitting by value. It is important that the name given is unique.
  • limit (integer)—Optional property to set the limit on the maximum number of table values or series that should be produced by this set of values. To be used only if split is true.

String-Based Segmentation Properties

The following properties are stored as strings:

machineId
clientId
prodVersion
prodEdition
prodBuild
prodLanguage
licenseType
formFactor *
osLanguage
osWordLength *
cpuType *
javaVersion *
javaVendor *
javaRuntime *
javaGraphics *
javaVmVersion *
javaVmName *
vm *
C01 .. C20 (Custom properties)
licenseKey *

NOTE: licenseKey requires a special user permission to be used for segmentation.

NOTE: Properties marked with an asterisk (*) are based on the current (latest known) values.

The type field when using one of the above properties needs to be string, stringArray or regex. A value field is always required. The contents of this field should be according to the specified type.

  • If string is specified, then the value field must contain a single string that needs to be matched precisely with the stored data.
  • If stringArray is specified, then the value field must contain an array of strings where one of which needs to match precisely with the stored data.
  • If specifying a regex, the value field should contain a string which is treated as a regular expression and the stored data will be matched against it using regular expression rules.

Example Using 1-Level Segmentation by string, stringArray, and regex Values

{
    "level1": {
        "property": "prodVersion",
        "segments": [
            {
                "type": "string",
                "value": "1.0"
            },
            {
                "type": "stringArray",
                "value": ["2.0", "2.1", "3.1"],
                "split": false,
                "segmentLabel": "Versions 2 and 3"
            },
            {
                "type": "regex",
                "value": "^4\..*",
                "split": false,
                "segmentLabel": "All version 4"
            },
            {
                "type": "regex",
                "value": "^5\..*",
                "split": true
            }
        ]
    }
}

In the above example, we are requesting a report with multiple segments. The first segment contains installations running version 1.0. Notice how this does not require a “split” property since there is only 1 value and therefore no further splitting is possible. The second segment contains versions 2.0, 2.1 and 3.1. In this case, the “split” property is required, and since we are requesting the API to combine these 3 versions, we must provide a “segmentLabel” value so that the returned data can be identified. The third segment is similar, although in this case the request is built using a regular expression. In this case, all versions starting with “4.” are to be included into one combined segment.

The last segment is different from the rest because we are requesting the API to split the data (split is set to true). Therefore, this can produce much more than 1 segment. In this case, we could see segments such as “5.1”, “5.2”, etc. Notice how since we are splitting, we should not provide a segmentLabel value since the labels are built using the different values that are found in the data.

Numeric Segmentation Properties

The following properties are stored as numeric values:

cpuCores *
displayCount *
ram *
resolutionWidth *
resolutionHeight *
lifetimeRuntimeMinutes *
lifetimeSessionCount *
screenPpi *
javaVmRam *

NOTE: Properties marked with an asterisk (*) are based on the current (latest known) values.

The type field in the above properties needs to be number or numberRange. If number is specified, then a value field must also be present. The value field should contain a number, which may contain a decimal point if required. If numberRange is specified, then the value field should NOT be used. Instead, the properties min and max are to be used. These refer to the minimum and maximum number to be included in the report. If only one limit needs to be set, the other property is to be left out. Therefore, if you want to include installations with up to 2 display devices, you would not specify a min value, but instead specify only a max and set it as 2.

Example Using 1-Level Segmentation by number, and numberRange Values

{
    "level1": {
        "property": "cpuCores",
        "segments": [
            {
                "type": "number",
                "value": 1,
            },
            {
                "type": "numberRange",
                "min": 2,
                "max": 4,
                "segmentLabel": "2 - 4"
            },
            {
                "type": "numberRange",
                "min": 5,
                "segmentLabel": "5 +"
            }
        ]
    }
}

In the above example, we are requesting a report with 3 segments. The first segment contains only installations running on 1 CPU core, the second segments contains installations running on 2, 3, or 4 cores (range 2 - 4), while the last segment contains all installations which are running on a machine with 5 or more CPU cores. Note how when the type was numberRange, we had do specify a segmentLabel which is a free string that will be used by the user to identify what is being included in that specific segment.

Boolean Segmentation Properties

The following properties are stored ad boolean values:

touchScreen

The type field needs to be boolean, and the value must be true or false. A segmentLabel field is also required

Example Using 1-Level Segmentation by Boolean Value

{
    "level1": {
        "property": "touchScreen",
        "segments": [
            {
                "type": "boolean",
                "value": true,
                "segmentLabel": "Yes"
            },
            {
                "type": "boolean",
                "value": false,
                "segmentLabel": "No"
            },
            {
                "includeNull": true,
                "segmentLabel": "Unknown"
            }
        ]
    }
}

In the above example, we are requesting a report with 3 segments. The first segment contains installations on which a touch screen was detected, the second one where no touch screen has been detected, while the last one is where we could not detect whether a touch screen is present due to the client using an old SDK which did not have touch screen detection support.

Special Segmentation Properties

Some properties need to be represented in a special format due to their unique requirements. These special properties are described below.

Special Segmentation Format: licenseStatus

The licenseStatus value is made up of 4 sub-values: activated, blocked, expired and allowed. These are presented as boolean values. Any number of segments can be defined, and each segment can contain any subset of the 4 sub-values. These values are ANDed together. A segmentLabel value is required.

In the following example, 2 segments are specified - the first one showing blocked AND not expired and the second one showing allowed AND activated:

[
    {
        "segmentLabel": "BL and not EXP",
        "blocked": true,
        "expired": false
    },
    {
        "segmentLabel": "WL and ACT",
        "allowed": true,
        "expired": true
    }
]

Special Segmentation Format: os

The os value is made up of 3 granularity levels - platform, version, and edition. A particular level needs to be selected, and this is to be included in the property name such as os.version or os.edition. Different granularity levels can be requested for different segmentation levels. Therefore, it is possible to generate a 3-level hierarchical tree in which level 1 would show the OS platform, level 2 would show the version, and level 3 would show the full name including the OS edition or sub-version. For a description of the differences between the 3 granularity levels, refer to Global Filters in API Reporting.

The following example shows the levels object requesting 3 granularity levels as described above:

{
    "level1": {
        "property": "os.platform",
        "segments": [
            {
                "type": "regex",
                "value": ".*",
                "split": true
            }
        ]
    },
    "level2": {
        "property": "os.version",
        "segments": [
            {
                "type": "regex",
                "value": ".*",
                "split": true
            }
        ]
    },
    "level3": {
        "property": "os.edition",
        "segments": [
            {
                "type": "regex",
                "value": ".*",
                "split": true
            }
        ]
    }
}

In the above example, no filtering is being done, and instead, a regular expression to include everything is set as the value. This will result in all OS platforms, versions, and editions to be included in the hierarchy.

Special Segmentation Format: geography

The geography value is made up of 3 granularity levels - continent, country, and usState. These granularity levels are explained in Global Filters in API Reporting. A particular level needs to be selected, and this is to be included in the property name such as geography.continent or geography.country. Different granularity levels can be requested for different segmentation levels. Therefore, it is possible to generate a 3-level hierarchical tree in which level 1 would show the continent, level 2 would show the country, and level 3 would show the US state (for United States only).

The following example shows the levels object requesting 3 granularity levels as described above:

{
    "level1": {
        "property": "geography.continent",
        "segments": [
            {
                "type": "regex",
                "value": ".*",
                "split": true
            }
        ]
    },
    "level2": {
        "property": "geography.country",
        "segments": [
            {
                "type": "regex",
                "value": ".*",
                "split": true
            }
        ]
    },
    "level3": {
        "property": "geography.usState",
        "segments": [
            {
                "type": "regex",
                "value": ".*",
                "split": true
            }
        ]
    }
}

In the above example, no filtering is being done, and instead, a regular expression to include everything is set as the value. This will result in all the continents, countries and US states (where applicable) to be included in the hierarchy.

Special Segmentation Format: gpu

The gpu value is made up of 2 granularity levels - vendor and model. These granularity levels are explained in Global Filters in API Reporting. A particular level needs to be selected, and this is to be included in the property name, namely gpu.vendor or gpu.model. Different granularity levels can be requested for different segmentation levels. Therefore, it is possible to generate a 2-level hierarchical tree in which level 1 would show the vendor, and level 2 would show the model number.

The following example shows the levels object requesting 2 granularity levels as described above:

{
    "level1": {
        "property": "gpu.vendor",
        "segments": [
            {
                "type": "regex",
                "value": ".*",
                "split": true
            }
        ]
    },
    "level2": {
        "property": "gpu.model",
        "segments": [
            {
                "type": "regex",
                "value": ".*",
                "split": true
            }
        ]
    }
}

In the above example, no filtering is being done, and instead, a regular expression to include everything is set as the value. This will result in all the GPU vendors and models to be included in the hierarchy.

Special Segmentation Format: optOut and backOff

Both backOff and optOut values are made up of 2 boolean sub-values: historical and current. Any number of segments can be defined, and each segment can contain any subset of the 2 sub-values. These values are ANDed together. A segmentLabel value is required.

In the following example, 2 segments are specified - the first one showing historical AND not current and the second one showing not historical (i.e. never opted-out):

[
    {
         "segmentLabel": "HISTORICAL and not CURRENT",
         "historical": true,
         "current": false
    },
    {
        "segmentLabel": "Never opted-out",
        "historical": false
    }
]

<NULL> Values in Segmentation and Levels (Date-Range Reports)

Null values in segmentation are to be requested in a similar way to <NULL> Values in Global Filters (Date-Range Reports). The same properties that support null in filtering also support null in segmentation.

By default, when segmenting, null values are not included within the segments, since only the values that have been specified in each segment are included. Null values don’t match any regular expression, so the only way to request null values to be included is to specify “includeNull” as true in a similar way to filtering. In segmentation, null values are returned as “<NULL>”. The API considers all cases where the data has never been set from the SDK, set as an empty string, or set as a string containing “<NULL>” to be the same.

The following example requests all values of prodBuild including null:

{
    "level1": {
        "property": "prodBuild",
        "segments": [
            {
                "type": "regex",
                "value": ".*",
                "includeNull": true
            }
        ]
    }
}

In the case of segmentation properties that use sub-properties (os, geography, and gpu), the includeNull value is to be included in the sub-property and applies to that specific sub-property only. In order to be able to include the includeNull property, instead of providing the value as a string or an array of strings, the value of the sub-property must be a JSON object that cointains a property named “value”, and another named “includeNull”. Each of these properties is optional, but at least one of them must be present. The same rules that apply for filtering these types of properties for null values also apply to segmentation.

In the following example, we are requesting segmentation by continent and are also requesting the number of clients where we could not detect the geographical location:

{
    "level1": {
        "property": "geography",
        "segments": [
            {
                "type": "regex",
                "continent": {
                                  "value": ".*",
                                  "includeNull": true
                             }
            }
        ]
    }
}
Was this article helpful? Yes No
No ratings
Version history
Last update:
‎Oct 02, 2023 10:59 AM
Updated by:
Contributors