# Telemetry Overview

An open specification for recording and measuring statistical data from real-world use of digital apps & platforms

## [Understanding Telemetry](/learn/understand)

## [Telemetry Specifications](/learn/specification)

## [Sending Telemetry](/use/sending_telemetry)

## [Consuming Telemetry](/use/consuming_telemetry)

## Library References

* Standalone JS Library

  The standalone telemetry JS library allows users to capture telemetry data without the restrictions of using any app that uses the Genie SDK, the EkStep content player or the EkStep or Sunbird portal. Partner users can use the JS library to log and sync telemetry data. They can decide how to use the Telemetry JS library, and integrate it with their app, webpage or web service

  [Standalone JS Library](/use/jslibrary) section will help you in understanding better how JS library serves the purpose of capturing telemetry data
* HTML Interface Library

  The ContentRenderer handles telemetry events for ECML content. HTML content has functionality such as click, navigation, assessment, etc. These functionalities are specific to or different for individual HTML content pieces.

  [HTML Interface Library](/use/html_interface_library) details information about the library used to log telemetry events for HTML content.
* AuthToken Generator JS Library

  The AuthToken generator JS Library is used to generate or refresh the user AuthToken. The Authtoken is mandatory for any API request.

  [AuthToken Generator JS Library](/use/authtokengenerator_jslibrary) details method and process of generating key and tokens.


# Understanding Telemetry

## What is Telemetry?

The word ‘Telemetry’ is derived from its Greek etymological roots, tele - remote and metron - measure.

In today’s connected world, Telemetry is a term used for technologies that automatically record and measure statistical data from real-world use and forward it to IT systems in a remote location for further analysis and study. Telemetry is used in a myriad of industries from tracking spacecrafts, medical monitoring, tracking wildlife, and so on.

'Events' are broad, human-readable actions, that can be tracked as a string. Events are used to categorize telemetry data.They are the basic unit for analytics and help identify user navigation or flow.

The concept of telemetry events is to identify:

**Who** did **what**, **on** **what**, and **where**, **using** **what**, **in relation** to what?

Every event has the following sections and corresponding fields to capture the data:

| Section        | Description              | Attributes                |
| -------------- | ------------------------ | ------------------------- |
| About          | About the event          | ets mid                   |
| Who            | About the actor          | uid                       |
| did            | Verb or action           | eid                       |
| on what        | Action on what object?   | content\_id content\_ver  |
| and where      | Context of the action    | env did sid channel pdata |
| using what     | Using which tool?        | ?                         |
| In relation to | Related to which action? | cdata                     |

## Why we need Telemetry?

The objective of telemetry is to assist in product, application or service development, modification or security. It works as a framework. Telemetry enables automatic collection of data from real-world, real-time use.

Typically, there are four levels of telemetry:

* Security
* Basic
* Enhanced
* Full

![](/files/-MkM8nIhrqLXkaHs3ABv)

The level of data collected is a discrete decision of an organization or business. Analysis of this data offers insights into product and user behaviour and usage patterns, driving business decisions and research outcomes. You can program your telemetry analytics to suit your requirements.

Sunbird’s telemetry service has Full level telemetry.


# Specification

## Version

The current version of the telemetry specification is 3. Version 3 is a complete rewrite of the specification where we have generalized the events in 17 generic event types to be able to capture all possible use-cases and not tied to any specific domain.

### Version 3.1

The telemetry version has been updated to 3.1 on 06/10/2021 with the addition of new optional attribute `platform` under the `pdata` section of the event envelope/structure.

The version 3 spec has provision to capture producer information in pdata as follows:

```javascript
pdata: {
    "id": "", // unique id assigned to that component. For ex: "sunbird.mobile" in case of a mobile app or "sunbird.desktop" incase of desktop
    "pid": "", // In case the component is distributed, then which instance of that component. For ex: "sunbird.mobile.contentplayer" incase of content player
    "ver": "" // version number of the build. For ex: "3.9.437"
}
```

However of late we have observed that there is increasing need to analyze the system/component usage by the underlying OS. For ex: Mobile usage distributed by android vs iOS is one example of it. Desktop usage segregated by Windows vs Ubuntu vs Mac is another example. To be able to support the need to analyze by the underlying platform we have introduced one more attribute `platform` under `pdata` as follows:

```javascript
pdata: {
    "id": "", // unique id assigned to that component. For ex: "sunbird.mobile" in case of a mobile app or "sunbird.desktop" incase of desktop
    "pid": "", // In case the component is distributed, then which instance of that component. For ex: "sunbird.mobile.contentplayer" incase of content player
    "ver": "", // version number of the build. For ex: "3.9.437"
    "platform": "" // Underlying OS platform. For ex: "Android/iOS/Windows/Ubuntu/MacOS"
}
```

## Telemetry V3 Event Structure

All events follow a common data structure, though the event data structure (“edata”) differs for each event. The complete data structure is as follows:

```
{
 // About the event
 "eid": , // Required. ID of the event
 "ets": , // Required. Epoch timestamp of event (time in milli-seconds. For ex: 1442816723)
 "ver": , // Required. Version of the event data structure, currently "3.1"
 "mid": , // Required. Unique message ID. Used for deduplication, replay and update indexes

 // Who did the event
 "actor": { // Required. Actor of the event.
   "id": , // Required. Id of the actor. For ex: uid incase of an user
   "type":  // Required. User, System etc.
 },

 // Context of the event
 "context": { // Required. Context in which the event has occured.
   "channel": , // Required. Channel which has produced the event
   "pdata": { // Optional. Producer of the event
     "id": , // Required. unique id assigned to that component
     "pid": , // Optional. In case the component is distributed, then which instance of that component
     "ver": , // Optional. version number of the build
     "platform": "" // Optional. Underlying OS platform. For ex: "Android/iOS/Windows/Ubuntu/MacOS"
   },
   "env": , // Required. Unique environment where the event has occured.
   "sid": , // Optional. session id of the requestor stamped by portal
   "did": , // Optional. uuid of the device, created during app installation
   "cdata": [{ // Optional. correlation data
     "type":"", // Required. Used to indicate action that is being correlated
     "id": "" // Required. The correlation ID value
   }],
   "rollup": { // Optional. Context rollups
     "l1": "",
     "l2": "",
     "l3": "",
     "l4": ""
   }
 },
 // What is the target of the event
 "object": { // Optional. Object which is the subject of the event.
   "id": , // Required. Id of the object. For ex: content id incase of content
   "type": , // Required. Type of the object. For ex: "Content", "Community", "User" etc.
   "ver": , // Optional. version of the object
   "rollup": { // Optional. Rollups to be computed of the object. Only 4 levels are allowed.
       "l1": "",
     "l2": "",
     "l3": "",
     "l4": ""
   }
 },

 // What is the event data
 "edata": {} // Required.

 // Tags
 "tags": [] // Optional. Encrypted dimension tags passed by respective channels
}
```

**Note:**

* All events have the same structure with only difference in edata structures.
* All events have unique event codes i.e., (IDs).
* All events are as per platform schema

## Events Specs

* [Start](/learn/v3_event_details#start) - This method initializes capture of telemetric data associated to the start of user action
* [Impression](/learn/v3_event_details#impression) - This method is used to capture telemetry for user visits to a specific page.
* [Interact](/learn/v3_event_details#interact) - This method is used to capture user interactions on a page. For example, search, click, preview, move, resize, configure
* [Assess ](/learn/v3_event_details#access)- This method is used to capture user assessments that happen while playing content.
* [Response](/learn/v3_event_details#response) - This method is used to capture user responses. For example; response to a poll, calendar event or a question.
* [Interrupt](/learn/v3_event_details#interrupt) - This method is used to capture interrupts triggered during user activity. For example; mobile app sent to background, call on the mobile, etc.
* [Feedback](/learn/v3_event_details#feedback) - This method is used to capture user feedback
* [Share](/learn/v3_event_details#share) - This method is used to capture everything associated with sharing. For example; Share content, telemetry data, link, file etc.
* [Audit](/learn/v3_event_details#audit) - This method is used to log telemetry when an object is changed. This includes life-cycle changes as well
* [Error](/learn/v3_event_details#error) - This method is used to capture when users face an error
* [Heartbeat](/learn/v3_event_details#heartbeat) - This method is used to log telemetry for heartbeat event to denote that the process is running
* [Log](/learn/v3_event_details#log) - This method is used to capture generic logging of events. For example; capturing logs for API calls, service calls, app updates etc.
* [Search](/learn/v3_event_details#search) - This method is used to capture the search state i.e. when search is triggered for content, item, assets etc.
* [Metrics](/learn/v3_event_details#metrics) - This method is used to log telemetry for service business metrics
* [Summary](/learn/v3_event_details#summary) - This method is used to log telemetry summary event
* [Exdata](/learn/v3_event_details#exdata) - This method is used as a generic wrapper event to capture encrypted or serialized data
* [End](/learn/v3_event_details#end) - This method is used to capture closure after all the activities are completed

### Start

This API is used to log telemetry when users view content or initiate game play

The "edata" structure of Start is as follows:

```
{
  "edata": {
    "type": "", // Required. app, session, editor, player, workflow, assessment
    "dspec": DSPEC, // Optional. Device spec
    "uaspec": UASPEC, // Optional. User agent spec
    "loc": "", // Optional. Location of the device
    "mode": "", // Optional. Mode of start. For "player" it would be "play/edit/preview". For Workflow it would be Review/Flag/Publish. For editor it could be "content", "textbook", "generic", "lessonplan" etc
    "duration": , // Optional. Time taken to initialize/start
    "pageid": "" // Optional. Page/Stage id where the start has happened.
  }
}
```

Example event data:

```
{
    "actor": {
      "id": "test-user1",
      "type": "User"
    },
    "context": {
      "cdata": [],
      "channel": "test-channel",
      "did": "test-device1",
      "env": "Genie",
      "pdata": {
        "id": "producer1",
        "pid": "genieservice.android",
        "ver": "1.0"
      },
      "sid": "3f2a0cc4-7bde-4044-8261-500dc13ef285"
    },
    "edata": {
      "mode": "edit",
      "pageid": "",
      "type": "player"
    },
    "eid": "START",
    "ets": 1518500741582,
    "mid": "92a9a779-ea2c-4f4e-8d07-fc7c3e851993",
    "tags": [],
    "ver": "3.0",
    "@timestamp": "2018-02-13T05:45:48.588Z",
    "ts": "2018-02-13T05:45:41.582+0000"
  }
```

### Impression

This API is used to log telemetry when users visit a specific page.

The "edata" structure of Start is as follows:

```
{
  "edata": {
    "type": "", // Required. Impression type (list, detail, view, edit, workflow, search)
    "subtype": "", // Optional. Additional subtype. "Paginate", "Scroll"
    "pageid": "", // Required. Unique page id
    "uri": "", // Required. Relative URL of the content
    "visits": [VISIT] // Optional. Capture the object visits
  }
}
```

Example event data:

```
{
    "actor": {
      "id": "test-user1",
      "type": "User"
    },
    "context": {
      "cdata": [],
      "channel": "test-channel",
      "did": "test-device1",
      "env": "ContentPlayer",
      "pdata": {
        "id": "producer1",
        "pid": "genieservice.android",
        "ver": "1.0"
      },
      "rollup": {},
      "sid": "7d6c6c9a-8323-49b2-84e0-3b46ae32eada"
    },
    "edata": {
      "visits": [
        {
          "objid": "course1",
          "objtype": "Course",
          "section": "Latest Courses",
          "index": 0
        },
        {
          "objid": "course2",
          "objtype": "Course",
          "section": "Latest Courses",
          "index": 1
        }
      ],
      "pageid": "home-page",
      "type": "workflow",
      "uri": ""
    },
    "eid": "IMPRESSION",
    "ets": 1518503128479,
    "mid": "4273778a-8f35-4945-97ae-bf5033c84425",
    "object": {
      "id": "test-content1",
      "type": "Content",
      "ver": "2.0"
    },
    "tags": [],
    "ver": "3.0",
    "@timestamp": "2018-02-13T06:25:32.914Z",
    "ts": "2018-02-13T06:25:28.479+0000"
  }
```

### Interact

This API is used to log telemetry of user interactions on the page. For example, search, click, preview, move, resize, configure

The "edata" structure of Start is as follows:

```
data - Object //Required
{
  "edata": {
    "type": "", // Required. Type of interaction TOUCH,DRAG,DROP,PINCH,ZOOM,SHAKE,ROTATE,SPEAK,LISTEN,WRITE,DRAW,START,ENDCHOOSE,ACTIVATE,SHOW,HIDE,SCROLL,HEARTBEAT,OTHER
    "subtype": "", // Optional. Additional types for a global type. For ex: for an audio the type is LISTEN and thesubtype can be one of PLAY,PAUSE,STOP,RESUME,END
    "id": "", // Required. Resource (button, screen, page, etc) id on which the interaction happened - use systemidentifiers when reporting device events
    "pageid": "", // Optional. Stage or page id on which the event happened
    "target": TARGET, // Optional. Target context where the interaction has happened
    "plugin": PLUGIN, // Optional. Plugin on which the interaction has happend
    "extra": { // Optional. Extra attributes for an interaction
      "pos": [{"x":,"y":,"z":}], // Array of positional attributes. For ex: Drag and Drop has two positional attributes. One where the drag has started and the drop point
      "values": [], // Array of values, e.g. for timestamp of audio interactions
    }
  }
}
```

Example event data:

```
{
    "actor": {
      "id": "test-user1",
      "type": "User"
    },
    "context": {
      "cdata": [],
      "channel": "test-channel",
      "did": "test-device1",
      "env": "ContentPlayer",
      "pdata": {
        "id": "producer1",
        "pid": "genieservice.android",
        "ver": "1.0"
      },
      "rollup": {},
      "sid": "7d6c6c9a-8323-49b2-84e0-3b46ae32eada"
    },
    "edata": {
      "id": "id1",
      "pageid": "end-page",
      "subtype": "",
      "type": "TOUCH"
    },
    "eid": "INTERACT",
    "ets": 1518503441413,
    "mid": "41c5632f-a47e-4910-99b3-3b351c3ca3bf",
    "object": {
      "id": "id1",
      "type": "Content",
      "ver": "1.0"
    },
    "tags": [],
    "ver": "3.0",
    "@version": "1",
    "@timestamp": "2018-02-13T06:30:33.578Z",
    "ts": "2018-02-13T06:30:41.413+0000"
  }
```

### Assess

This API is used to log telemetry of assessments that have occured when the user is viewing content

The "edata" structure of Start is as follows:

```
{
  "edata": {
    "item": QUESTION, // Required. Question Data
    "index": , // Optional. Index of the question within a content.
    "pass": "", // Required. Yes, No. This is case-sensitive. default value: No.
    "score": , // Required. Evaluated score (Integer or decimal) on answer(between 0 to 1), default is 1 if pass=YES or 0 if pass=NO. 
    "resvalues": [{"id":"value"}], // Required. Array of key-value pairs that represent child answer (result of this assessment)
    "duration":  // Required. time taken (decimal number) for this assessment in seconds
  }
}
```

Example event data:

```
{
    "actor": {
      "id": "test-user1",
      "type": "User"
    },
    "context": {
      "cdata": [],
      "channel": "test-channel",
      "did": "test-device",
      "env": "ContentPlayer",
      "pdata": {
        "id": "producer1",
        "ver": "1.0"
      },
      "rollup": {},
      "sid": "ci4gjqokrccvbdl4kss4pbhnh0"
    },
    "edata": {
      "duration": 9,
      "item": {
        "desc": "",
        "exlength": 0,
        "id": "ques1",
        "maxscore": 1,
        "mc": [],
        "mmc": [],
        "params": [],
        "uri": ""
      },
      "pass": "No",
      "resvalues": [
        {
          "ans1": "6"
        }
      ],
      "score": 0
    },
    "eid": "ASSESS",
    "ets": 1518503832030,
    "mid": "4399a98d6c50c5d70a3150f3a5ab649e",
    "object": {
      "id": "test-content",
      "type": "Content",
      "ver": "1.0"
    },
    "tags": [],
    "ver": "3.0",
    "@timestamp": "2018-02-13T06:37:25.333Z",
    "ts": "2018-02-13T06:37:12.030+0000"
  }
```

### Response

This API is used to log telemetry of user response. For example; Responded to assessments.

The "edata" structure of Start is as follows:

```
{
  "edata": {
    "target": TARGET, // Required. Target of the response
    "type": "", // Required. Type of response. CHOOSE, DRAG, SELECT, MATCH, INPUT, SPEAK, WRITE
    "values": [{"key":"value"}] // Required. Array of response tuples. For ex: if lhs option1 is matched with rhs optionN - [{"lhs":"option1"}, {"rhs":"optionN"}]
  }
}
```

Example event data:

```
{
    "actor": {
      "id": "test-user1",
      "type": "User"
    },
    "context": {
      "cdata": [],
      "channel": "test-channel",
      "did": "test-device",
      "env": "ContentPlayer",
      "pdata": {
        "id": "producer1",
        "ver": "1.0"
      },
      "rollup": {},
      "sid": ""
    },
    "edata": {
      "target": {
        "id": "ques1",
        "type": "AssessmentItem",
        "ver": "1.0"
      },
      "type": "SELECT",
      "values": [
        {
          "option": "A",
          "state": "selected"
        }
      ]
    },
    "eid": "RESPONSE",
    "ets": 1518503809778,
    "mid": "RESPONSE:55ea33c06880c9179c92d223661172c6",
    "object": {
      "id": "test-content1",
      "type": "Content",
      "ver": "1"
    },
    "tags": [],
    "ver": "3.0",
    "@timestamp": "2018-02-13T06:37:01.255Z",
    "ts": "2018-02-13T06:36:49.778+0000"
  }
```

### Interrupt

This API is used to log telemetry for any interruptions that have occurred when a user is viewing content or playing games. For example; screen lock, incoming call, etc.

The "edata" structure of Start is as follows:

```
{
  "edata": {
    "type": "", // Required. [m:background, m:resume]
    "pageid": "" // Optional. Page id where the interrupt has happened
  }
}
```

Example event data:

```
{
    "actor": {
      "id": "test-user",
      "type": "User"
    },
    "eid": "INTERRUPT",
    "edata": {
      "type": "resume"
    },
    "ver": "3.0",
    "@timestamp": "2018-02-13T06:48:56.626Z",
    "ets": 1518504535560,
    "context": {
      "channel": "test-channel",
      "env": "Genie",
      "sid": "a9da9668-d3f0-4edf-8c2a-e92c0b4cb24f",
      "did": "test-device",
      "pdata": {
        "id": "producer1",
        "pid": "genieservice.android",
        "ver": "1.0.25"
      },
      "cdata": []
    },
    "mid": "INTERRUPT:15704362-aa2a-4b4c-b99c-0f4296a98f52",
    "object": {
      "parent": {}
    },
    "tags": [
      "registered-tag1"
    ],
    "ts": "2018-02-13T06:48:55.560+0000"
  }
```

### Feedback

This API is used to log telemetry of feedback provided by the user.

The "edata" structure of Start is as follows:

```
{
  "edata": {
    "rating": 3, // Optional. Numeric score (+1 for like, -1 for dislike, or 4.5 stars given in a rating)
    "comments": "User entered feedback" // Optional. Text feedback (if any)
  }
}
```

Example event data:

```
{
    "actor": {
      "id": "test-user",
      "type": "User"
    },
    "context": {
      "cdata": [],
      "channel": "test-channel",
      "did": "test-device",
      "env": "ContentPlayer",
      "pdata": {
        "id": "producer",
        "pid": "genieservice.android",
        "ver": "1.0"
      },
      "rollup": {},
      "sid": "fe6e4b5f-ef32-4a20-827f-eb094df05e8a"
    },
    "edata": {
      "comments": "",
      "rating": 2
    },
    "eid": "FEEDBACK",
    "ets": 1518456436008,
    "mid": "5a7bee12-a4ed-49b1-9ac9-e03343045d08",
    "object": {
      "id": "test-content1",
      "type": "Content",
      "ver": "1.0"
    },
    "tags": [],
    "ver": "3.0",
    "@timestamp": "2018-02-12T17:27:27.297Z",
    "ts": "2018-02-12T17:27:16.008+0000"
  }
```

### Share

This API is used to log telemetry when a user shares any content with other users.

The "edata" structure of Start is as follows:

```
{
  "edata": {
    "dir": "", // In/Out
    "type": "", // File/Link/Message
    "items": [{ // Required. array of items shared
      "id": "",
      "type": "",
      "ver": ""
      "params": [
        {"key": "value"}
      }],
      "origin": { // Origin of the share file/link/content
        "id": "", // Origin id
        "type": "" // Origin type
      },
      "to": {
        "id": "",
        "type": ""
      }
    }]
  }
}
```

Example event data:

```
{
    "actor": {
      "id": "test-user1",
      "type": "User"
    },
    "eid": "SHARE",
    "edata": {
      "dir": "In",
      "type": "File",
      "items": [
        {
          "ver": "1.0",
          "origin": {
            "id": "devcie1",
            "type": "device"
          },
          "id": "content1",
          "to": {
            "id": "",
            "type": ""
          },
          "type": "CONTENT",
          "params": [
            {
              "transfers": 0,
              "count": 0
            }
          ]
        },
        {
          "ver": "2.0",
          "origin": {
            "id": "device1",
            "type": "device"
          },
          "id": "content2",
          "to": {
            "id": "",
            "type": ""
          },
          "type": "CONTENT",
          "params": [
            {
              "transfers": 0,
              "count": 0
            }
          ]
        }
      ]
    },
    "ver": "3.0",
    "@timestamp": "2018-02-13T07:00:59.995Z",
    "ets": 1518505245934,
    "context": {
      "channel": "test-channel",
      "env": "Genie",
      "sid": "6aa26dab-672e-4507-a2b5-c63fe926796c",
      "did": "test-device",
      "pdata": {
        "id": "producer1",
        "pid": "genieservice.android",
        "ver": "1.0.25"
      },
      "cdata": []
    },
    "mid": "SHARE:ec607e89-7d5f-4898-ae86-c690e35432fa",
    "object": {
      "parent": {}
    },
    "tags": [
      "tag1"
    ],
    "ts": "2018-02-13T07:00:45.934+0000"
  }
```

### Audit

This API is used to log telemetry when an object is changed. This includes life-cycle changes as well.

The "edata" structure of Start is as follows:

```
data - Object //Required
{
  "edata": {
    "props": [""], // Updated properties
    "state": "", // Optional. Current state
    "prevstate": "" // Optional. Previous state
  }
}
```

Example event data:

```
{
    "actor": {
      "id": "",
      "type": ""
    },
    "eid": "AUDIT",
    "edata": {
      "state": "Draft",
      "prevstate": ""
    },
    "ver": "3.0",
    "@timestamp": "2018-02-13T07:09:04.183Z",
    "ets": 1518505742782,
    "context": {
      "channel": "test-channel",
      "env": "",
      "sid": "",
      "did": "",
      "pdata": {
        "id": "producer1",
        "pid": "ObjectLifecycle",
        "ver": "1.0"
      },
      "cdata": []
    },
    "mid": "AUDIT:6ef03ef3a9fa8308204ea4d8570591e0",
    "object": {
      "id": "test-content1",
      "type": "Content",
      "ver": "",
      "subtype": "Story",
      "parent": {
        "id": "",
        "type": ""
      }
    },
    "tags": [],
    "ts": "2018-02-13T07:09:02.782+0000"
  }
```

### Error

This API is used to log telemetry of any error that has occurred when a user is viewing content or playing games.

The "edata" structure of Start is as follows:

```
{
  "edata": {
    "err": "", // Required. Error code
    "errtype": "", // Required. Error type classification - "SYSTEM", "MOBILEAPP", "CONTENT"
    "stacktrace": "", // Required. Detailed error data/stack trace
    "pageid": "", // Optional. Page where the error has occured
    "object": OBJECT, // Optional. Object on which the error occured
    "plugin": PLUGIN // Optional. Plugin in which the error occured
  }
}
```

Example event data:

```
{
    "actor": {
      "id": "test-user",
      "type": "User"
    },
    "context": {
      "cdata": [],
      "channel": "test-channel",
      "did": "test-device",
      "env": "Genie",
      "pdata": {
        "id": "producer1",
        "pid": "genieservice.android",
        "ver": "6.0"
      },
      "sid": "a8506bb6-edc5-4b59-b935-07dbabd1e9f3"
    },
    "edata": {
      "err": "ERR_TOKEN_INVALID",
      "errtype": "UNAUTHORIZED_ACCESS",
      "stacktrace": "{\"id\":\"api.upload.url\",\"ver\":\"1.0\",\"ts\":\"2018-02-12T17:04:21.726Z\",\"params\":{\"resmsgid\":\"id1\",\"msgid\":null,\"status\":\"failed\",\"err\":\"ERR_TOKEN_INVALID\",\"errmsg\":\"Access denied\"},\"responseCode\":\"UNAUTHORIZED_ACCESS\",\"result\":{}}"
    },
    "eid": "ERROR",
    "ets": 1518505910718,
    "mid": "58a11d49-22c8-4535-a28b-7a323005d930",
    "tags": [],
    "ver": "3.0",
    "@timestamp": "2018-02-13T07:12:10.415Z",
    "ts": "2018-02-13T07:11:50.718+0000"
  }
```

### Heartbeat

This API is used to log telemetry for heartbeat event to denote that the process is running.

The "edata" structure of Start is as follows:

```
data - Object //Required
{
  "edata": {
  }
}
```

### Log

This API is used to log telemetry of generic log events. For example; API calls, service calls, app updates, etc.

The "edata" structure of Start is as follows:

```
{
  "edata": {
    "type": "", // Required. Type of log (system, process, api_access, api_call, job, app_update etc)
    "level": "", // Required. Level of the log. TRACE, DEBUG, INFO, WARN, ERROR, FATAL
    "message": "", // Required. Log message
    "pageid": "", // Optional. Page where the log event has happened
    "params": [{"key":"value"}] // Optional. Additional params in the log message
  }
}
```

Example event data:

```
{
    "actor": {
      "id": "test-user1",
      "type": "User"
    },
    "eid": "LOG",
    "edata": {
      "level": "trace",
      "type": "api_call",
      "message": "successful",
      "params": [
        {
          "mode": "WIFI"
        }
      ]
    },
    "ver": "3.0",
    "@timestamp": "2018-02-12T13:00:24.918Z",
    "ets": 1518460198146,
    "context": {
      "channel": "test-channel",
      "env": "Genie",
      "sid": "85a8b3af-362f-48a5-9454-ac050dfe5a3a",
      "did": "test-device",
      "pdata": {
        "id": "producer1",
        "pid": "genieservice.android",
        "ver": "1.0.25"
      },
      "cdata": []
    },
    "mid": "LOG:69e9ca45-c7e2-4a94-af50-50a4ff854cc9",
    "object": {
      "parent": {}
    },
    "tags": [
      "tag1"
    ],
    "ts": "2018-02-12T18:29:58.146+0000"
  }
```

### Search

This API is used to log telemetry when a user triggers a search for any content, item or asset

The "edata" structure of Start is as follows:

```
{
  "edata": {
    "type": "",
    "query": "", // Required. Search query string 
    "filters": {}, // Optional. Additional filters (see the API spec)
    "sort": {}, // Optional. Additional sort parameters
    "correlationid": "", // Optional. Server generated correlation id (for mobile app's telemetry)
    "size": 333, // Required. Number of search results
    "topn": [{}] // Required. top N (configurable) results with their score
  }
}
```

Example event data:

```
{
    "actor": {
      "id": "test-user",
      "type": "User"
    },
    "context": {
      "cdata": [],
      "channel": "test-channel",
      "did": "test-device",
      "env": "Genie",
      "pdata": {
        "id": "producer1",
        "pid": "genieservice.android",
        "ver": "6.6"
      },
      "sid": "0ec7c32e-8058-4624-be72-623760c9c5c3"
    },
    "edata": {
      "correlationid": "abcd",
      "filters": {
        "compatibilityLevel": {
          "max": 3,
          "min": 1
        },
        "contentType": [
          "Story",
          "Worksheet",
          "Game",
          "Collection",
          "TextBook"
        ],
        "objectType": [
          "Content"
        ],
        "status": [
          "Live"
        ]
      },
      "query": "hshshshhs",
      "size": 0,
      "topn": [],
      "type": "Content"
    },
    "eid": "SEARCH",
    "ets": 1516001242930,
    "mid": "7cfb0376-45b6-4e05-885b-081b7097b938",
    "tags": [],
    "ver": "3.0",
    "@timestamp": "2018-01-15T07:29:12.553Z",
    "ts": "2018-01-15T07:27:22.930+0000"
  }
```

### Metrics

This API is used to log telemetry for service business metrics (also accessible via health API).

The "edata" structure of Start is as follows:

```
data - Object - Required
{
  "edata": {
    "metric1": Int,
    "metric2": Int
    /// more metrics, each is a key value
  }
}
```

### Summary

This API is used to log telemetry summary event

The "edata" structure of Start is as follows:

```
{
  "edata": {
    "type": "", // Required. Type of summary. Free text. "session", "app", "tool" etc
    "mode": "", // Optional.
    "starttime": Long, // Required. Epoch Timestamp of app start. Retrieved from first event.
    "endtime": Long, // Required. Epoch Timestamp of app end. Retrieved from last event.
    "timespent": Double, // Required. Total time spent by visitor on app in seconds excluding idle time.
    "pageviews": Long, // Required. Total page views per session(count of CP_IMPRESSION)
    "interactions": Long, // Required. Count of interact events
    "envsummary": [{ // Optional
        "env": String, // High level env within the app (content, domain, resources, community)
        "timespent": Double, // Time spent per env
        "visits": Long // count of times the environment has been visited
    }],
    "eventssummary": [{ // Optional
        "id": String, // event id such as CE_START, CE_END, CP_INTERACT etc.
        "count": Long // Count of events.
    }],
    "pagesummary": [{ // Optional
        "id": String, // Page id
        "type": String, // type of page - view/edit
        "env": String, // env of page
        "timespent": Double, // Time taken per page
        "visits": Long // Number of times each page was visited
    }],
    "extra": [{ // Optional. Additional summary data specific to mime type or app. For ex: wordsPerMin
      "id": "", // Required. Key for the extra data
      "value": "" // Required. Value for the extra data
    }]
  }
}
```

### Exdata

This API is used to log telemetry for external data, while playing content

The "edata" structure of Start is as follows:

```
{
  "edata": {
    "type": "", // Free flowing text. For ex: partnerdata, xapi etc
    "data": "" // Serialized data (can be either encrypted/encoded/stringified)
  }
}
```

Example event data:

```
{
    "actor": {
      "id": "test-user",
      "type": "User"
    },
    "eid": "EXDATA",
    "edata": {
      "data": "\"dc:APA91bFi4zDhvOiymoL4uMszNfOBnPXTzPiohtVEQ5pmoKD7Hwo_1MYgZVdkk9fPne7xHP7cUu_eic6NU2RKldKiISefqilYJfpoCHe8ouidqLUNfhjKr\"",
      "type": "partnerdata"
    },
    "ver": "3.0",
    "@timestamp": "2018-02-13T07:43:25.271Z",
    "ets": 1518507781930,
    "context": {
      "channel": "test-channel",
      "env": "Genie",
      "sid": "8aaf8a9e-7c23-44e2-b262-dffc2935a3b7",
      "did": "test-device",
      "pdata": {
        "id": "producer1",
        "pid": "genieservice.android"
      },
      "cdata": []
    },
    "mid": "EXDATA:32b880df-a2d9-41e6-9821-9c9108fddbcc",
    "object": {
      "parent": {}
    },
    "tags": [],
    "ts": "2018-02-13T07:43:01.930+0000"
  }
```

### End

This API is used to log telemetry while the user is closing or exiting the content or game

The "edata" structure of Start is as follows:

```
{
  "edata": {
    "type": , // Required. app, session, editor, player, workflow, assessment
    "mode": "", // Optional. Mode of start. For "player" it would be "play/edit/preview". For Workflow it would be Review/Flag/Publish. For editor it could be "content", "textbook", "generic", "lessonplan" etc
    "duration": , // Optional. Total duration from start to end in seconds
    "pageid": "", // Optional. Page/Stage id where the end has happened.
    "summary": [{"key":"value"}] // Optional. Summary of the actions done between start and end. For ex: "progress" for player session, "nodesModified" for collection editor
  }
}
```

Example event data:

```
{
    "actor": {
      "id": "test-user",
      "type": "User"
    },
    "eid": "END",
    "edata": {
      "mode": "play",
      "duration": 21,
      "summary": [
        {
          "progress": 50
        }
      ],
      "type": "player",
      "pageid": "play_video"
    },
    "ver": "3.0",
    "@timestamp": "2018-02-13T08:55:16.041Z",
    "ets": 1518512093695,
    "context": {
      "channel": "test-channel",
      "env": "ContentPlayer",
      "sid": "575d41ea-01fb-4e5e-86e0-5af15d82c7ee",
      "did": "test-device",
      "pdata": {
        "id": "producer",
        "pid": "genieservice.android",
        "ver": "1.0"
      },
      "cdata": [ ]
    },
    "mid": "END:54b2e8ea-e376-4d91-94eb-9cd4356a934e",
    "object": {
      "id": "test-content",
      "type": "Content",
      "ver": "1.0"
    },
    "tags": [
      "tag1"
    ],
    "ts": "2018-02-13T08:54:53.695+0000"
  }
```


# V3 Event Details

Every API method has an associated event. The following API methods log details of the associated telemetry event.

* [Start](/learn/v3_event_details#start) - This method initializes capture of telemetric data associated to the start of user action
* [Impression](/learn/v3_event_details#impression) - This method is used to capture telemetry for user visits to a specific page.
* [Interact](/learn/v3_event_details#interact) - This method is used to capture user interactions on a page. For example, search, click, preview, move, resize, configure
* [Assess ](/learn/v3_event_details#access)- This method is used to capture user assessments that happen while playing content.
* [Response](/learn/v3_event_details#response) - This method is used to capture user responses. For example; response to a poll, calendar event or a question.
* [Interrupt](/learn/v3_event_details#interrupt) - This method is used to capture interrupts triggered during user activity. For example; mobile app sent to background, call on the mobile, etc.
* [Feedback](/learn/v3_event_details#feedback) - This method is used to capture user feedback
* [Share](/learn/v3_event_details#share) - This method is used to capture everything associated with sharing. For example; Share content, telemetry data, link, file etc.
* [Audit](/learn/v3_event_details#audit)
* [Error](/learn/v3_event_details#error) - This method is used to capture when users face an error
* [Heartbeat](/learn/v3_event_details#heartbeat) -
* [Log](/learn/v3_event_details#log) - This method is used to capture generic logging of events. For example; capturing logs for API calls, service calls, app updates etc.
* [Search](/learn/v3_event_details#search) - This method is used to capture the search state i.e. when search is triggered for content, item, assets etc.
* [Metrics](/learn/v3_event_details#metrics)
* [Summary](/learn/v3_event_details#summary)
* [Exdata](/learn/v3_event_details#exdata) - This method is used as a generic wrapper event to capture encrypted or serialized data
* [End](/learn/v3_event_details#end) - This method is used to capture closure after all the activities are completed

## Start

This API is used to log telemetry when users view content or initiate game play

```

start: function(config, contentId, contentVer, data) { }
```

Request Arguments:

```

{
  "config": Object, //Config object
  "contentId": String, //Required. Id of the content
  "contentVer": String, //Required. Version of the content. Defaults to "1.0"
  "data": { // Required. event data

    "type": String, //Required.  app, session, editor, player, workflow, assessment
    "mode": "", //Required. mode of preview: preview, edit or play 
    "stageid": "" //Required. stage id where the play has been initiated
  }
}
```

## Impression

This API is used to log telemetry when users visit a specific page.

```

impression: function(data) { }
```

Request Arguments:

```

data - Object //Required

{

    "type": String, //Required. Impression type (list, detail, view, edit, workflow, search)

    "subtype": String, //Optional. Additional subtype. "Paginate", "Scroll"

    "pageid": String, //Required.  Unique page id

    "itype": "", // type of interaction - SWIPE, SCRUB (fast forward using page thumbnails) or AUTO

    "stageto": "" // game level, stage of page id to which the navigation was done

}
```

## Interact

This API is used to log telemetry of user interactions on the page. For example, search, click, preview, move, resize, configure

```

interact: function(data) { }
```

Request Arguments:

```

data - Object //Required
{
  "type": "", // Required. Type of interaction TOUCH,DRAG,DROP,PINCH,ZOOM,SHAKE,ROTATE,SPEAK,LISTEN,WRITE,DRAW,START,ENDCHOOSE,ACTIVATE,SHOW,HIDE,SCROLL,HEARTBEAT,OTHER
  "subtype": "", // Optional. Additional types for a global type. For ex: for an audio the type is LISTEN and thesubtype can be one of PLAY,PAUSE,STOP,RESUME,END
  "id": "", // Required. Resource (button, screen, page, etc) id on which the interaction happened - use systemidentifiers when reporting device events
  "pageid": "", // Optional. Stage or page id on which the event happened
  "extra": { // Optional. Extra attributes for an interaction
    "pos": [{"x":,"y":,"z":}], // Array of positional attributes. For ex: Drag and Drop has two positional attributes. One where the drag has started and the drop point
    "values": [], // Array of values, e.g. for timestamp of audio interactions
    "tid": "", // When interaction is between multiple resources, (e.g. drag and drop) - target resource id
    "uri": "" // Unique external resource identifier if any (for recorded voice, image, etc.)
  }
}
```

## Assess

This API is used to log telemetry of assessments that have occured when the user is viewing content

```

assess: function(data) { }
```

Request Arguments:

```

data - Object //Required
{
  "item": QUESTION, // Required. Question Data
  "pass": "", // Required. Yes, No. This is case-sensitive. default value: No.
  "score": , // Required. Evaluated score (Integer or decimal) on answer(between 0 to 1), default is 1 if pass=YES or 0 if pass=NO. 
  "resvalues": [{"id":"value"}], // Required. Array of key-value pairs that represent child answer (result of this assessment)
  "duration":  // Required. time taken (decimal number) for this assessment in seconds
}

QUESTION = {
  "id": "", // unique assessment question id. its an required property.
  "maxscore", // user defined score to this assessment/question.
  "exlength": , // expected time (decimal number) in seconds that ideally child should take
  "params": [ // Array of parameter tuples
     {"id":"value"} // for ex: if var1 is substituted with 5 apples the parameter is {"var1":"5"}
  ],
  "uri": "", // Unique external resource identifier if any (for recorded voice, image, etc.)
  "desc": "short description",
  "title": "title",
  "mmc": [], // User defined missing micros concepts
  "mc": []   // micro concepts list
}
```

## Response

This API is used to log telemetry of user response. For example; Responded to assessments.

```

response: function(data) { }
```

Request Arguments:

```

data  - Object //Required
{
  "target": TARGET, // Required. Target of the response
  "qid": "", // Required. Unique assessment/question id
  "type": "", // Required. Type of response. CHOOSE, DRAG, SELECT, MATCH, INPUT, SPEAK, WRITE
  "values": [{"key":"value"}] // Required. Array of response tuples. For ex: if lhs option1 is matched with rhs optionN - [{"lhs":"option1"}, {"rhs":"optionN"}]
}

TARGET = {
  "id": "", // Required. unique id for the target
  "ver": "", // Required. version of the target
  "type": "", // Required. Type of the target
  "parent": {
    "id": "", // Optional. parent id of the object
    "type": "" // Optional. parent type of the object. Required if parentid is present.
  }
}
```

## Interrupt

This API is used to log telemetry for any interruptions that have occurred when a user is viewing content or playing games. For example; screen lock, incoming call, etc.

```

interrupt: function(data) { }
```

Request Arguments:

```

data - Object //Required
{
  "type": "", // Required. Type of interuption
  "pageid": "", // Optional. Current Stage/Page unique id on which interuption occured
  "eventid": "" // Optional. unique event ID
}
```

## Feedback

This API is used to log telemetry of feedback provided by the user.

```

// To log content start/play event
feedback: function(data) { }
```

Request Arguments:

```

data - Object //Required
{
  "contentId": "", // Required. Id of the content
  "rating": 3, // Optional. Numeric score (+1 for like, -1 for dislike, or 4.5 stars given in a rating)
  "comments": "User entered feedback" // Optional. Text feedback (if any)
}
```

## Share

This API is used to log telemetry when a user shares any content with other users.

```

// To log content start/play event
share: function(data) { }
```

Request Arguments:

```

data - Object //Required
{
  "dir": "", // In/Out
  "type": "", // File/Link/Message
  "items": [{ // Required. array of items shared
    "obj": {
      "id": "",
      "type": "",
      "ver": ""
    },
    "params": [
      {"key": "value"}
    ],
    "origin": { // Origin of the share file/link/content
      "id": "", // Origin id
      "type": "" // Origin type
    },
    "to": {
      "id": "",
      "type": ""
    }
  }]
}
```

## Audit

This API is used to log telemetry when an object is changed. This includes life-cycle changes as well.

```

audit: function(data) { }
```

Request Arguments:

```

data - Object //Required
{
  "edata": {
    "props": [""], // Updated properties
    "state": "", // Optional. Current state
    "prevstate": "" // Optional. Previous state
  }
}
```

## Error

This API is used to log telemetry of any error that has occurred when a user is viewing content or playing games.

```

error: function(error) { }
```

Request Arguments:

```

error - Object //Required
{
  "err": "", // Required. Error code
  "errtype": "", // Required. Error type classification - "SYSTEM", "MOBILEAPP", "CONTENT"
  "stacktrace": "", // Required. Detailed error data/stack trace
}
```

## Heartbeat

This API is used to log telemetry for heartbeat event to denote that the process is running.

```

heartbeat: function(data) { }
```

Request Arguments:

```

data - Object //Required
{
  {
  "edata": {
  }
}
```

## Log

This API is used to log telemetry of generic log events. For example; API calls, service calls, app updates, etc.

```

log: function(data) { }
```

Request Arguments:

```

data - Object //Required
{
  "type": "", // Required. Type of log (system, process, api_access, api_call, job, app_update etc)
  "level": "", // Required. Level of the log. TRACE, DEBUG, INFO, WARN, ERROR, FATAL
  "message": "", // Required. Log message
  "params": [{"key":"value"}] // Optional. Additional params in the log message
}
```

## Search

This API is used to log telemetry when a user triggers a search for any content, item or asset

```

search: function(data) { }
```

Request Arguments:

```

data - Object - Required
{
  "type": "", // Required. content, assessment, asset 
  "query": "", // Required. Search query string 
  "filters": {}, // Optional. Additional filters
  "sort": {}, // Optional. Additional sort parameters
  "correlationid": "", // Optional. Server generated correlation id (for mobile app's telemetry)
  "size": 333, // Required. Number of search results
  "topn": [{}] // Required. top N (configurable) results with their score
}
```

## Metrics

This API is used to log telemetry for service business metrics (also accessible via health API).

```

metrics: function(data) { }
```

Request Arguments:

```

data - Object - Required
{
  "edata": {
    "metric1": Int,
    "metric2": Int
    /// more metrics, each is a key value
  }
}
```

## Summary

This API is used to log telemetry summary event

```

summary: function(data) { }
```

Request Arguments:

```

data - Object - Required
{
  "edata": {
    "type": "", // Required. Type of summary. Free text. "session", "app", "tool" etc
    "mode": "", // Optional.
    "starttime": Long, // Required. Epoch Timestamp of app start. Retrieved from first event.
    "endtime": Long, // Required. Epoch Timestamp of app end. Retrieved from last event.
    "timespent": Double, // Required. Total time spent by visitor on app in seconds excluding idle time.
    "pageviews": Long, // Required. Total page views per session(count of CP_IMPRESSION)
    "interactions": Long, // Required. Count of interact events
    "envsummary": [{ // Optional
        "env": String, // High level env within the app (content, domain, resources, community)
        "timespent": Double, // Time spent per env
        "visits": Long // count of times the environment has been visited
    }],
    "eventssummary": [{ // Optional
        "id": String, // event id such as CE_START, CE_END, CP_INTERACT etc.
        "count": Long // Count of events.
    }],
    "pagesummary": [{ // Optional
        "id": String, // Page id
        "type": String, // type of page - view/edit
        "env": String, // env of page
        "timespent": Double, // Time taken per page
        "visits": Long // Number of times each page was visited
    }],
    "extra": [{ // Optional. Additional summary data specific to mime type or app. For ex: wordsPerMin
       "id": "", // Required. Key for the extra data
       "value": "" // Required. Value for the extra data
    }]
  }
}
```

## Exdata

This API is used to log telemetry for external data, while playing content

```

exdata: function(data) { }
```

Request Arguments:

```

data - Object - Required

{

  type - Free flowing text. For ex: partnerdata, xapi etc

  .... Serialized data (can be either encrypted/encoded/stringified)

}
```

## End

This API is used to log telemetry while the user is closing or exiting the content or game

```

end: function(data) { }
```

Request Arguments:

```

data - Object //Required
{
  "contentId": "", // Required. Id of the content
  "type": , // Required. app, session, editor, player, workflow, assessment
  "duration": , // Required. Total duration from start to end in seconds
  "pageid": "", // Optional. Page/Stage id where the end has happened.
  "summary": [{"key":"value"}] // Optional. Summary of the actions done between start and end. For ex: "progress" for player session, "nodesModified" for collection editor
}
```


# jslibrary

## Need

The purpose of a standalone JS library for telemetry is to facilitate capture and distribution of telemetry data by users who would like to use their own apps, content players or portals.

We chose to use a JS library for the following reasons:

* All the telemetry events that are generated and synced to the server have the same format (field data types and time zone value)
* It is easy to upgrade to new versions, in case of major changes in telemetry
* There is effortless backward compatibility, as changes are handled within the telemetry library. Any upgrade of the telemetry library does not require code changes in the content
* There are reduced number of API calls
* There are simple API methods to generate the complete telemetry event as only the required fields are passed

## Prerequisites

The following are prerequisites to use or integrate the JS library:

* JQuery library should be available
* Valid Authtoken and Key to make API calls
* The [telemetry.min.js](https://github.com/project-sunbird/project-sunbird.github.io/blob/dev/pages/developer-docs/telemetry/other_files/telemetry.min.js){:target="\_blank"} file

**Note:** For details on generating and using the Authtoken and Key, refer to the section

* Device ID value

**Note:** For details on how to get the device ID value, refer to [website](https://android-developers.googleblog.com/2011/03/identifying-app-installations.html)

## Configure

This JS library helps to generate telemetry events. These events sync to the server or data-pipeline in a batch as defined in the configuration. To log telemetry events, the user has to call the start method by passing the configuration along with other parameters.

**Note:** All telemetry events sync only to the server or data-pipeline, when connected to the Internet.

Telemetry events are generated based on the configuration of the telemetry library.

**Required Configuration (Context)**

| Property  | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             | Required | Default Value                                                                                   |
| --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- | ----------------------------------------------------------------------------------------------- |
| pdata     | Producer data. It is an object containing id, version and pid.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          | true     | Defaults to genie ex : {"id": "genie", "ver": "6.5.2567" pid:""}                                |
| channel   | It is an string containing unique channel name.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         | true     | Defaults to in.ekstep                                                                           |
| uid       | It is an string containing user id.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     | true     | defaults to "anonymous"                                                                         |
| did       | <p>It is an string containing unique device id.</p><ul><li>To generate did value for android refer to <a href="https://android-developers.googleblog.com/2011/03/identifying-app-installations.html">here</a> ANDROID\_ID is generally used for mobiles</li><li>To generate did value for web client refer <a href="https://github.com/Valve/fingerprintjs2">here</a>. If consumer is not sending any did value then by default library will generate did using <a href="https://github.com/Valve/fingerprintjs2">fingerPrintJs2</a>.</li><li>For server side it's mandtory to pass did value</li></ul> | true     | Default to [fingerPrintjs2](https://github.com/Valve/fingerprintjs2)(Note: Only for web client) |
| authtoken | It is an string containing consumer token to access the API                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             | true     |                                                                                                 |
| Property  | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             | Required | Default Value                                                                                   |
| env       | It is an string containing Unique environment where the event has occurred                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              | true     | defaults to "ContentPlayer"                                                                     |

**Additional Configuration**

| Property   | Description                                                                                                                       | Required | Default Value                         |
| ---------- | --------------------------------------------------------------------------------------------------------------------------------- | -------- | ------------------------------------- |
| sid        | It is an string containing user session id.                                                                                       | optional |                                       |
| batchsize  | It is an int containing number of events count to sync at a time. Can be configured from min value 10 to max value 1000.          | optional | defaults to 20                        |
| mode       | It is an string which defines to identify preview used by the user to play/edit/preview.                                          | optional | defaults to "play"                    |
| host       | It is an string containing API endpoint host.                                                                                     | optional | defaults to "<https://api.ekstep.in>" |
| endpoint   | It is an string containing API endpoint. Please don't change default value. Update this only when the data is proxied             | optional | Defaults to "/v3/telemetry"           |
| tags       | It is an array. It can be used to tag devices so that summaries/metrics can be derived via specific tags. Helpful during analysis | optional | Defaults to \[]                       |
| cdata      | It is an array. Correlation data. Can be used to correlate multiple events. Generally used to track user flow                     | optional | Defaults to \[]                       |
| dispatcher |                                                                                                                                   |          |                                       |

**Sample:**

```

{
  "pdata": {
    "id": "genie",
    "ver": "6.5.2567",
    "pid": ""
  },

  "env": "ContentPlayer",
  "channel": "XXXX",
  "did": "20d63257084c2dca33f31a8f14d8e94c0d939de4",
  "authtoken": "XXXX",
  "uid": "anonymous",
  "sid": "85e8a2c8-bb8e-4666-a21b-c29ec590d740",
  "batchsize": 20,
  "mode": "play",
  "host": "XXXX",
  "endpoint": "/v3/telemetry",  
  "tags": [],
  "cdata": []
}
```

**Dispatcher:**

User can define custom dispatcher to override the default functionality of telemetry sync. By default telemetry events will send to default server/host. User can override this default functionality by defining his own "dispatcher" object to handle telemetry events.

```

var customDispatcher = {
    dispatch: function(event){
        // User defined logic to send telemetry to server or store locally etc..
    }
};
```

Send this object as dispatcher in the above sample configuration ("dispatcher":customDispatcher).

## How to use telemetry JS library

Download the telemetry-sdk npm module from [here](https://www.npmjs.com/package/@project-sunbird/telemetry-sdk)

```

npm i @project-sunbird/telemetry-sdk
```

**Example:**

```

$t = require('@project-sunbird/telemetry-sdk');   
$t.start(config, contentId, contentVer,data, options);
```

To use the telemetry JS libraries, add the following to your HTML/application. The file path is a relative path, for example; assets/js to the associated files within the html content.

```

<!-- External Libraries -->
  <script src="[relative_path]/jquery.min.js"></script>

  <!-- Telemetry JS library -->
  <script src="[relative_path]/telemetry.min.js"></script>
  <script src="[relative_path]/auth-token-generator.min.js"></script>
  <script>
    function init() {
          // Generate auth token
          // Key: Partner generated key
          // secret: partner secret value 
          let token = AuthTokenGenerate.generate(key, secret);
          config.authToken = token;
          let startEdata = {};
          let options = {};
          $t.start(config, "content_id, "contetn_ver", startEdata, options );
      }
  init()
  </script>
```

## Telemetry API methods

Every API method has an associated event. The following API methods log details of the associated telemetry event.

* [Start](/use/jslibrary#start) - This method initializes capture of telemetric data associated to the start of user action
* [Impression](/use/jslibrary#impression) - This method is used to capture telemetry for user visits to a specific page.
* [Interact](/use/jslibrary#interact) - This method is used to capture user interactions on a page. For example, search, click, preview, move, resize, configure
* [Assess ](/use/jslibrary#access)- This method is used to capture user assessments that happen while playing content.
* [Response](/use/jslibrary#response) - This method is used to capture user responses. For example; response to a poll, calendar event or a question.
* [Interrupt](/use/jslibrary#interrupt) - This method is used to capture interrupts triggered during user activity. For example; mobile app sent to background, call on the mobile, etc.
* [End](/use/jslibrary#end) - This method is used to capture closure after all the activities are completed
* [Feedback](/use/jslibrary#feedback) - This method is used to capture user feedback
* [Share](/use/jslibrary#share) - This method is used to capture everything associated with sharing. For example; Share content, telemetry data, link, file etc.
* [Audit](/use/jslibrary#audit) - This method is used when an object is changed to know previous and current state. This includes lifecycle changes as well.
* [Error](/use/jslibrary#error) - This method is used to capture when users face an error
* [Heartbeat](/use/jslibrary#heartbeat) - This method is used to know is process is running or not.
* [Log](/use/jslibrary#log) - This method is used to capture generic logging of events. For example; capturing logs for API calls, service calls, app updates etc.
* [Search](/use/jslibrary#search) - This method is used to capture the search state i.e. when search is triggered for content, item, assets etc.
* [Metrics](/use/jslibrary#metrics) - Service business metrics (also accessible via health API)
* [Summary](/use/jslibrary#summary) - Summary event
* [Exdata](/use/jslibrary#exdata) - This method is used as a generic wrapper event to capture encrypted or serialized data

### Start

This API is used to log telemetry when users view content or initiate game play

```

start: function(config, contentId, contentVer, data, options) { }
```

Request Arguments:

```

let config = Object; // Telemetry Configurations
let contentId = String; //Required. Id of the content
let contentVer = String; //Required. Version of the content. Defaults to "1.0"
let data = { // Required. event data
    "type": String, //Required.  app, session, editor, player, workflow, assessment
    "mode": "", //Required. mode of preview: preview, edit or play 
    "stageid": "" //Required. stage id where the play has been initiated
};
let options = { // Optional
    context: {}, // To override the existing context
    object: {}, // To override the existing object
    actor: {}, // To override the existing actor
    tags: {}, // To override the existing tags
    runningEnv: "server" // It can be either client or server
};

```

### Impression

This API is used to log telemetry when users visit a specific page.

```

impression: function(data, options) { }
```

Request Arguments:

```


let data = { // Required
    "type": String, //Required. Impression type (list, detail, view, edit, workflow, search)
    "subtype": String, //Optional. Additional subtype. "Paginate", "Scroll"
    "pageid": String, //Required.  Unique page id
    "itype": "", // type of interaction - SWIPE, SCRUB (fast forward using page thumbnails) or AUTO
    "stageto": "" // game level, stage of page id to which the navigation was done
};
```

```

let options = { // Optional
    context: {}, // To override the existing context
    object: {}, // To override the existing object
    actor: {}, // To override the existing actor
    tags: {}, // To override the existing tags
    runningEnv: "server" // It can be either client or server
};
```

### Interact

This API is used to log telemetry of user interactions on the page. For example, search, click, preview, move, resize, configure

```

interact: function(data, options) { }
```

Request Arguments:

```


let data = { // Required
    "type": "", // Required. Type of interaction TOUCH,DRAG,DROP,PINCH,ZOOM,SHAKE,ROTATE,SPEAK,LISTEN,WRITE,DRAW,START,ENDCHOOSE,ACTIVATE,SHOW,HIDE,SCROLL,HEARTBEAT,OTHER
    "subtype": "", // Optional. Additional types for a global type. For ex: for an audio the type is LISTEN and thesubtype can be one of PLAY,PAUSE,STOP,RESUME,END
    "id": "", // Required. Resource (button, screen, page, etc) id on which the interaction happened - use systemidentifiers when reporting device events
    "pageid": "", // Optional. Stage or page id on which the event happened
    "extra": { // Optional. Extra attributes for an interaction
        "pos": [{ "x": , "y": , "z": }], // Array of positional attributes. For ex: Drag and Drop has two positional attributes. One where the drag has started and the drop point
        "values": [], // Array of values, e.g. for timestamp of audio interactions
        "tid": "", // When interaction is between multiple resources, (e.g. drag and drop) - target resource id
        "uri": "" // Unique external resource identifier if any (for recorded voice, image, etc.)
    }
};
```

```

let options = { // Optional
    context: {}, // To override the existing context
    object: {}, // To override the existing object
    actor: {}, // To override the existing actor
    tags: {}, // To override the existing tags
    runningEnv: "server" // It can be either client or server
}; 
```

### Assess

This API is used to log telemetry of assessments that have occured when the user is viewing content

```

assess: function(data, options) { }
```

Request Arguments:

```

let QUESTION = {
    "id": "", // unique assessment question id. its an required property.
    "maxscore", // user defined score to this assessment/question.
    "exlength": , // expected time (decimal number) in seconds that ideally child should take
    "params": [ // Array of parameter tuples
        { "id": "value" } // for ex: if var1 is substituted with 5 apples the parameter is {"var1":"5"}
    ],
    "uri": "", // Unique external resource identifier if any (for recorded voice, image, etc.)
    "desc": "short description",
    "title": "title",
    "mmc": [], // User defined missing micros concepts
    "mc": [] // micro concepts list
}

let data = { //Required
    "item": QUESTION, // Required. Question Data
    "pass": "", // Required. Yes, No. This is case-sensitive. default value: No.
    "score": "", // Required. Evaluated score (Integer or decimal) on answer(between 0 to 1), default is 1 if pass=YES or 0 if pass=NO. 
    "resvalues": [{ "id": "value" }], // Required. Array of key-value pairs that represent child answer (result of this assessment)
    "duration": "" // Required. time taken (decimal number) for this assessment in seconds
};
```

```

 let options = { //Optional
    context: {}, // To override the existing context
    object: {}, // To override the existing object
    actor: {}, // To override the existing actor
    tags: {}, // To override the existing tags
    runningEnv: "server" // It can be either client or server
};
```

### Response

This API is used to log telemetry of user response. For example; Responded to assessments.

```

response: function(data, options) { }
```

Request Arguments:

```

let TARGET = {
    "id": "", // Required. unique id for the target
    "ver": "", // Required. version of the target
    "type": "", // Required. Type of the target
    "parent": {
        "id": "", // Optional. parent id of the object
        "type": "" // Optional. parent type of the object. Required if parentid is present.
    }
};

let data = { // Required
    "target": TARGET, // Required. Target of the response
    "qid": "", // Required. Unique assessment/question id
    "type": "", // Required. Type of response. CHOOSE, DRAG, SELECT, MATCH, INPUT, SPEAK, WRITE
    "values": [{ "key": "value" }] // Required. Array of response tuples. For ex: if lhs option1 is matched with rhs optionN - [{"lhs":"option1"}, {"rhs":"optionN"}]
};
```

```

let options = { // Optional
    context: {}, // To override the existing context
    object: {}, // To override the existing object
    actor: {}, // To override the existing actor
    tags: {}, // To override the existing tags
    runningEnv: "server" // It can be either client or server
};
```

### Interrupt

This API is used to log telemetry for any interruptions that have occurred when a user is viewing content or playing games. For example; screen lock, incoming call, etc.

```

interrupt: function(data, options) { }
```

Request Arguments:

```

let data = { //Required
    "type": "", // Required. Type of interuption
    "pageid": "", // Optional. Current Stage/Page unique id on which interuption occured
    "eventid": "" // Optional. unique event ID
};
```

```

 let options = { // Optional
    context: {}, // To override the existing context
    object: {}, // To override the existing object
    actor: {}, // To override the existing actor
    tags: {}, // To override the existing tags
    runningEnv: "server" // It can be either client or server
};
```

### Feedback

This API is used to log telemetry of feedback provided by the user.

```

// To log content start/play event
feedback: function(data, options) { }
```

Request Arguments:

```

let data = { // Required
    "contentId": "", // Required. Id of the content
    "rating": 3, // Optional. Numeric score (+1 for like, -1 for dislike, or 4.5 stars given in a rating)
    "comments": "User entered feedback" // Optional. Text feedback (if any)
};
```

```

let options = { // Optional
    context: {}, // To override the existing context
    object: {}, // To override the existing object
    actor: {}, // To override the existing actor
    tags: {}, // To override the existing tags
    runningEnv: "server" // It can be either client or server
};
```

### Share

This API is used to log telemetry when a user shares any content with other users.

```

// To log content start/play event
share: function(data, options) { }
```

Request Arguments:

```

let data = { // Required
    "dir": "", // In/Out
    "type": "", // File/Link/Message
    "items": [{ // Required. array of items shared
        "obj": {
            "id": "",
            "type": "",
            "ver": ""
        },
        "params": [
            { "key": "value" }
        ],
        "origin": { // Origin of the share file/link/content
            "id": "", // Origin id
            "type": "" // Origin type
        },
        "to": {
            "id": "",
            "type": ""
        }
    }]
};
```

```

 let options = { // Optional
    context: {}, // To override the existing context
    object: {}, // To override the existing object
    actor: {}, // To override the existing actor
    tags: {}, // To override the existing tags
    runningEnv: "server" // It can be either client or server
};

```

### Audit

This API is used to log telemetry when an object is changed. This includes life-cycle changes as well.

```

audit: function(data, options) { }
```

Request Arguments:

```

let data = { // Required
    "edata": {
        "props": [""], // Updated properties
        "state": "", // Optional. Current state
        "prevstate": "" // Optional. Previous state
    }
};
```

```

  let options = { // Optional
    context: {}, // To override the existing context
    object: {}, // To override the existing object
    actor: {}, // To override the existing actor
    tags: {}, // To override the existing tags
    runningEnv: "server" // It can be either client or server
};
```

### Error

This API is used to log telemetry of any error that has occurred when a user is viewing content or playing games.

```

error: function(error, options) { }
```

Request Arguments:

```

let error = { // Required
    "err": "", // Required. Error code
    "errtype": "", // Required. Error type classification - "SYSTEM", "MOBILEAPP", "CONTENT"
    "stacktrace": "", // Required. Detailed error data/stack trace
};
```

```

 let options = { // Optional
    context: {}, // To override the existing context
    object: {}, // To override the existing object
    actor: {}, // To override the existing actor
    tags: {}, // To override the existing tags
    runningEnv: "server" // It can be either client or server
};
```

### Heartbeat

This API is used to log telemetry for heartbeat event to denote that the process is running.

```

heartbeat: function(data, options) { }
```

Request Arguments:

```

let data = { // Required
    "edata": {}
}
```

```

 let options = { // Optional
    context: {}, // To override the existing context
    object: {}, // To override the existing object
    actor: {}, // To override the existing actor
    tags: {}, // To override the existing tags
    runningEnv: "server" // It can be either client or server
};

```

### Log

This API is used to log telemetry of generic log events. For example; API calls, service calls, app updates, etc.

```

log: function(data, options) { }
```

Request Arguments:

```

let data = { // Required
    "type": "", // Required. Type of log (system, process, api_access, api_call, job, app_update etc)
    "level": "", // Required. Level of the log. TRACE, DEBUG, INFO, WARN, ERROR, FATAL
    "message": "", // Required. Log message
    "params": [{ "key": "value" }] // Optional. Additional params in the log message
};
```

```

let options = { // Optional
    context: {}, // To override the existing context
    object: {}, // To override the existing object
    actor: {}, // To override the existing actor
    tags: {}, // To override the existing tags
    runningEnv: "server" // It can be either client or server
};
```

### Search

This API is used to log telemetry when a user triggers a search for any content, item or asset

```

search: function(data, options) { }
```

Request Arguments:

```

let data = { // Required
    "type": "", // Required. content, assessment, asset 
    "query": "", // Required. Search query string 
    "filters": {}, // Optional. Additional filters
    "sort": {}, // Optional. Additional sort parameters
    "correlationid": "", // Optional. Server generated correlation id (for mobile app's telemetry)
    "size": 333, // Required. Number of search results
    "topn": [{}] // Required. top N (configurable) results with their score
};
```

```

let options = { // Optional
    context: {}, // To override the existing context
    object: {}, // To override the existing object
    actor: {}, // To override the existing actor
    tags: {}, // To override the existing tags
    runningEnv: "server" // It can be either client or server
}; 
```

### Metrics

This API is used to log telemetry for service business metrics (also accessible via health API).

```

metrics: function(data, options) { }
```

Request Arguments:

```

let data = { // Required
    "edata": {
        "metric1": Int,
        "metric2": Int
            /// more metrics, each is a key value
    }
};
```

```

 let options = { // Optional
    context: {}, // To override the existing context
    object: {}, // To override the existing object
    actor: {}, // To override the existing actor
    tags: {}, // To override the existing tags
    runningEnv: "server" // It can be either client or server
};
```

### Summary

This API is used to log telemetry summary event

```

summary: function(data, options) { }
```

Request Arguments:

```

let data = { // Required
    "edata": {
        "type": "", // Required. Type of summary. Free text. "session", "app", "tool" etc
        "mode": "", // Optional.
        "starttime": Long, // Required. Epoch Timestamp of app start. Retrieved from first event.
        "endtime": Long, // Required. Epoch Timestamp of app end. Retrieved from last event.
        "timespent": Double, // Required. Total time spent by visitor on app in seconds excluding idle time.
        "pageviews": Long, // Required. Total page views per session(count of CP_IMPRESSION)
        "interactions": Long, // Required. Count of interact events
        "envsummary": [{ // Optional
            "env": String, // High level env within the app (content, domain, resources, community)
            "timespent": Double, // Time spent per env
            "visits": Long // count of times the environment has been visited
        }],
        "eventssummary": [{ // Optional
            "id": String, // event id such as CE_START, CE_END, CP_INTERACT etc.
            "count": Long // Count of events.
        }],
        "pagesummary": [{ // Optional
            "id": String, // Page id
            "type": String, // type of page - view/edit
            "env": String, // env of page
            "timespent": Double, // Time taken per page
            "visits": Long // Number of times each page was visited
        }]
    }
};
```

```

  let options = { // Optional
    context: {}, // To override the existing context
    object: {}, // To override the existing object
    actor: {}, // To override the existing actor
    tags: {}, // To override the existing tags
    runningEnv: "server" // It can be either client or server
};
```

### Exdata

This API is used to log telemetry for external data, while playing content

```

exdata: function(data, options) { }
```

Request Arguments:

```

let data = {
    "type":"" - Free flowing text.For ex: partnerdata,xapi etc
   ....Serialized data(can be either encrypted / encoded / stringified)

};
```

```

  let options = { // Optional
    context: {}, // To override the existing context
    object: {}, // To override the existing object
    actor: {}, // To override the existing actor
    tags: {}, // To override the existing tags
    runningEnv: "server" // It can be either client or server
};
```

### End

This API is used to log telemetry while the user is closing or exiting the content or game

```

end: function(data, options) { }
```

Request Arguments:

```

let data = { // Required
    "contentId": "", // Required. Id of the content
    "type": "", // Required. app, session, editor, player, workflow, assessment
    "duration": "", // Required. Total duration from start to end in seconds
    "pageid": "", // Optional. Page/Stage id where the end has happened.
    "summary": [{ "key": "value" }] // Optional. Summary of actions done between start and end. For ex: "progress" for player session, "nodesModified" for collection editor
};
```

```

  let options = { // Optional
    context: {}, // To override the existing context
    object: {}, // To override the existing object
    actor: {}, // To override the existing actor
    tags: {}, // To override the existing tags
    runningEnv: "server" // It can be either client or server
};
```

### ResetContext

This is used to reset the current context value with new context object.

```

 @param {context} Object    - If context is undefined then library is reset to previous event context value.
 $t.resetContext(context) 
```

### ResetObject

Which is used reset the current object value with new obj

```

 @param {obj} Object      - If the Object is undefined then library is reset to previous event object value.
 $t.resetObject(obj) 
```

### ResetActor

Which is used reset the current actor value with new actor

```

 @param {actor} Object    - If the actor is undefined then library is reset to previous event actor value.
 $t.resetActor(actor) 
```

### ResetTags

Which is used to reset the current tag's value with new tag's

```

 @param {tags} Array      - If tags are undefined then library is reset to previous event tags value.
 $t.resetTags(tags) 
```

## ChangeLog

**Jan 2018**

* For the `start` event, Changed the both `contentId` and `contentVer` to an optional parameters from mandtory.
* Decoupling of the both init and start methods.
* Introduced new initialize method, Where user can initialize the telemetry without calling `start` event. [More details](/use/jslibrary#initialize)
* Introduced new context parameter in all telemetry event methods, Where user can easily update the context value for each event.
* Introduced `resetContext` method, Which is used to reset the context to new context value/global context. [More details](/use/jslibrary#resetcontext)
* Introduced `resetObject` method, Which is used to reset the current object value. [More details](/use/jslibrary#resetobject)
* Introduced `resetTags` method, Which is used to reset the current tags value. [More details](/use/jslibrary#resettags)
* Introduced `resetActor` method, Which is used to reset the current actor value. [More details](/use/jslibrary#resetactor)
* Previously if the user invokes an end event then the user must and should invoke start event to initialize the telemetry. but in the updated on no need to invoke start event because telemetry is initialized globally.
* Bug fixes


# html\_interface\_library

## Need

The HTML interface library eases the HTML developer’s effort to log telemetry events from HTML content. It uses simple API methods exposed by the library to log associated events. The reasons to develop the HTML interface library are:

* Any HTML content can package the interface library as part of the content. Thus using the library, the HTML content can log telemetry events.
* There are simple API methods to generate the complete telemetry event as only the required fields are passed
* It is easy to upgrade to new versions, in case of major changes in the telemetry library
* There is effortless backward compatibility, as changes are handled within the telemetry library. Any upgrade of the telemetry library does not require code changes in the content
* The library will handle logging of events from HTML content when it is playing in case portal or device/app.

## How to use HTML interface library

Add the following to your HTML Content:

The file\_path is the relative path (eg. assets/js) to these files within the html content.

```

<!-- HTML Interface  JS library -->
<script src="[relative_path]/htmlinterface.js"></script>

//you can log telemetry interact event as shown below
org.ekstep.contentrenderer.interface.telemetryService.interact(data) 
//or 
RI.telemetryService.interact(data)
```

## API methods

The HTML interface provides simple methods to log telemetry, to handle the ContentRenderer overlay, to get content information, etc.

The HTML interface exposes the following list of API methods:

* [dispatchEvent](/use/html_interface_library#dispatchevent) - This method helps dispatch events to the ContentRenderer to handle specific functionality of ContentRenderer
* [getcontentMetadata](/use/html_interface_library#getcontentmetadata) - This method is used to access content metadata
* [getConfig](/use/html_interface_library#getconfig) - This method is used to access content-renderer configuration
* [gotoEndPage](/use/html_interface_library#gotoendpage) - This method helps to open the ContentRenderer end page after HTML content is completely viewed
* [exit](/use/html_interface_library#exit) - This method helps to close the ContentRenderer
* [telemetryService.interact](/use/html_interface_library#telemetry-interact)- This method helps to log telemetry interact event
* [telemetryService.impression](/use/html_interface_library#telemetry-impression) - This method helps to log the Impression event on page or state change
* [telemetryService.response](/use/html_interface_library#telemetry-response) - This method helps to log telemetry response event when an option is selected during an assessment
* [telemetryService.assessmentStart](/use/html_interface_library#telemetry-assessmentstart) - This method is used when an assessment begins and it returns the event object
* [telemetryService.assess](/use/html_interface_library#telemetry-assess) - This method helps to log the Assess event when the assessment is evaluated
* [telemetryService.exdata](/use/html_interface_library#telemetry-exdata) - This method helps log the telemetry ExData event

### DispatchEvent

Dispatch an specific event to control ContentRenderer functionalities.

```

/**
  * eventName - Event name that has to dispatch to handle ContentRenderer functionality
  */
dispatchEvent: function(eventName) {
  // dispatch event to control ContentRenderer functionalities
}
```

### getcontentMetadata

This will return the content metadata information(HTML Cotnent metadata here).

```

/**
  * contentId - Current opened HTML content identifier
  * cb - callback function after after getting content iformation from API call
  */
getcontentMetadata = function(contentId, cb){
}
```

### getConfig

This will return the content renderer configuration. This will help to know what is the context of HTML content playing in ContentRenderer.

```

getConfig = function(){
}
```

### gotoEndPage

After completion of HTML content, you can call this function to show ContentRenderer end-page. This will take the user out of HTML content view.

```

gotoEndPage = function(){
}
```

### exit

If you want to close the HTML game & contentRenderer to take user back to app, you can call this function.

```

exit= function(){
}
```

### Telemetry Interact

Api method to log telemetry interact events. Any interact events in HTML can log using this API method.

```

/**
 * Interface to log temetry interact(INTERACT) event
 * data - {Object} Telemetry event data
 */
interact: function(data){
  _telemetryService.interact(data.type, data.id, data.extype, data.eks);
}
```

### Telemetry Response

Api method to log telemetry response events. When an assessment is playing in content, on selection of option/answer data can be passed by calling this function.

```

/**
 * Interface to log telemetry response(RESPONSE) event
 * data - {Object} Telemetry event data
 */
response: function(data){
    _telemetryService.interact(data.type, data.id, data.extype, data.eks);
}
```

### Telemetry assessmentStart

Api method to get assessment start event data. This event object should be passed as a parameter while calling telemetry assess api method.

```

/**
 * Interface to get assess start event
 * data - {Object} Telemetry event data
 */
assessmentStart: function(data){
    _telemetryService.assess(data.qid, data.subj, data.qlevel, data.data);
}
```

### Telemetry Assess

Api method to log telemetry assess event. After submitting/validating the result of assessment question, call this funciton to log assessment result data.

```

/**
 * Interface to log telemetry assess(ASSESS) event
 * event - {Object} telemetry event object returned after calling assessmentStart() API method
 * data - {Object} Telemetry event data
 */
assess: function(event, data){
    _telemetryService.assessEnd(event, data);
}
```

### Telemetry Impression

Api method to log telemtry impression event. When there is a state/page change, call this method to log impression event

```

/**
 * Interface to log telemetry impression(IMPRESSION)  event
 * data - {Object} Telemetry event data
 */
impression: function(data){
    _telemetryService.impression(data.stageid, data.stageto, data.data);
}
```

### Telemetry Exdata

Api method to log telemtry exdata events. Any additional information of can be passed by calling this function.

```

/**
 * Interface to log telemetry Exdata(EXDATA) event
 * data - {Object} Telemetry event data
 */
exdata: function(data){
   _telemetryService.xapi(data);
},
```


# authtokengenerator\_jslibrary

## Methods

The following API methods are provided by the AuthToken generator library

### Generate new AuthToken

```

generate: function(key, secret){}
```

Request Arguments:

```

key- "key" of the JWT Credential For ex: '398e54e888da42f8d089je28c298o42b'
secret- "secret" of the JWT Credential For ex: '07c6e2t1rb92987fnrd705jkk8582p9e'
```

### Regenerate Expired AuthToken

```

refresh: function(oldAuthToken) { }
```

### Generate JWT With Bash

Authtoken can be generated using the bash script also, for more details refer <https://willhaley.com/blog/generate-jwt-with-bash/>

## How to generate authorization credentials

This section details the procedure to generate the AuthToken and secret key that is required to access any APIs and to configure the standalone telemetry JS library.

### Process

![](/files/-MkM8nDCJs23mASphEql)

### Prerequisites

* Access to the Ekstep Community portal

### Procedure

| Step                                                                                                                                                                                                                                                                                                                                                                                                                         | Screen                           |
| ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------- |
| <p><strong>Sign In</strong><br>1. Sign in to Ekstep QA portal (<https://qa.ekstep.in>)<br>2. Go to Resources > Developers<br> <strong>Note:</strong> If you have already created QA credentials and tested Sunbird, and are looking at acquiring production credentials, repeat the same steps on visit <a href="https://community.ekstep.in/api-credentials"><https://community.ekstep.in/api-credentials></a> instead.</p> | ![](/files/-MkM8nDDRwo-9xjRVwDe) |
| <p><strong>Request API Access</strong><br>1. Select <strong>API credentials</strong><br>2. The <strong>Manage Credentials</strong> page is displayed<br>3. Click <strong>Request API access</strong> to request access for available API groups</p>                                                                                                                                                                          | ![](/files/-MkM8nDEx0UPoTGuB3ab) |
| <p>On successful submission of the API access request, the portal admin is notified. The admin either approves or rejects the request</p><p> You are notified of the admin’s action through a mail to your registered mail ID</p><p>You can also view the action taken, by clicking the notification icon on the portal</p>                                                                                                  | ![](/files/-MkM8nDFsF181_JPUHWr) |
| <p><strong>Generate New Credentials</strong><br>1. Enter the username<br>2. Enter notes, if any<br>3. The API groups that can be accessed with the created credentials are listed here<br>4. Click <strong>Generate credentials</strong> to generate key and secret</p>                                                                                                                                                      | ![](/files/-MkM8nDGYo5cAeo5F8Nw) |
| <p><strong>Note the Credentials</strong><br>1. Ensure to copy the key and secret and confirm the same<br>2. Click <strong>Close</strong> after copying the Key and Secret</p>                                                                                                                                                                                                                                                | ![](/files/-MkM8nDHT5ctrNPpJs43) |


# sending\_telemetry

## Prerequisites

The following are the prerequisites for sending telemetry:

### Authtoken

Authtoken is required to access any APIs. See [AuthToken generator JS](/use/authtokengenerator_jslibrary) to understand the process to generate authorization credentials.

### Channel Id

### API key

Sunbird implementors currently need to get a API key for accessing EkStep platform. Currently all the contents are stored here.

When you are initially trying out the Sunbird, please request the keys from the EkStep QA environment. For requesting the keys see [Procedure](/use/authtokengenerator_jslibrary#procedure) section and to follow the steps for getting secret key.

## Telemetry Helpers

The following telemetry helpers gives much insights about capturing and collecting the telemetry data.

### Standalone JS Library

The standalone telemetry JS library allows users to capture telemetry data without the restrictions of using any app that uses the Genie SDK, the EkStep content player or the EkStep or Sunbird portal. Partner users can use the JS library to log and sync telemetry data. They can decide how to use the Telemetry JS library, and integrate it with their app, webpage or web service

When using the standalone telemetry JS library, you can capture and sync telemetry data only when you are connected to the Internet.

There is no storage within the library. To capture offline telemetry data, users need to decide where the data will be stored and how it will sync with the servers when their app gets connected online. [Standalone JS Library](/use/jslibrary) section will help you in understanding better how JS library serves the purpose of capturing telemetry data.

### HTML Interface Library

The ContentRenderer handles telemetry events for ECML content. HTML content has functionality such as click, navigation, assessment, etc. These functionalities are specific to or different for individual HTML content pieces. For HTML Content, the ContentRenderer logs only the telemetry start event. It does not log telemetry for any other event. By embedding the HTML interface library within the HTML content helps log telemetry events for the actions that take place in the HTML content.

[HTML Interface Library](/use/html_interface_library) details information about the library used to log telemetry events for HTML content.

### AuthToken Generator JS

The AuthToken generator JS library is used to generate or refresh the user AuthToken. The Authtoken is mandatory for any API request. The AuthToken is passed as part of configuration to the telemetry JS library. [AuthToken Generator JS Library](/use/authtokengenerator_jslibrary) details method and process of generating key and tokens.


# consuming\_telemetry

## Telemetry Exhaust APIs

The Sunbird telemetry services are made available through a daily exhaust, supported by Ekstep infra from multiple channels. It is common that, these channels will not have the data pipeline to process the telemetry data. Hence, telemetry are made available to channels.

Steps involved in consuming Data Exhaust:

1. \[Automated] A User need to register using [Register User API](https://github.com/ekstep/Common-Design/wiki/Data-Exhaust-API-Specification#data-exhaust-register-user-api){:target="\_blank"}. This API returns a license key, which needs to be used when requesting telemetry data. This creates an entry for the user in `data_exhaust_users` table.&#x20;
2. \[Manual] Access needs to be granted, manually, to this user to the dataset resource that they want to consume. This access is granted by making an entry, for corresponding user and resource, in `data_exhaust_users_resources` table.
3. \[Automated] User can then use [Datasets API](https://github.com/ekstep/Common-Design/wiki/Data-Exhaust-API-Specification#data-exhaust-dataset-api){:target="\_blank"} to download telemetry data. User has to pass the license key, got in Step 1, for authentication. Internally, Datasets API will invoke [Authentication API](https://github.com/ekstep/Common-Design/wiki/Data-Exhaust-API-Specification#data-exhaust-authenticate-api){:target="\_blank"} and [Authorisation API](https://github.com/ekstep/Common-Design/wiki/Data-Exhaust-API-Specification#data-exhaust-authorize-api){:target="\_blank"} to check if the user has is valid and has access to the requested resource, if the checks pass, dataset is returned.

`Note`: Database schema of Data Exhaust is described [here](https://github.com/ekstep/Common-Design/wiki/TDD-DataSets#database-schema-changes){:target="\_blank"}.

#### Using channel ID and API key to request channel telemetry

## Standard Telemetry Workflows

This section details **Standard Telemetry Workflows** for different access channels.

### Mobile App Workflow

```
        START(type: "app")
            ...| --> app events such as IMPRESSION, FEEDBACK, etc may happen
            START(type: "session")
                ...
                | --> IMPRESSION - For the pages that the user visits
                | --> INTERACT --> one of the content is clicked
                    | --> START(type: "player") --> events generated by specific content
                        ...|
                        ...| --> in-content events such as ASSESS, INTERACT, IMPRESSION, LEVEL_SET etc.
                        ...|
                    | --> END(type: "player")
                | --> IMPRESSION - Returned back to mobile app for content player
                ...| --> app events such as IMPRESSION, INTERACT, etc. may happen
                | --> INTERACT --> one of the content is clicked
                    | --> START(type: "player") --> events generated by specific content
                        ...|
                        ...| --> in-content events such as ASSESS, INTERACT, IMPRESSION, LEVEL_SET etc.
                        ...|
                    | --> END(type: "player")
                | --> IMPRESSION - Returned back to mobile app for content player
                ...| --> app events such as IMPRESSION, INTERACT, etc. may happen
            END(type: "session")
            ...| --> app events such as APP_UPDATE, FEEDBACK, etc may happen
        END(type: "app")
```

### Web Portal Workflow

```
        AUDIT (object: user) --> (Optional if a user is created for the first time)
        START(type: "session") --> User session starts
            ...
            | --> IMPRESSION - For the pages that the user visits
            | --> INTERACT - For the interactions on the page
            // there is no explicit logout/timeout
```

### Content Editor Workflow

```
        START (type: "session") - User logs in
            ...
            | --> IMPRESSION (Portal) - User visits content creation page (cdata session)
            | --> INTERACT (Portal) - User initiates content creation
            | --> AUDIT (Platform) - User creates a new content
            | --> START (type: "editor", mode: "content")
                ...
                | --> INTERACT (Editor) - In editor, user is loading the asset browser
                | --> SEARCH (Platform) - In AT, user is searching for assets (cdata session, search result id)
                | --> PLUGIN_LIFECYCLE (Editor) - User selects the asset for content (which search result was used)
                | --> PLUGIN_LIFECYCLE (Editor) - User removes the asset from content
                | --> INTERACT (Editor) - User clicks save in AT
                | --> ACCESS (Platform) - Platform save API is called
                | --> INTERACT (Editor) - User clicks on submit to review
                | --> AUDIT (object: Content, state: "Review", prevstate: "Draft") - Platform sends the content to review state
            | --> END (type: "editor", mode: "content") - User closes the editor and goes back to portal
```

### Backend-services Workflow

```
            AUDIT (object: Service, state: "Ready") --> State transition to READY
            ...| --> ACCESS events for API requests
            ACCESS
                LOG --> Log events in the context of the incoming request (by request correlation ID)
                ...
            METRICS --> Health/business metrics (e.g. number of jobs executed)
            AUDIT (object: Service, state: "Stopped") --> State transition to STOPPED
```

### DIAL Code Consumption Workflow

```
            AUDIT (object: Service, state: "Ready") --> State transition to READY
            ...| --> ACCESS events for API requests
            ACCESS
                LOG --> Log events in the context of the incoming request (by request correlation ID)
            --> SEARCH (Platform) - In AT, user is searching for assets (cdata session, search result id)
                ...
            SCAN --> Health/business metrics (e.g. number of jobs executed)
            | --> INTERACT --> one of the content is clicked
                    | --> START(type: "player") --> events generated by specific content
                        ...|
                        ...| --> in-content events such as ASSESS, INTERACT, IMPRESSION, LEVEL_SET etc.
                        ...|
            AUDIT (object: Service, state: "Stopped") --> State transition to STOPPED
```


