How to access your data via API?

In Metricalp, you can always access your dashboard data via API. You can use it to build your own dashboard or to produce your own custom report workflows. To access your data via API, you will need two things. API Access Token and your tracker data-tid.

You can find your API Access Token in your Account Settings. Go to Account Settings and then API Tokens tab.

In this screen, you can view or copy your API Access Token. Also, you can replace it (for security reasons). But be careful, when you replace your API Access Token, your old API Access Token will be invalid and will not work. Always keep in safe your token.

The second thing is data-tid of your target tracker to access its data. You can find your tracker data-tid in the tracker settings page. Please check: Embed Share Tracker to detailed info about your data-tid.

Now you have your API Access Token and data-tid then you are ready to access your data via API. Let's deep dive it.

Data API

Firstly, to access dashboard data you should make POST requests to dashboard enpoint in below:

Endpoint
https://api.metricalp.com/dashboard

You have to include your API Access Token into Authorization header with Bearer prefix

JS
const headers = {Authorization: 'Bearer eyJ0b2tlbiI6ImxmYXFpaG16NTAyNTU5bmJtYno2YWtvNndrYzhuNWF4Iiwib2lkIjoxfQ=='}

Get Tracker

Lets start with a simple one. You can get your tracker's name, timezone, goals, funnels and other info with get tracker api request. You will find an example with JavaScript below but you can use any language you want. It is just a HTTP Post request with Authorization header and JSON body.

Request:

JavaScript

        fetch('https://api.metricalp.com/dashboard', {
          method: 'POST',
          headers: {
            'Content-Type': 'application/json',
            'Authorization': 'Bearer eyJ0b2tlbiI6ImdvNHY3b3VhMmw1b3ZwdWlubXlzNWh0eXlzNHVuem53Iiwib2lkIjo2fQ==',
          },
          body: JSON.stringify({
            reqRoute: 'get-tracker',
            trackerId: 'mam2',
          }),
        }).then(response => response.json()).then(data => {console.log(data)});

In header we provided our API access token and in body we provided:

- reqRoute:'get-tracker'

- trackerId: 'mam2' (which it is your tracket data-tid which we got it above)

If everything goes well, the success response will be like:

JSON
         {
          tracker_id: 2,
          owner_id: 6,
          tracker_name: 'Test Tracker',
          is_active: 1,
          timezone: 'UTC',
          create_date: '2024-01-22T13:56:27.568Z',
          update_date: '2024-01-22T13:56:27.568Z',
          allow_all_hosts: 1,
          allowed_hosts: '[]',
          access: 'private',
          access_key: '',
          deactive_reason: null,
          tracker_warning: null,
          goals: [
            {
              tracker_id: 2,
              goal_id: '6-2-ls3gep4h-kfm',
              goal_name: 'Click purchase button in US',
              goal_props: '[{"key":"event_type","value":"click_purchase","matchType":"exact","caseSensitive":true},{"key":"country","value":"United States","matchType":"exact","caseSensitive":false}]'
            },
            {
              tracker_id: 2,
              goal_id: '6-2-ls3gdxss-gfs',
              goal_name: 'Visit Purchase screen',
              goal_props: '[{"key":"event_type","value":"screen_view","matchType":"exact","caseSensitive":true},{"key":"path","value":"/purchase","matchType":"exact","caseSensitive":false}]'
            }
          ],
          funnels: [
            {
              tracker_id: 2,
              funnel_id: '6-2-ls3gf7qk-qvh',
              funnel_name: 'Purchase in US',
              goals_flow: '6-2-ls3gdxss-gfs>6-2-ls3gep4h-kfm'
            }
          ]
        }

We have got all basic info about our tracker also funels and goals. The funnel and goal ids will be important while doing query for them below. You may want to keep it for querying them.

Query

Now we can query our dashboard data. We will describe body structure for a request in query. But first, here the full TypeScript type of expected request body in query route:

TS

        
        export type FieldCondition = { value: string | boolean | number; eq: boolean };
        
        export type Conditions = {
          tracker_id: string;
          from_date: number;
          to_date?: number;
          browser?: FieldCondition;
          browser_detail?: FieldCondition;
          operating_system?: FieldCondition;
          device_type?: FieldCondition;
          country?: FieldCondition;
          city?: FieldCondition;
          event_type?: FieldCondition;
          hostname?: FieldCondition;
          os_detail?: FieldCondition;
          path?: FieldCondition;
          entered_from_path?: FieldCondition;
          exited_from_path?: FieldCondition;
          source?: FieldCondition;
          source_detail?: FieldCondition;
          utm_medium?: FieldCondition;
          utm_source?: FieldCondition;
          utm_campaign?: FieldCondition;
          utm_content?: FieldCondition;
          utm_term?: FieldCondition;
          custom_prop1?: FieldCondition;
          custom_prop2?: FieldCondition;
          custom_prop3?: FieldCondition;
          custom_prop4?: FieldCondition;
          custom_prop5?: FieldCondition;
          goal_id?: FieldCondition;
        };
        
        type RequestBody = {
            reqRoute: 'query';
            genericType: 'main' | 'main-chart' | 'non-pfph' | 'pfph' | 'funnel' | 'event-type' | 'realtime-summary';
            conditions: Conditions;
            funnel?: string;
            fields: string[];
            offset?: number;
            rangeType?: 'five-min' | 'hourly' | 'daily' | 'weekly' | 'monthly';
            trackerAccessKey?: string;
            mainActiveTab?:
              | 'eventUniqueCount'
              | 'totalSessions'
              | 'totalScreenViews'
              | 'viewsPerSession'
              | 'bounceRate'
              | 'eventTotalCount'
              | 'uniqueGoalConversion';
            extendedLimit?: boolean;
        }

No worries, we will explain these fields and their purposes in below.

- reqRoute

reqRoute is 'query' while querying dashboard data. It was get-tracker while getting tracker data above. So, as you realized, endpoint is always same but body.reqRoute changes for different request types. For querying data, it will always be 'query'.

- genericType

genericType is important specific concept in Metricalp. main and main-chart is clear because of names. When you get data for main metrics like unique visitors, total sessions, total screen views etc you need to set this main. If you want to get data in chart structure for specific metric, you need to set this main-chart. non-pfph and pfph are special terms in Metricalp. pfph basically means permanent per session. For example a visitor`s browser is Chrome and it can not be changed in a session. So it is pfph field. But the path field can be changed in a session flow because visitor can jump from a page to another. So it is non-pfph field. We are doing this separation to achieve big performance optimizations under the hood. Here you can find the list of all non-pfph and pfph fields:

Non-PFPH:

  • path
  • source
  • source_detail
  • hostname
  • utm_medium
  • utm_source
  • utm_campaign
  • utm_content
  • utm_term
  • custom_prop1
  • custom_prop2
  • custom_prop3
  • custom_prop4
  • custom_prop5

PFPH:

  • city
  • country
  • browser
  • browser_detail
  • operating_system
  • os_detail
  • device_type
  • user_language
  • user_timezone

Also if you want to get funnel data you should set this genericType to funnel. You can get event types by setting this to event-type and lastly, to get realtime data as summary you can set this to realtime-summary

- conditions

As you know you can set conditions (filters) in Dashboard. For example like to get visitors only in US and has browser Chrome. To set conditions in API, you need to set conditions field in request body. A condition can be based on equality (is) or non-equality (is not).

JS
const conditions = { "browser": { "eq": true, "value": "Chrome" }}

If you set eq true it means filter based on equality so it brings visitors with Chrome visitor. But if you set it false then it means, only bring visitors do *NOT* have Chrome browser.

Important note:

You must always include your tracker data-tid (as tracker_id), event_type, from date and to date info in the conditions. Otherwise query will not work. Keep in mind you should be the owner of the tracker or that tracker should be public to access its data.

Then here an example of a full Conditions object:

JS

        const conditions = {
          "browser": {
            "eq": true,
            "value": "Chrome"
          },
          "tracker_id": "mam1",
          "from_date": 1706734800000,
          "to_date": 1706795834711,
          "event_type": {
            "value": "screen_view",
            "eq": true
          }
        }

- funnel

You need to provide this value only while doing query for funnel (genericType = funnel).

It should be flow of goal ids in funnel. You had this data when you do a get-tracker request. You had all funnel data and their goals_flow. Use goals_flow data in here to get results for funnel. Example:

"funnel": "6-2-ls3gdxss-gfs>6-2-ls3gep4h-kfm"

You will see full request example at the end of this documentation.

- fields

In one request you can results for one or more fields. So you can provide fields list as array in request body.Important thing is you should have non-pfph or pfph fields in fields list based on your genericType. You can not mix them in single request. This is a double way (both client & server) performance optimization restrict.

"fields": ["country","city","user_language","browser"]

- offset

In a field query request, you will have 10 items per field (desc order based on unique count) (i.e top 10 browsers). But for a single field (like clicking show more button in dashboard) when you want to see more, you need to query based on a pagination logic. Offset will provide it. You can set offset to 0 for first query and then +20 for every other query to see page by page the results. You will see a full example at the end.

- rangeType

This is required when you do a genericType main-chart query. It determines chart's rangeType. You can set it to five-min, hourly, daily, weekly or monthly.

- trackerAccessKey

If your tracker's access setting is key, then people can access your dashboard data through API with key which you set in settings. They need to send this key in every request. You can set this key in trackerAccessKey field in request body. If your tracker's access setting is 'public' or 'private' or 'you are the owner of tracker and you provided public access token' then you do not need to set this field.

- mainActiveTab

When you make a query request for chart (genericType= main-chart), you need to specify which field you are making request. For example, you want to get chart data for unique visitors. Then you need to set this field to eventUniqueCount. Also, rangeType is required for chart requests as described above.

- extendedLimit

Defaultly every query returns 10 result per field. When you query a single field (for example clicking show more button in dashboard) you can set this true to have 20 results per field. Every page will have 20 items and you can use offset parameter to paginate.

Full Query Examples

Getting Main Metrics

Request:

JavaScript
       fetch('https://api.metricalp.com/dashboard', {
          method: 'POST',
          headers: {
            'Content-Type': 'application/json',
            'Authorization': 'Bearer eyJ0b2tlbiI6InA0ajF0bjA4eGxqcm1xODJzZm94d2l6eWwzY2c3b28yIiwib2lkIjoxfQ',
          },
          body: JSON.stringify({
              "reqRoute": "query",
              "trackerAccessKey": "",
              "genericType": "main",
              "fields": [],
              "conditions": {
                  "tracker_id": "mam1",
                  "from_date": 1706734800000,
                  "to_date": 1706811129699,
                  "event_type": {
                      "value": "screen_view",
                      "eq": true
                  }
              }
          }),
        }).then(response => response.json()).then(data => {console.log(data)});

Response:

JSON
       {
          bounceRate: 79.55,
          viewsPerSession: 1.72,
          eventUniqueCount: 1088,
          totalSessions: 1112,
          eventTotalCount: 1747,
          uniqueGoalConversion: 0,
          trackerStatus: 'active'
        }

Getting Main Chart

Request:

JavaScript
       fetch('https://api.metricalp.com/dashboard', {
          method: 'POST',
          headers: {
            'Content-Type': 'application/json',
            'Authorization': 'Bearer eyJ0b2tlbiI6InA0ajF0bjA4eGxqcm1xODJzZm94d2l6eWwzY2c3b28yIiwib2lkIjoxfQ',
          },
          body: JSON.stringify({
              "reqRoute": "query",
              "trackerAccessKey": "",
              "genericType": "main-chart",
              "fields": [],
              "mainActiveTab": "eventUniqueCount",
              "rangeType": "hourly",
              "conditions": {
                  "tracker_id": "mam1",
                  "from_date": 1706734800000,
                  "to_date": 1706811129699,
                  "event_type": {
                      "value": "screen_view",
                      "eq": true
                  }
              }
          }),
        }).then(response => response.json()).then(data => {console.log(data)});

Response:

JSON
        [
          { dt: '1706734800000', value: '41' },
          { dt: '1706738400000', value: '19' },
          { dt: '1706742000000', value: '56' },
          { dt: '1706745600000', value: '54' },
          { dt: '1706749200000', value: '43' },
          { dt: '1706752800000', value: '43' },
          { dt: '1706756400000', value: '37' },
          { dt: '1706760000000', value: '52' },
          { dt: '1706763600000', value: '67' },
          { dt: '1706767200000', value: '55' },
          { dt: '1706770800000', value: '23' },
          { dt: '1706774400000', value: '59' },
          { dt: '1706778000000', value: '54' },
          { dt: '1706781600000', value: '52' },
          { dt: '1706785200000', value: '65' },
          { dt: '1706788800000', value: '62' },
          { dt: '1706792400000', value: '65' },
          { dt: '1706796000000', value: '56' },
          { dt: '1706799600000', value: '58' },
          { dt: '1706803200000', value: '62' },
          { dt: '1706806800000', value: '57' },
          { dt: '1706810400000', value: '8' }
        ]

Getting Non-PFPH Fields

Request:

JavaScript
       fetch('https://api.metricalp.com/dashboard', {
          method: 'POST',
          headers: {
            'Content-Type': 'application/json',
            'Authorization': 'Bearer eyJ0b2tlbiI6InA0ajF0bjA4eGxqcm1xODJzZm94d2l6eWwzY2c3b28yIiwib2lkIjoxfQ',
          },
          body: JSON.stringify({
              "reqRoute": "query",
              "trackerAccessKey": "",
              "genericType": "non-pfph",
              "fields": [
                  "source",
                  "path"
              ],
              "conditions": {
                  "tracker_id": "mam1",
                  "from_date": 1706734800000,
                  "to_date": 1706811659111,
                  "event_type": {
                      "value": "screen_view",
                      "eq": true
                  }
              }
          }),
        }).then(response => response.json()).then(data => {console.log(data)});

Response:

JSON
        {
          source: [
            { label: 'Direct', uniq: '738' },
            { label: 'com.twitter.android', uniq: '310' },
            { label: 'www.adsensecustomsearchads.com', uniq: '27' },
            { label: 't.co', uniq: '15' },
            { label: 'www.google.com', uniq: '6' },
            { label: 'youtube.com', uniq: '5' },
            { label: 'com.google.android.gm', uniq: '1' }
          ],
          path: [
            { label: '/', uniq: '1073' },
            { label: '/contact', uniq: '55' },
            { label: '/blog', uniq: '42' },
            { label: '/features', uniq: '32' },
            { label: '/pricing', uniq: '31' },
            { label: '/docs/getting-started', uniq: '15' },
            { label: '/how-it-works', uniq: '15' },
            { label: '/team', uniq: '14' },
            { label: '/google-analytics-alternative', uniq: '10' },
            { label: '/about-us', uniq: '9' }
          ],
          unknown: []
        }

Getting PFPH Fields

Request:

JavaScript
       fetch('https://api.metricalp.com/dashboard', {
          method: 'POST',
          headers: {
            'Content-Type': 'application/json',
            'Authorization': 'Bearer eyJ0b2tlbiI6InA0ajF0bjA4eGxqcm1xODJzZm94d2l6eWwzY2c3b28yIiwib2lkIjoxfQ',
          },
          body: JSON.stringify({
              "reqRoute": "query",
              "trackerAccessKey": "",
              "genericType": "pfph",
              "fields": [
                  "operating_system",
                  "device_type",
                  "hostname"
              ],
              "conditions": {
                  "tracker_id": "mam1",
                  "from_date": 1706734800000,
                  "to_date": 1706811659111,
                  "event_type": {
                      "value": "screen_view",
                      "eq": true
                  }
              }
          }),
        }).then(response => response.json()).then(data => {console.log(data)});

Response:

JSON
        {
          operating_system: [
            { label: 'iOS', uniq: '611' },
            { label: 'Android', uniq: '424' },
            { label: 'Windows', uniq: '30' },
            { label: 'macOS', uniq: '24' },
            { label: 'Linux', uniq: '4' }
          ],
          device_type: [
            { label: 'mobile', uniq: '1026' },
            { label: 'desktop', uniq: '58' },
            { label: 'tablet', uniq: '9' }
          ],
          hostname: [
            { label: 'www.metricalp.com', uniq: '1091' },
            { label: 'dev.metricalp.com', uniq: '2' }
          ],
          unknown: []
        }

Getting Funnel

Request:

JavaScript
          fetch('https://api.metricalp.com/dashboard', {
          method: 'POST',
          headers: {
            'Content-Type': 'application/json',
            'Authorization': 'Bearer eyJ0b2tlbiI6InA0ajF0bjA4eGxqcm1xODJzZm94d2l6eWwzY2c3b28yIiwib2lkIjoxfQ',
          },
          body: JSON.stringify({
              "reqRoute": "query",
              "trackerAccessKey": "",
              "genericType": "funnel",
              "fields": [],
              "conditions": {
                  "tracker_id": "mam1",
                  "from_date": 1706734800000,
                  "to_date": 1706812149470,
                  "event_type": {
                      "value": "screen_view",
                      "eq": true
                  }
              },
              "funnel": "1-1-lrnyba2a-kt8>1-1-ls3jvfpd-mfk"
          }),
        }).then(response => response.json()).then(data => {console.log(data)});

Response:

JSON
{ '1-1-lrnyba2a-kt8': 337, '1-1-lrnyba2a-kt8>1-1-ls3jvfpd-mfk': 0 }

As you see, response also returning with IDs of goals instead names. You should use goal info (you got with get-tracker request) to map ids to goal names in funnel.

Getting Event Types

Request:

JavaScript
        fetch('https://api.metricalp.com/dashboard', {
          method: 'POST',
          headers: {
            'Content-Type': 'application/json',
            'Authorization': 'Bearer eyJ0b2tlbiI6InA0ajF0bjA4eGxqcm1xODJzZm94d2l6eWwzY2c3b28yIiwib2lkIjoxfQ',
          },
          body: JSON.stringify({
              "reqRoute": "query",
              "trackerAccessKey": "",
              "genericType": "event-type",
              "fields": [],
              "conditions": {
                  "tracker_id": "mam1",
                  "from_date": 1706734800000,
                  "to_date": 1706812312189
              }
          }),
        }).then(response => response.json()).then(data => {console.log(data)});

Response:

JSON
        [
          { event_type: 'screen_view', count: '1777' },
          { event_type: 'live_demo_button_click', count: '68' },
          { event_type: 'sso_login', count: '2' }
        ]

Getting Realtime Summary

Request:

JavaScript
       fetch('https://api.metricalp.com/dashboard', {
          method: 'POST',
          headers: {
            'Content-Type': 'application/json',
            'Authorization': 'Bearer eyJ0b2tlbiI6InA0ajF0bjA4eGxqcm1xODJzZm94d2l6eWwzY2c3b28yIiwib2lkIjoxfQ',
          },
          body: JSON.stringify({
              "reqRoute": "query",
              "trackerAccessKey": "",
              "genericType": "realtime-summary",
              "fields": [],
              "conditions": {
                  "tracker_id": "mam1",
                  "from_date": 1706811620538,
                  "to_date": 1706812520538
              }
          }),
        }).then(response => response.json()).then(data => {console.log(data)});

Response:

JSON
[ { unique_count: '14', total_count: '29' } ]

Getting Single field with pagination

Request:

JavaScript
       fetch('https://api.metricalp.com/dashboard', {
          method: 'POST',
          headers: {
            'Content-Type': 'application/json',
            'Authorization': 'Bearer eyJ0b2tlbiI6InA0ajF0bjA4eGxqcm1xODJzZm94d2l6eWwzY2c3b28yIiwib2lkIjoxfQ',
          },
          body: JSON.stringify({
              "reqRoute": "query",
              "trackerAccessKey": "",
              "genericType": "pfph",
              "fields": [
                  "country"
              ],
              "conditions": {
                  "tracker_id": "mam1",
                  "from_date": 1706734800000,
                  "to_date": 1706812519694,
                  "event_type": {
                      "value": "screen_view",
                      "eq": true
                  }
              },
              "extendedLimit": true,
              "offset": 0
          }),
        }).then(response => response.json()).then(data => {console.log(data)});

Bonus - Request for second page:

JavaScript
       fetch('https://api.metricalp.com/dashboard', {
          method: 'POST',
          headers: {
            'Content-Type': 'application/json',
            'Authorization': 'Bearer eyJ0b2tlbiI6InA0ajF0bjA4eGxqcm1xODJzZm94d2l6eWwzY2c3b28yIiwib2lkIjoxfQ',
          },
          body: JSON.stringify({
              "reqRoute": "query",
              "trackerAccessKey": "",
              "genericType": "pfph",
              "fields": [
                  "country"
              ],
              "conditions": {
                  "tracker_id": "mam1",
                  "from_date": 1706734800000,
                  "to_date": 1706812519694,
                  "event_type": {
                      "value": "screen_view",
                      "eq": true
                  }
              },
              "extendedLimit": true,
              "offset": 20
          }),
        }).then(response => response.json()).then(data => {console.log(data)});

Response:

JSON
       {
          country: [
            { label: 'India-IN', uniq: '195' },
            { label: 'Nigeria-NG', uniq: '162' },
            { label: 'Turkey-TR', uniq: '65' },
            { label: 'United Kingdom-GB', uniq: '57' },
            { label: 'Indonesia-ID', uniq: '35' },
            { label: 'Kenya-KE', uniq: '33' },
            { label: 'France-FR', uniq: '31' },
            { label: 'Germany-DE', uniq: '29' },
            { label: 'Thailand-TH', uniq: '29' },
            { label: 'Canada-CA', uniq: '28' },
            { label: 'South Africa-ZA', uniq: '25' },
            { label: 'Italy-IT', uniq: '19' },
            { label: 'Pakistan-PK', uniq: '18' },
            { label: 'Philippines-PH', uniq: '16' },
            { label: 'Poland-PL', uniq: '15' },
            { label: 'Taiwan-TW', uniq: '14' },
            { label: 'United Arab Emirates-AE', uniq: '13' },
            { label: 'Argentina-AR', uniq: '13' },
            { label: 'Ghana-GH', uniq: '12' },
            { label: 'Malaysia-MY', uniq: '12' }
          ],
          unknown: []
        }

Query with conditions (filters)

Request:

JavaScript
       fetch('https://api.metricalp.com/dashboard', {
          method: 'POST',
          headers: {
            'Content-Type': 'application/json',
            'Authorization': 'Bearer eyJ0b2tlbiI6InA0ajF0bjA4eGxqcm1xODJzZm94d2l6eWwzY2c3b28yIiwib2lkIjoxfQ',
          },
          body: JSON.stringify({
              "reqRoute": "query",
              "trackerAccessKey": "",
              "genericType": "non-pfph",
              "fields": [
                  "source"
              ],
              "conditions": {
                  "country": {
                      "eq": true,
                      "value": "Canada-CA"
                  },
                  "browser": {
                      "eq": true,
                      "value": "Mobile Chrome"
                  },
                  "tracker_id": "mam1",
                  "from_date": 1706734800000,
                  "to_date": 1706813796572,
                  "event_type": {
                      "value": "screen_view",
                      "eq": true
                  }
              }
          }),
        }).then(response => response.json()).then(data => {console.log(data)});

Response:

JSON
       {
          source: [
            { label: 'com.twitter.android', uniq: '3' },
            { label: 'Direct', uniq: '1' }
          ],
          browser_detail: [
            { label: 'Mobile Chrome 121', uniq: '3' },
            { label: 'Mobile Chrome 120', uniq: '1' }
          ],
          unknown: []
        }

When you have browser in condition you will also get browser_detail in response. This is case also source -> source_detail, operating_system -> os_detail

Query for Custom Event Type instead screen_view

Request:

JavaScript
       fetch('https://api.metricalp.com/dashboard', {
          method: 'POST',
          headers: {
            'Content-Type': 'application/json',
            'Authorization': 'Bearer eyJ0b2tlbiI6InA0ajF0bjA4eGxqcm1xODJzZm94d2l6eWwzY2c3b28yIiwib2lkIjoxfQ',
          },
          body: JSON.stringify({
              "reqRoute": "query",
              "trackerAccessKey": "",
              "genericType": "pfph",
              "fields": [
                  "country",
                  "city",
                  "user_language",
                  "browser"
              ],
              "conditions": {
                  "tracker_id": "mam1",
                  "from_date": 1706734800000,
                  "to_date": 1706813796572,
                  "event_type": {
                      "value": "live_demo_button_click",
                      "eq": true
                  }
              }
          }),
        }).then(response => response.json()).then(data => {console.log(data)});

Response:

JSON
       {
          country: [
            { label: 'India-IN', uniq: '16' },
            { label: 'Nigeria-NG', uniq: '5' },
            { label: 'Kenya-KE', uniq: '3' },
            { label: 'Pakistan-PK', uniq: '3' },
            { label: 'United Kingdom-GB', uniq: '2' },
            { label: 'Turkey-TR', uniq: '2' },
            { label: 'Germany-DE', uniq: '2' },
            { label: 'Botswana-BW', uniq: '2' },
            { label: 'Italy-IT', uniq: '1' },
            { label: 'South Africa-ZA', uniq: '1' }
          ],
          city: [
            { label: 'Nairobi-KE', uniq: '3' },
            { label: 'Mumbai-IN', uniq: '3' },
            { label: 'Pune-IN', uniq: '2' },
            { label: 'Madurai-IN', uniq: '2' },
            { label: 'Gaborone-BW', uniq: '2' },
            { label: 'Kayseri-TR', uniq: '2' },
            { label: 'Katsina-NG', uniq: '2' },
            { label: 'Abuja-NG', uniq: '2' },
            { label: 'Islamabad-PK', uniq: '2' },
            { label: 'Vapi-IN', uniq: '1' }
          ],
          user_language: [
            { label: 'English (United States)-US', uniq: '20' },
            { label: 'English (United Kingdom)-GB', uniq: '16' },
            { label: 'English (India)-IN', uniq: '6' },
            { label: 'Spanish (Argentina)-419', uniq: '1' },
            { label: 'English (Canada)-CA', uniq: '1' },
            { label: 'Russian-unknown', uniq: '1' },
            { label: 'French (France)-FR', uniq: '1' },
            { label: 'Chinese (S)-CN', uniq: '1' },
            { label: 'Russian (Russia)-RU', uniq: '1' },
            { label: 'German-unknown', uniq: '1' }
          ],
          browser: [
            { label: 'Mobile Chrome', uniq: '21' },
            { label: 'Mobile Safari', uniq: '15' },
            { label: 'Chrome', uniq: '7' },
            { label: 'Firefox', uniq: '2' },
            { label: 'Instagram', uniq: '1' },
            { label: 'Chrome WebView', uniq: '1' },
            { label: 'Facebook', uniq: '1' },
            { label: 'Samsung Browser', uniq: '1' }
          ],
          unknown: []
        }