# Overview

## ***What is Sunbird inQuiry?***

Sunbird inQuiry is a software building block that enables setting up of question banks for various use cases such as assessments, quizzes, practice worksheets, surveys, and many more. These are applicable in multiple domains related to education and human development.&#x20;

Here are some examples of solutions that can be enabled through Sunbird inQuiry:

* Conduct assessments which can evaluate users’ understanding of concepts and issue certificates based on assessment score.&#x20;
* Evaluate assessment data to take informed decisions and plan for interventions.&#x20;
* Launch surveys to collect feedback and analyse responses.&#x20;

Further, Sunbird inQuiry can be extended for use cases like adaptive tests, gamified quizzes, rubric-driven assessments, competitions, etc.

## ***What does Sunbird inQuiry offer?***

\
This building block consists of pluggable tools and microservices that enable creation of questions and question sets (collection of questions), configuration of their behaviour, curation and publishing them for users to play on any device.&#x20;

Key capabilities offered by Sunbird inQuiry are:&#x20;

* **Question banks:** Reuse and organize question(s) into question sets. Question(s) are tagged to rich metadata and created as per the interoperable[ QuML spec](https://quml.sunbird.org/).
* **Authoring and Publishing:** Enable question(s) and question set(s) creation, curation and publish workflows using the pluggable editor and microservice ; and/or bulk import existing questions through APIs.
* **Diverse question types:** inQuiry comes with two pre-built question types - Multiple choice questions (MCQ) and subjective questions. It can be extended to build new question types, basis your needs.
* **Engaging & inclusive experiences:** Configure features like randomizing questions, timer, hints, etc using a pluggable player to enable various use cases. Player is built as per the WCAG AA guidelines which enables you to reach more learners.&#x20;
* **Observability:** Make meaning of the user's actions and derive insights by leveraging telemetry data e.g. user response, result, and summary data. &#x20;

## ***Where has Sunbird inQuiry been used?***&#x20;

Sunbird inQuiry is leveraged in DIKSHA - Digital Infrastructure for Knowledge Sharing, the national school education platform of India. &#x20;

***Contributors:*** EkStep, Samagra & Shikshalokam

***Last release date & version:*** 01-Mar-2022, 4.7.0

**A short video on the overview of inQuiry**

{% embed url="<https://youtu.be/vl18Fpl--z0>" %}

## &#x20;<a href="#last-release-date" id="last-release-date"></a>


# Capabilities

inQuiry capabilities can power a variety of use-cases. A few examples are shown below:

![inQuiry - Example Use Cases](https://3506001968-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FWu4HIWGkb7dD4y0Kup4W%2Fuploads%2FxsAVtNGdJQBQ5PYWQXl8%2FScreen%20Shot%202022-03-21%20at%204.37.26%20PM.png?alt=media\&token=d41d8520-db0d-4bb4-8355-ccb12cf476bb)

### a) Question banks:

Inquiry enables users to create, reuse and organize question(s) into question sets

* Questions are created as per the interoperable [QuML](https://quml.sunbird.org/#quml-specification) spec. QuML spec provides a standard content format for storing and exchanging questions, independent of the author and authoring tool and hence ensures reusability, longevity and platform independence.
* Questions are tagged to rich metadata and associated with relevant concepts enabling multiple use cases of questions. For eg : For a student attempting questions for learning, if the questions focus on micro-concept level assessment of student’s proficiency, it is possible to identify strengths, areas that need focus & improvement, and recommend the relevant content to the student that specifically address the individual learning needs.

<figure><img src="https://3506001968-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FWu4HIWGkb7dD4y0Kup4W%2Fuploads%2FumAwJSVTPIJLWTJ3ajqP%2FScreenshot%202022-12-12%20at%208.22.44%20PM.png?alt=media&amp;token=c296c07d-8985-427a-a54c-edb7c2f8894c" alt=""><figcaption></figcaption></figure>

### b) Authoring and Publishing :

Enables question(s) and questions set(s) creation, curation and publishing

* Question(s) can be created using the pluggable editor and/or can be bulk imported through APIs.
* Questions set(s) (which is a collection of questions) can be created using the question set editor, and can be configured for the required behaviour. For eg, if the question set is curated for conducting a test, the solutions should not be displayed to the user who is playing with it. Whereas, for a student using the question set to practice for a topic, it can be configured to show hints, or show solution and get feedback as and when they respond.
* Question set can be curated by creating new questions or by reusing questions from the questions bank.
* The question(s) and question set(s) go through a review workflow, where once the creator saves the updates, it is sent for review and a reviewer has the capability to either accept and publish the question(s) or question set(s), or reject the them. Only the published ones will be available for consumption.

### c) **Diverse question types:**&#x20;

* inQuiry comes with two pre-built question types - Multiple choice questions (MCQ) and subjective questions. It can be extended to build new question types, based on your needs.

  For example, True or False questions, Match the following questions, Fill in the blanks questions etc.
* It allows you to create questions with rich media, scientific formulae and math equations.
* It gives flexibility for creators to choose different layouts for rendering questions.

### **d) Engaging & inclusive experiences:**&#x20;

* The editor features are driven using a dynamic reactive form.&#x20;
* inQuiry allows creators to configure behavioural features and create different workflow for the end user who plays with the question(s) or question set(s).

&#x20;     There are a wide range of behaviours that can be enabled through inQuiry

<figure><img src="https://3506001968-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FWu4HIWGkb7dD4y0Kup4W%2Fuploads%2F7Py2nmTumawEchNbw5K2%2FScreenshot%202022-12-09%20at%2010.55.15%20AM.png?alt=media&amp;token=ec4d9939-52de-43ed-b628-e7df9abc2cd7" alt=""><figcaption><p>inQuiry - Example of configurable behaviours</p></figcaption></figure>

* The pluggable player in inQuiry is built as per the WCAG AA guidelines which enables you to reach more learners.&#x20;

### **e) Observability:**

Every single user interaction is instrumented as per the Sunbird telemetry spec. Therefore, enabling you to use this granular data to create custom reports to turn user actions into insights. Here are the events specific to inQuiry:

* START - The start of a question/question set session.
* INTERACT - Captures the user interactions
* IMPRESSION - Captures the page change event
* ERROR - Captures the error that occurred during the content play
* ASSESS - capture score and assessment data.
* RESPONSE - capture user responses.
* SUMMARY - It used to log telemetry summary event
* END - end of a question/question set session.

Click [here](https://telemetry.sunbird.org) to know more about Sunbird telemetry spec.

Click [`here`](/learn/product-and-developer-guide/analytics) to check sample telemetry events

### **Additional Information**

Below recording from one of the Sunbird webinars provides more information about the capabilities enabled by inQuiry, the QuML spec, and the technical architecture.

{% embed url="<https://www.youtube.com/watch?t=1068s&v=xgvZUfYrxmQ>" %}


# Components

In this section, we will cover in a little detail about each of the key components of the inQuiry building block.

### **a) Question Set Editor**

Question set editor is a tool offered by inQuiry to help you kickstart your creation of **Question Banks**. The key capabilities of this editor are:

* Extendible, Embeddable and Configurable:
  * Configuration driven: The editor features are driven using a form and not hardcoded to the tool. This allows you to unleash different capabilities for different end-user workflows using the same editor.
  * It is built using an angular tech stack and can be installed and used in any portal built using angular. It can also be extended to build native integrations with JS and React frameworks.
  * It is built using a plug-in architecture thereby enabling ease of extending the code to build new capabilities.
* Create new questions or reuse already live questions to stitch a question set with proper metadata tagging.
* Ability to create question sets with multiple sections.
* Ability to define the consumption behaviour of the question set. For example:- show hints, solution, set timer, etc.
* Ability to preview question set to replicate the actual user experience before publishing it.
* In-built curation workflows to ensure that all questions are reviewed before they are made Live.

### **b) Question Editor**

Question editor enables you to create **diverse question types:**

* The inQuiry comes with two pre-built question types:
  * **Multiple choice questions** which are \*\*\*\* interactive type of question(s).

![Multiple choice question](https://3506001968-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FWu4HIWGkb7dD4y0Kup4W%2Fuploads%2FyVe3fZp86YPkdWE4en2o%2FMCQ-Question.png?alt=media\&token=5335db2c-8663-4a07-bc1d-4082ca0e46cb)

* **Subjective questions** which are non-interactive type of question(s) with pre-populated question & answers.

![Subjective question](https://3506001968-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FWu4HIWGkb7dD4y0Kup4W%2Fuploads%2FWQiOPU9KkpGFz8HoiJ49%2FSubjective-Question.png?alt=media\&token=30b34cd8-29dd-46d7-984f-98058f443e87)

* Allows you to create questions with rich media, scientific formulae, math equations amongst others with proper metadata tagging.

![](https://3506001968-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FWu4HIWGkb7dD4y0Kup4W%2Fuploads%2FTXQmqO3Terr1NcB8fum9%2Fimage.png?alt=media\&token=bfaebe50-e4d7-4a0c-b994-5ab44cc13352)

### ![](https://3506001968-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FWu4HIWGkb7dD4y0Kup4W%2Fuploads%2FaByAQaz0ABe6rfgQpfbF%2Fimage.png?alt=media\&token=e6a37a63-ed17-4f49-9e9f-aea5bbc0758c)

### **c) Question & Question Set services**

It enables the question(s) and question set(s) **publishing process**. These are microservices that allow you to: \*\*\*\*

* Create, copy, collaborate, curate & publish question(s) and question set(s).
* Easily scale as per your needs.

### **d) Question Set Player (QuML player)**

Question set player is a player provided by inQuiry to create **engaging & inclusive experiences** for end users consuming the question sets. The key capabilities of this player are:

* Extendible, Embeddable, and Configurable:
  * It is built using plug-in based architecture thereby enabling you to extend and build new capabilities with ease.
  * Configuration driven: This allows you to configure the player with different capabilities for different workflows.
  * It can be plugged into any hybrid mobile app or can be played in web view. Can be extended to build native integrations with JS and React frameworks.
* Inclusive:
  * Built as per the WCAG AA recommendations allowing you to reach a wider audience from day 1.
* Offline & Online:
  * Built to support both online and offline modes of consumption.
* Enables a variety of solutions:
  * Allows you to use question sets for different use cases. For example:- the user experience for practice worksheets can be configured to show feedback, hints for each question. However, a high stake assessment can be configured to have a completely different consumption behaviour with randomization of questions, a limited number of attempts, and a completion timer.
* Responsive to different resolutions and orientations.

**A short video on the components of inQuiry**

{% embed url="<https://youtu.be/8j1gr3LzlS8>" %}

***


# Technical Architecture

Sunbird inQuiry building block enables the creation and consumption of the Question & Question set objects.&#x20;

The creation apps calls Question& Question Set service to create, update & publish the Question & Question Sets and consumption apps use the same service for rendering Question Sets.

![](https://3506001968-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FWu4HIWGkb7dD4y0Kup4W%2Fuploads%2Fmdne7aEl7RvHwjM0j9tO%2Finquiry.png?alt=media\&token=21a8b19d-2552-4458-9199-5dfa7df2783e)


# Product & Developer Guide

The components of inQuiry building block that enable the key capabilities outlined in the [overview](/) and [capabilities](/learn/capabilities) pages are:

{% content-ref url="/pages/il77BtGtgsHV6rZq27pC" %}
[Question & Question Set Editor](/learn/product-and-developer-guide/question-and-question-set-editor)
{% endcontent-ref %}

{% content-ref url="/pages/a08GrkIEAc7bZdr1ZhaM" %}
[Question & Question Set Service](/learn/product-and-developer-guide/question-and-question-set-service)
{% endcontent-ref %}

{% content-ref url="/pages/8RANM2CsmRErem3hSIFp" %}
[Question Set Player](/learn/product-and-developer-guide/question-set-player)
{% endcontent-ref %}

{% content-ref url="/pages/31BK8S3jUZnw4GfGcyXB" %}
[Analytics](/learn/product-and-developer-guide/analytics)
{% endcontent-ref %}

In the subsequent pages you will find detailed functional and technical documentation about these components.&#x20;


# Quick Starter Guide

This is a quick guide page to explore on the capabilities of inQuiry.&#x20;

The following section explains about the components of inQuiry on a high level and references to the respective areas of this microsite.

InQuiry has 3 components as stated below,

* Question & Question Set Editor (QuML Editor)
* Question Set Player (QuML Player)
* Question & Question Set Service (Micro-service)

The specification that enables all these 3 components work in tandem is a standard called [QuML](https://quml.sunbird.org/) (Question Markup Language)

## inQuiry components

The section below gives a high level overview of how the inQuiry components functions together. More details [here](/learn/technical-architecture).

<figure><img src="https://files.gitbook.com/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FWu4HIWGkb7dD4y0Kup4W%2Fuploads%2Fmdne7aEl7RvHwjM0j9tO%2Finquiry.png?alt=media&#x26;token=21a8b19d-2552-4458-9199-5dfa7df2783e" alt=""><figcaption></figcaption></figure>

{% embed url="<https://youtu.be/mjV0MmP9WuQ?si=SpE9q8f7j5r2htmD&t=103>" %}

## What is QuML?

QuML defines a standard format for representation of questions, tests and their results, supporting the exchange of this material between authoring and delivery systems, repositories and other e-learning systems.

More details on QuML is available [here](https://quml.sunbird.org/).

QuML is a specification for storage, rendering and distribution of Questions and QuestionSets.

Key advantages are,

* Interoperability
* Longevity
* Reusability

{% embed url="<https://youtu.be/mjV0MmP9WuQ?si=qQ4j446PZoZue14V&t=1042>" %}

## Different types of questions supported

As part of the standard offering, inQuiry supports the below questions out of the box

* Multiple Choice Question
* Multi-select Multiple Choice Question
* Subjective Question

The service layer is capable for creating a variety of different question types adhering to the QuML specification.&#x20;

Examples of adopter implementation of question types are as follow,

* Fill In The Blanks
* Date
* Slider
* etc.

## Technology stack used in inQuiry Components

Editor is build using: Angular / HTML5 / CSS

Player is build using: Angular / HTML5 / CSS

Service is build using: Play Framework / Scala


# inQuiry Components

This section captures information on the internal details about the inQuiry Service component.

### Component Architecture Diagram

<figure><img src="https://3506001968-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FWu4HIWGkb7dD4y0Kup4W%2Fuploads%2F7m4ujO5mDhB6QJmxJqhN%2Fimage.png?alt=media&amp;token=586186d4-2cb7-41df-8a39-d8ad8969c818" alt=""><figcaption></figcaption></figure>

<details>

<summary>Component Architecture Explained</summary>

* The core components of inQuiry are QuML Editor, QuML player and inQuiry Service.
* QuML Editor, Player and inQuiry Service all implements the QuML specification for creating and maintaining Questions and QuestionSets.
* QuML Editor uses the Knowlg BB services as explained [here](https://app.gitbook.com/o/-Mi9QwJlsfb7xuxTBc0J/s/Wu4HIWGkb7dD4y0Kup4W/~/changes/294/learn/product-and-developer-guide/question-and-question-set-editor/apis#knowlg-service)
* inQuiry Service also uses the Knowlg core services for inprocess communication to the underlying data stores.
* inQuiry uses Telemetry services for sending the telemetry events
* There are a few common sunbird libraries that both QuML Editor and QuML player uses

</details>

{% embed url="<https://youtu.be/mjV0MmP9WuQ?si=M7t7v9AdIF0sCUL8&t=583>" %}

### Brief Description

Sunbird inQuiry is used to power the assessment capabilities in Sunbird. This uses an open specification called as QuML for preparing the questions and question sets.

#### Components

* [Editor](/learn/product-and-developer-guide/quick-starter-guide/inquiry-components/editor)
* [Player](/learn/product-and-developer-guide/quick-starter-guide/inquiry-components/player)
* [inQuiry Service](/learn/product-and-developer-guide/quick-starter-guide/inquiry-components/inquiry-service)


# Editor

Sunbird [inQuiry Editor](/learn/product-and-developer-guide/question-and-question-set-editor/architecture) is used for creating questions and questionSets. The current Editor supports the following question types.&#x20;

This Editor is also known as Question & Question Set Editor or QuML Editor.

* Multiple Choice Question (MCQ)
* Multi-select Multiple Choice Question (MMCQ)
* Subjective Question (SA)

## Question & Question Set Editor (QuML Editor)

Question set editor is a tool offered by inQuiry to help you kickstart your creation of Question Banks.

More details on the editor can be found [here](/learn/capabilities-1#a-question-set-editor) and [here](/learn/product-and-developer-guide/question-and-question-set-editor).

Editor architecture is as below,

<figure><img src="https://3506001968-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FWu4HIWGkb7dD4y0Kup4W%2Fuploads%2FsPea2P02APFUhbivoqWI%2Fimage.png?alt=media&amp;token=f4bc6b8c-1afa-46c7-bb04-0d2c8d5cbafb" alt=""><figcaption></figcaption></figure>

Editor Module is as detailed below,

<figure><img src="https://3506001968-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FWu4HIWGkb7dD4y0Kup4W%2Fuploads%2FrRBe2HGGojiGU7uJSWv1%2Fimage.png?alt=media&amp;token=b54d96aa-9533-4d97-bafc-58ed2f410328" alt=""><figcaption></figcaption></figure>

<details>

<summary>Additional details about the internals of the Editor</summary>

* Editor Module - Root module of the editor library where all the components and services are imported
* Editor Component - Base component of the Editor which consists of the sub components
  * Header Components - contains the buttons any header elements
  * Metadata Components - for capturing metadata
  * Player Component - for preview of question and questionSet
  * Fancy Tree Component - for tree view (navigation)
  * Resource Lib Component - for adding question from Library
* Editor Service - service layer that makes the API calls related to Editor. For eg:- save, update
* Telemetry Service - initialise the Telemetry SDK and prepare the telemetry events
  * Telemetry SDK - to sent out the telemetry events to external Telemetry Service

</details>

#### Question / QuestionSet Creation flow

<figure><img src="https://3506001968-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FWu4HIWGkb7dD4y0Kup4W%2Fuploads%2Fd08TdhmXRyntySn5OkQv%2Fimage.png?alt=media&amp;token=a63bc12e-dbc9-4d48-ae9b-86f64b1dadbf" alt=""><figcaption></figcaption></figure>

#### Question / QuestionSet Review process flow

<figure><img src="https://3506001968-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FWu4HIWGkb7dD4y0Kup4W%2Fuploads%2F6qcPQzTckEmCRoSAlJbZ%2Fimage.png?alt=media&amp;token=1c625b42-268d-4b01-84c4-73ec2fd5165a" alt=""><figcaption><p>QuestionSet creation flow</p></figcaption></figure>

<figure><img src="https://3506001968-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FWu4HIWGkb7dD4y0Kup4W%2Fuploads%2FXXZHh88e9lDJ0vlrFwQL%2Fimage.png?alt=media&amp;token=5f3c4881-9e51-49d2-885f-0065e2e76583" alt=""><figcaption><p>QuestionSet Review / Publish flow</p></figcaption></figure>

#### Editor interaction with Knowlg BB Service

<figure><img src="https://3506001968-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FWu4HIWGkb7dD4y0Kup4W%2Fuploads%2FJF6GICy0vMXgIrRLwoOj%2Fimage.png?alt=media&amp;token=63885a27-9568-4685-818f-a1e8f961b3db" alt=""><figcaption></figcaption></figure>

#### Code Structure

* [Repository](/learn/product-and-developer-guide/question-and-question-set-editor/source-code)
* Important Folder / Package structure

  <pre><code><strong>- projects
  </strong>	- questionset-editor-library-wc [This contains the application for building web component and copy the files into web-component folder]
  	- questionset-editor-library [This contains the actual code of editor library which get build and bundled into editor library npm package]
  - src [This contains the Sample Application for running the editor library]
  - web-component-examples [This contains the code for running editor web component in vanilla js]
  - web-component [This contains the files which get bundled to form npm packge of editor web component]
  </code></pre>

#### Dependencies

Details are listed [here](/use/learn-more/dependencies) for the below specified dependencies

* [Sunbird QuML Specification](https://quml.sunbird.org/)
* [Sunbird inQuiry Service](/learn/product-and-developer-guide/quick-starter-guide/inquiry-components/inquiry-service)&#x20;
* [Sunbird Knowlg Service](https://knowlg.sunbird.org/)
* Sunbird Telemetry

## APIs used by Editor

APIs invoked from Editor component is listed [here](/learn/product-and-developer-guide/question-and-question-set-editor/apis)


# Player

Sunbird [inQuiry Player](/learn/product-and-developer-guide/question-set-player/architecture) is used for consuming the question set. The current player supports the following question types,

* Multiple Choice Question (MCQ)
* Multi-select Multiple Choice Question (MMCQ)
* Subjective Question (SA)

This Player is also known as Question Set Player or QuML Player.

## Question Set Player (QuML Player)

Question set player is a player provided by inQuiry to create engaging & inclusive experiences for end users consuming the question sets.

More details on the player can be found [here](/learn/capabilities-1#d-question-set-player-quml-player) and [here](/learn/product-and-developer-guide/question-set-player).

Player architecture is as below,

<figure><img src="https://3506001968-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FWu4HIWGkb7dD4y0Kup4W%2Fuploads%2F4YSViWvbckkB18bnUYzX%2Fimage.png?alt=media&amp;token=8505fd85-ca6b-4254-9d35-e5f9fd33df4f" alt=""><figcaption></figcaption></figure>

Player Module is as detailed below,

<figure><img src="https://3506001968-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FWu4HIWGkb7dD4y0Kup4W%2Fuploads%2F3vg1l2ZXS8JnAK7sivpT%2Fimage.png?alt=media&amp;token=8149b940-67ea-4e0f-a7ae-8cedff5c43a8" alt=""><figcaption></figcaption></figure>

<details>

<summary>Additional details about the internals of the Player</summary>

* Player Module - Root module of the player library where all the components and services are imported
* Player Component - Base component of the Editor which consists of the sub components
  * Section Component - Handles different types of questions by using its sub components
    * Start Page Component - Provide instructions for exams
    * MCQ Component - for rendering multiple choice questions.
    * SA Component - for rendering short answer questions (subjective)
    * Alert Component - Showing feedback or solutions
  * End Page Component - Summary of exam
* Viewer Service - service layer that makes the API calls related to Player. For eg:- question list
* Telemetry Service - initialise the Telemetry SDK and prepare the telemetry events
  * Telemetry SDK - to sent out the telemetry events to external Telemetry Service

</details>

#### Question / QuestionSet Consumption flow

<figure><img src="https://3506001968-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FWu4HIWGkb7dD4y0Kup4W%2Fuploads%2FTUcOfLCAqgQqhPwhKBXJ%2Fimage.png?alt=media&amp;token=9d0cf128-d09a-4691-843e-2fd58f3c8c59" alt=""><figcaption><p>User attempting questions</p></figcaption></figure>

#### Code Structure

* [Repository](/learn/product-and-developer-guide/question-set-player/source-code)
* Important Folder / Package structure

  ```
  - projects
  	- quml-demo-app [Sample application for library]
  	- quml-library [Contains library components and service]
  	- quml-player-wc [Application to generate web component]
  - web-component-examples [Contains sample projects]
  - web-component [Contains generated web component files]
  ```

#### Dependencies

Details are listed [here](https://inquiry.sunbird.org/use/learn-more/dependencies) for the below specified dependencies

* [Sunbird QuML Specification](https://quml.sunbird.org/)
* [Sunbird inQuiry Service](/learn/product-and-developer-guide/quick-starter-guide/inquiry-components/inquiry-service)&#x20;
* Sunbird Telemetry

## APIs used by Player

APIs invoked from Player component is listed [here](/learn/product-and-developer-guide/question-set-player/apis)


# inQuiry Service

Sunbird [inQuiry Service](/learn/product-and-developer-guide/question-and-question-set-service/architecture) is the backend service used from inQuiry Editor and Player. This service is also called as Question & QuestionSet service.

## Question & Question Set Service

Question and Question set service is a micro-service which provides APIs to manage the lifecycle and workflows of creation and consumption of question & question set objects.

More details on the player can be found [here](/learn/capabilities-1#c-question-and-question-set-services) and [here](/learn/product-and-developer-guide/question-and-question-set-service).

Question & Question Set Service architecture is as below,

<figure><img src="https://files.gitbook.com/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FWu4HIWGkb7dD4y0Kup4W%2Fuploads%2FrA9rFcWflZ5JbOcENCbA%2FInQuiry%20Backend%20Architecture.png?alt=media&#x26;token=a12df702-71d5-4f03-b3e5-80880cf6de15" alt=""><figcaption></figcaption></figure>

{% embed url="<https://youtu.be/mjV0MmP9WuQ?si=n61pgaVwp9G55QI4&t=2407>" %}

#### Player / Editor interaction with inQuiry Service

<figure><img src="https://3506001968-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FWu4HIWGkb7dD4y0Kup4W%2Fuploads%2FkEJ25xYF7xp3qk5leome%2Fimage.png?alt=media&amp;token=27914eeb-4a7f-4154-83d0-ed52dde31940" alt=""><figcaption></figcaption></figure>

#### Publish Process

<figure><img src="https://3506001968-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FWu4HIWGkb7dD4y0Kup4W%2Fuploads%2F5bx2stnqIQzjdCSXxt6c%2Fimage.png?alt=media&amp;token=d3c8e283-c28f-432b-99d0-9ce7444ef9cd" alt=""><figcaption><p>Publish Process</p></figcaption></figure>

{% embed url="<https://youtu.be/mjV0MmP9WuQ?si=IUEzBizPUScSA58R&t=2448>" %}

### Critical APIs - Sequence of calls

Below is a high level picture of how the sequence of flow happens for some of the critical apis. The flow is similar to other API end points in inQuiry.

This also shows the usage of Knowlg core in the flow of inQuiry apis.

**QuestionSet Create**

<figure><img src="https://3506001968-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FWu4HIWGkb7dD4y0Kup4W%2Fuploads%2Fis5BxP9NRFzxCMzslRkT%2Fquestionset_create_sequence.png?alt=media&amp;token=bbbe5c60-fa56-48f4-8712-86ae77a4721a" alt=""><figcaption></figcaption></figure>

**QuestionSet Read**

<figure><img src="https://3506001968-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FWu4HIWGkb7dD4y0Kup4W%2Fuploads%2FrZpLREpoKCoruTO9qYZR%2Fquestionset_read_sequence.png?alt=media&amp;token=53dbf904-39d1-467d-be29-3d209443f456" alt=""><figcaption></figcaption></figure>

**QuestionSet Update**

<figure><img src="https://3506001968-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FWu4HIWGkb7dD4y0Kup4W%2Fuploads%2FPTAeWeGyCz7KsoUWYdOp%2Fquestionset_update_sequence.png?alt=media&amp;token=8f5183eb-fd59-46f0-9d40-d18fac29540d" alt=""><figcaption></figcaption></figure>

**Question Create**

<div data-full-width="false"><figure><img src="https://3506001968-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FWu4HIWGkb7dD4y0Kup4W%2Fuploads%2FiEZhBcDmSIMFT4HHIURa%2Fquestion_create_sequence.png?alt=media&amp;token=5c818a3c-22ec-4aff-b43b-896a32b17d70" alt=""><figcaption></figcaption></figure></div>

{% hint style="info" %}
The detail on how the data is saved and retrieved is not depicted in above sequence of flow as it is part of Knowlg core library.&#x20;
{% endhint %}

{% embed url="<https://youtu.be/mjV0MmP9WuQ?si=Bb45DfVfW6ffIC63&t=2489>" %}

#### Data Models

* Schemas
  * [Question Schema](https://inquiry.sunbird.org/learn/product-and-developer-guide/question-and-question-set-service/schema/question-schema)
  * [QuestionSet Schema](https://inquiry.sunbird.org/learn/product-and-developer-guide/question-and-question-set-service/schema/questionset-schema)
* Databases
  * **Neo4J** (Primary Data Storage. inQuiry store all objects (e.g: Question/QuestionSet/ObjectCategory, etc) simple/lite metadata (e.g: name, description, createdOn, etc) in graph)
  * **Cassandra** (Secondary data Storage. inQuiry stores all complex/bulk data in this storage. For more information, please refer to external section of each object config (config.json) to see what all data gets stored in secondary storage for particular object.)
  * **Elastic Search** (Data Stored in Grpah Database (Primary Data Storage) gets replicated in Elasticsearch through data pipeline. So that user can search data based on different criteria (e.g: need to search science subject questions for class 5))
  * **Redis** (Used for caching the question / questionSet information. It only stores object which are ready for consumption (objects in Live status))
  * **Cloud Storage** (Used to store assets like media, question/questionset bundles, artifacts in the cloud storage)

#### Code Structure

* [Repository](/learn/product-and-developer-guide/question-and-question-set-service/source-code)
* Important Folder / Package structure

  ```
  - assessment-api [API service containing question and question set service]
   - assessment-actors
     - src/main/scala/org/sunbird /actors [Contains the actor module which talk to manager module as well as graph engine]
     - src/main/scala/org/sunbird/managers [Contains additional utility which is needed for processing]
   - assessment-service
     - app/controllers [The REST API controllers]
   - qs-hierarchy-manager
     - src/main/scala/org/sunbird/managers [all utility to perform operations on hierarchal structure]
  ```

{% embed url="<https://youtu.be/yoHBowTh4OQ?si=ivf7Rh1NNwblG-d8&t=23>" %}

* Sub Components
  * Question API

    This is used for question management like create, read, update, review, publish etc.

    [API Documentation](https://inquiry.sunbird.org/learn/product-and-developer-guide/question-and-question-set-service/apis/v1#question-management-apis)
  * QuestionSet API

    This is used for question set management like create, read, update, review, publish etc.

    [API Documentation](https://inquiry.sunbird.org/learn/product-and-developer-guide/question-and-question-set-service/apis/v1#question-set-management-apis)
  * Flink Jobs Used

    async-questionset-publish \[Used for Question and QuestionSet publish]
  * [Configuration](/learn/product-and-developer-guide/question-and-question-set-service/configuration)
* [Developer Installation Guide](/use/developer-installation/question-and-question-set-service)

#### Dependencies

Details are listed [here](https://inquiry.sunbird.org/use/learn-more/dependencies) for the below specified dependencies

* [Sunbird QuML Specification](https://quml.sunbird.org/)
* [Sunbird Knowlg Service](https://knowlg.sunbird.org/)
* Sunbird Telemetry Specification
* Sunbird Obsrv (Optional)

{% embed url="<https://youtu.be/mjV0MmP9WuQ?si=Lv8cgzUIYjivNfX8&t=815>" %}

## API listing

The APIs exposed by the micro service is available [here](/learn/product-and-developer-guide/question-and-question-set-service/apis)


# Question & Question Set Editor

Multilevel hierarchy contents like Practise Questionset, Exam Questionset, etc.

## Key Features:

Question set editor is a powerful tool that provides various features:-

#### a) Ability to load dynamic reactive forms with configuration fields and validations.

#### b) Enables the creation of different types of questions.

The inQuiry comes with two pre-built question types:

* Multiple Choice Question (interactive) and
* Subjective Question (non-interactive).

![](https://3506001968-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FWu4HIWGkb7dD4y0Kup4W%2Fuploads%2FD2dKO4bjCtwZ1HZorVx0%2Fimage.png?alt=media\&token=1badb8b6-e46a-4701-a1bf-2b9964382ada)

#### c) Ability to create a question(s) that have images & rich text.

Question set editor provides features to add images, mathematical formula, formatting of texts as per the needs, etc.

![](https://3506001968-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FWu4HIWGkb7dD4y0Kup4W%2Fuploads%2FrMkwkwGUvRqo110vceOt%2Fimage.png?alt=media\&token=c618dc38-5a4b-482e-9caf-c81a646cf157)

#### d) Ability to add and customize scientific and mathematical formulae in the question text.

![](https://3506001968-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FWu4HIWGkb7dD4y0Kup4W%2Fuploads%2FcCDG1V44x5vwjkxuNMbf%2Fimage.png?alt=media\&token=9cdeec9d-e4c6-4d8e-81fa-79fbb6bd2d25)

#### e) Flexibility for creators to choose to render their questions in one of the three different layouts:&#x20;

* &#x20;Vertical layout

![Vertical layout](https://3506001968-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FWu4HIWGkb7dD4y0Kup4W%2Fuploads%2FA3KJFqmq85eNilXs8cnQ%2Fimage.png?alt=media\&token=8e4357dc-9ac6-4ebf-bbdc-02dff3506631)

* Grid layout

![Grid layout](https://3506001968-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FWu4HIWGkb7dD4y0Kup4W%2Fuploads%2FTjfYPQVScAJOCoHOAbMD%2Fimage.png?alt=media\&token=ad9bbc63-b85d-49cc-a441-aad5c4c8b0da)

* &#x20;Horizontal layout

![](https://3506001968-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FWu4HIWGkb7dD4y0Kup4W%2Fuploads%2FCIjY6Sn0ZEEGNQFGdjAj%2Fimage.png?alt=media\&token=3319d97c-9e41-42f6-9109-4f9593b6b0c7)

#### f) Ability to include 'Solutions' - either 'text+image' only solutions or 'video' solutions to the question(s)

During the question creation solution can be added to the question, the solution can have text and image or the video which can be shown in the player on enabling the **Show Solution** in the editor.

![](https://3506001968-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FWu4HIWGkb7dD4y0Kup4W%2Fuploads%2Fu9uYqbCdTWe2cLTmfCSg%2Fimage.png?alt=media\&token=7d019f14-c953-4a3a-94c7-93b5a1a04aac)

![](https://3506001968-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FWu4HIWGkb7dD4y0Kup4W%2Fuploads%2FLeFnSgzJ59Lnvp2X0nEc%2FMcq-text-solution.png?alt=media\&token=3cecf948-11f2-49a9-abf0-65b02734bc1d)

![](https://3506001968-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FWu4HIWGkb7dD4y0Kup4W%2Fuploads%2FyxPgv9dIVOXDelQQzwo3%2FMcq-video-solution.png?alt=media\&token=47cc18a2-c107-4d5a-9f98-6438dfd8b4ed)

#### g) Allows for question level metadata tagging against system defined taxonomy. Below is a screenshot of question tagging enabled using the Indian K-12 taxonomy.

![](https://3506001968-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FWu4HIWGkb7dD4y0Kup4W%2Fuploads%2FXa11gQzZ2JtkvP2GQTln%2Fquestion-metadata.png?alt=media\&token=937e82e2-3ed5-4901-9423-811181ccf107)

#### h) Ability to preview questions

![](https://3506001968-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FWu4HIWGkb7dD4y0Kup4W%2Fuploads%2FWTutS3xvWDDWVt9QAkDa%2Fquestion-preview.png?alt=media\&token=c5f423bd-a9d2-4417-95c1-77516b13f986)

#### i) Ability to create question sets with ease using the tree structure

The WYSIWYG editor makes the creation experience easier and faster for creators. For acheving this we are using [fancy tree](https://github.com/mar10/fancytree/wiki),  which provides efficient and performance handling of large data sets, It also provides the ability to drag and drop any question in a multi-level hierarchy.

![](https://3506001968-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FWu4HIWGkb7dD4y0Kup4W%2Fuploads%2FQKSsXcSY3cpyTi7HzAn0%2FQuestionset.png?alt=media\&token=ec5a664e-2edc-4ca2-962e-87b17cf03d6d)

#### j) Configuration behaviour of the question set and section

The various question set level configurations available to the creator are:

1. **Set maximum time** - The maximum time allowed for the users to complete the question set.
2. **Submit confirmation page** - If enabled, provides an explicit Submit option for the users to review their answers and submit the assessment.&#x20;
3. **Max attempts** - It defines the number of times the user can attempt a question set.
4. **Summary Type** - Defines the details which we want to show on the summary page, For example:- Score, Duration, Score+Duration.&#x20;

![](https://3506001968-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FWu4HIWGkb7dD4y0Kup4W%2Fuploads%2Fy2bBmvVMFowi6RVrhVTk%2FQuestion-set-behaviour-fields.png?alt=media\&token=b0b98975-d828-4588-a3b2-06b25048ff20)

![](https://3506001968-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FWu4HIWGkb7dD4y0Kup4W%2Fuploads%2FCKev9MhnyCnVjNnO2MEY%2FQuestionset-preview.png?alt=media\&token=06043285-4634-45fe-b698-80fe6df4a718)

#### k) Ability to group questions into multiple sections with each section having its own specific behaviour.

The various section level configurations available to the creator are:

1. **Count of questions to be displayed in this section** - By default, all questions in the section are shown to the user. However, creators have an option to show only a sub-set of questions by using this property.
2. **Shuffle questions** - If enabled, users are presented with questions in a random order whenever they attempt the assessment.
3. **Show feedback** - If enabled, users are informed whether they have correctly answered questions or not.&#x20;
4. **Show solution** - If enabled, solutions to each question are shown to the users.

![](https://3506001968-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FWu4HIWGkb7dD4y0Kup4W%2Fuploads%2FpjyMLIgaJWOLt0EZVqHs%2Fsection-form.png?alt=media\&token=a8623d13-cc26-4757-9ec1-2a99575206f8)


# Architecture

![Question Set Editor - Architecture](https://3506001968-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FWu4HIWGkb7dD4y0Kup4W%2Fuploads%2F7SGN9NrN8jUVm8IkSTFp%2Fimage.png?alt=media\&token=56d700e1-48b1-48e3-951b-25061ec28d4c)

#### [FancyTree](https://github.com/mar10/fancytree/wiki)

The main purpose of using a fancy tree is a tree view/tree grid that allows to dynamically render powerful, user-friendly tree view, drag\&drop, lazy loading, efficient and performant handling of large data sets.

[**CKEditor5**](https://ckeditor.com/ckeditor-5/)

CKEditor provides features to add images, mathematical formula, formatting of texts as per the needs, etc in questions.

#### [Question Set Player](https://inquiry.sunbird.org/learn/product-and-developer-guide/question-set-player)

The sunbird players is used to preview Question and Questionset.

#### [Common Form (Sunbird Form)](https://ed.sunbird.org/use-1/independent-libraries/sunbirded-forms)

Use Common Forms to define the dynamic layout of a page that contains fields and sections. What makes this dynamic is you can show/hide the sections & fields based on certain criteria, which currently is not possible with static page layouts.

#### [Telemetry SDK](https://telemetry.sunbird.org/)

Telemetry SDK is a standalone telemetry JS library allows to capture telemetry data.


# Features

Following are the features and related configuration to enable these features in question set editor:

## Mode

The editor can be set into different type of mode, we can achieve this by changing the value of the Config#mode property. \
\
Following are types of mode:\
1\.  read\
2\. edit\
3\. review\
\
**- read**\
The read mode is a feature within the editor that allows users to see the editor. But you cannot edit it.\
Here’s the configuration:

```
"config": {
   mode: 'read',
}
```

![](https://3506001968-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FWu4HIWGkb7dD4y0Kup4W%2Fuploads%2FYpFLfnMgNH88o7SVN41Y%2Fimage.png?alt=media\&token=fbd2aa05-957f-456b-839e-5a6a34e3b480)

**- edit**\
All the fields will be enabled to edit for the collection creator.\
Here’s the configuration:

```
"config": {
   mode: 'edit',
}
```

![](https://3506001968-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FWu4HIWGkb7dD4y0Kup4W%2Fuploads%2FOvwmRjxV4YunLupG0jYS%2Fimage.png?alt=media\&token=0dec1dc1-cbb7-4239-af98-4b12d21e1354)

**- review**\
It’s similar to read mode only. but here users can perform some actions such as publish, reject. \
Here’s the configuration:

```
"config": {  
    mode: 'review',
}
```

![](https://3506001968-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FWu4HIWGkb7dD4y0Kup4W%2Fuploads%2FRFwDxFikUEHeOYBTzO2e%2Fimage.png?alt=media\&token=cfa26ea3-9ba8-4d54-94e4-653ae09ebefd)

You define which fields of a form can be editable for a specific `mode` with limited editing rights, leaving the rest of the fields non-editable to them. \
\
\- **editableFields**\
Its object for different types of mode based on which some fields get enabled.\
Here is the sample configuration for review mode:

```
"config": {  
    mode: 'review',
    editableFields: {
    "review": [
        "instructions"
    ]
}
}
```

Note: In above case **editableFields.review**: \['instructions'] so only instruction field is enabled for reviewer while reviewing the questionset.

## Media Upload Config

Media Config sets the max size limit for images to be uploaded in the question set editor and the type of images.\
Here is the configuration:

```
"config": {  
    assetConfig: {
        "image": {
            "size": 1,
            "sizeType": "MB",
            "accepted": "png, jpeg"
        }
    }
}
```

![](https://3506001968-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FWu4HIWGkb7dD4y0Kup4W%2Fuploads%2F6JmOJ1n6ALUDRHHrbOc7%2Fimage.png?alt=media\&token=8e6c128e-0788-44cc-86f1-06aa00c16d0d)

## Organize TOC

The maximum number of levels in the questionset has to be defined using the `maxDepth` property. This has to be updated in the object metadata of the primary category definition under hierarchy.\
`maxDepth` defines the level of questionset i.e at which level question is to be linked. If `maxDepth` is set as 0, `Create New` button get enabled to question at root node.

![](https://3506001968-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FWu4HIWGkb7dD4y0Kup4W%2Fuploads%2FtUzNySichInAfx2L8ENY%2Fimage.png?alt=media\&token=d48d2fe5-296e-46d5-a460-283bf0b56a18)

Note: children at root node is to be defined which defines the type of question can be created at root node. Here is the default value to be used for children.

```
children: {
    Question: [
      'Multiple Choice Question',
      'Subjective Question'
    ]
  }
```

he maxDepth is set as 1, we need to define hierarchy also.

Here is the default value of hierarchy we are using, you can change the name of level also

```
hierarchy: {
    "level1": {
        "name": "Section",
        "type": "Unit",
        "mimeType": "application/vnd.sunbird.questionset",
        "primaryCategory": "Practice Question Set",
        "iconClass": "fa fa-folder-o",
        "children": {
            "Question": [
                "Multiple Choice Question",
                "Subjective Question"
            ]
        }
    }
}
```

***Note: If you add more depth you need to add more levels in hierarch***

## Add Collaborator

This feature allow us to share the questionset with other users so they can contribure back to the same questionset. To enables the add collaborator option in the question set editor we need to set`showAddCollaborator` as true. \
Here is the configuration:

```
"config": {  
    showAddCollaborator: true
    }
```

![](https://3506001968-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FWu4HIWGkb7dD4y0Kup4W%2Fuploads%2FcgvMweAWuGkk5ylt5DfH%2Fimage.png?alt=media\&token=dcea23c8-ee7f-4793-b80c-58bc40cc9710)

## Question Linking Limit

**questionSet.maxQuestionsLimit**

This defines the maxiumun number of question to be created in a questionset.

```
questionSet: {
    "maxQuestionsLimit": "500"
}
```

Suppose if "maxQuestionsLimit" is set to **“5“** then while trying to create new question it will give error maxlimit message as:

![](https://3506001968-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FWu4HIWGkb7dD4y0Kup4W%2Fuploads%2Fp8Ct3OWOhReq2wuI8Njd%2Fimage.png?alt=media\&token=cc462537-34f6-4680-abff-2af5208aa61d)

## Icon

This defines the icon which comes in the node and levels, you can set your own icon here by adding the class of icon, in root node for iconClass: 'fa fa-book' icon is shown as:

![](https://3506001968-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FWu4HIWGkb7dD4y0Kup4W%2Fuploads%2FHfnpXJfC9WsW3hwQb9z7%2Fimage.png?alt=media\&token=432b4fee-caf1-4bc5-b82f-58c8174c11dd)

## &#x20;Common Framework License URL

It defines where should the creative common framework link should be redirected.

Ex - `commonFrameworkLicenseUrl: 'https://creativecommons.org/licenses/'`

<figure><img src="https://3506001968-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FWu4HIWGkb7dD4y0Kup4W%2Fuploads%2F26866CVmR3XRBo9pLIhQ%2FcommonFrameworkLicenseUrl.png?alt=media&amp;token=73985e05-f5a4-4971-81cb-59d64ba773bc" alt=""><figcaption></figcaption></figure>

## Content Policy URL

It defines where should the content policy link should be redirected.

`contentPolicyUrl: "/term-of-use.html"` we are using this config in Diksha as it redirects to (<https://diksha.gov.in/term-of-use.html>)

![](https://3506001968-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FWu4HIWGkb7dD4y0Kup4W%2Fuploads%2FKQ7KdnDvSdB8bBiKSCSd%2Fimage.png?alt=media\&token=37f0be68-dc61-42d6-b52d-68ab688334ce)


# Configuration

In this section we have covered various configurations available in questionset editor to enable and disable some functionalities.

Question Set Editor is an angular library built with Angular, and it exports some modules and components.

## **Component:** `editor`

This is the main editor Component that accepts some configuration (here `editorConfig`) based on it loads the editor. &#x20;

Let's deep dive into the player input configuration:

```
  export interface questionSetEditorConfig = {
    context: Context;
    config: Config;
  }
```

## :clipboard:Inpu&#x74;**:**&#x20;

### **1. Context -** Required <a href="#context-required" id="context-required"></a>

This Required property from the `questionSetEditorConfig` provides the context to the questionset editor mostly in terms of the telemetry.

Along with this it also provides the channel level config, if available.

```
export interface Context {
    env: string;
    sid: string;
    did: string;
    uid: string;
    channel: string;
    pdata: Pdata;
    contextRollup: ContextRollup;
    tags: string[];
    identifier?: string;
    authToken?: string;
    cdata?: Cdata[];
    timeDiff?: number;
    objectRollup?: ObjectRollup;
    host?: string;
    endpoint?: string;
    userData?: {
        firstName: string;
        lastName: string;
    };
    framework: string;
    user: User;
    programId?: string;
    contributionOrgId?: string;
    defaultLicense?: any;
    cloudStorageUrls?: string[];
    labels?: any;
    targetFWIds?: string[];
    board?: any;
    medium?: any;
    gradeLevel?: any;
    subject?: any;
    topic?: any;
    additionalCategories?: any[];
    actor?: any;
    channelData?: any;
    correctionComments?: any;
    sourcingResourceStatus?: string;
    sourcingResourceStatusClass?: string;
    collectionIdentifier?: string;
    unitIdentifier?: string;
    collectionObjectType?: string;
    collectionPrimaryCategory?: string;
    cloudStorage?: any;
}
```

The context has been classified into two parts as below:

1. Telemetry Context
2. Editor Context

#### 1. Telemetry Context:

It provides the context to the editor mostly in terms of the telemetry. Let's understand the description of the following properties:

<table><thead><tr><th width="150">Property Name</th><th>Description</th><th width="150">Required</th><th>Default Value</th></tr></thead><tbody><tr><td><code>env</code></td><td>It is <code>string</code> and Unique environment where the event has occured <strong>For example:</strong> in case of question set editor its <code>questionset_editor</code></td><td>true</td><td><p><code>questionset_editor</code></p><p><code>OR</code></p><p><code>collection_editor</code></p></td></tr><tr><td><code>sid</code></td><td>It is <code>string</code> and session id of the requestor stamped by portal <strong>For example:</strong> <code>vLpZ1rFl6-sxMVHi4RrmrlHw0HsX9ggC</code></td><td>true</td><td></td></tr><tr><td><code>did</code></td><td>It is <code>string</code> and uuid of the device, created during app installation or browser <strong>For example:</strong> <code>1d8e290dd3c2a6a9eeac58568cdef28d</code></td><td>true</td><td></td></tr><tr><td><code>uid</code></td><td>It is <code>string</code> and Current logged in user id <strong>For example:</strong> <code>5a587cc1-e018-4859-a0a8-e842650b9d64</code></td><td>true</td><td></td></tr><tr><td><code>channel</code></td><td>It is <code>string</code> which defines channel identifier to know which channel is currently using. <strong>For example:</strong> <code>01309282781705830427</code></td><td>true</td><td></td></tr><tr><td><code>pdata</code></td><td>It is an <code>object</code> which defines the producer information it should have identifier and version and canvas will log in the telemetry. <strong>For example:</strong> <code>{ id: 'local.sunbird.portal', ver: '4.1.0', pid: 'sunbird-portal' }</code></td><td>true</td><td></td></tr><tr><td><code>contextRollup</code></td><td>It is an <code>object</code> which defines collection roll up data For example: <code>{ l1: 'do_1234567890' }</code></td><td>true</td><td></td></tr><tr><td><code>tags</code></td><td>It is an <code>object</code> and Encrypted dimension tags passed by respective channels. For example: <code>['01307938306521497658']</code></td><td>true</td><td></td></tr><tr><td><code>identifier</code></td><td>It is <code>string</code> and Identifier of collection.</td><td>false</td><td><code>''</code></td></tr><tr><td><code>authToken</code></td><td>It is <code>string</code> and Auth key to make api calls.</td><td>false</td><td><code>''</code></td></tr><tr><td><code>cdata</code></td><td>It is an <code>array</code> which defines the correlation data</td><td>false</td><td><code>[]</code></td></tr><tr><td><code>timeDiff</code></td><td>It is <code>number</code> and timeDiff (in sec) is diff of server date and local date</td><td>false</td><td><code>''</code></td></tr><tr><td><code>objectRollup</code></td><td>It is an <code>object</code> which defines object rollup data (Only 4 levels are allowed)</td><td>false</td><td><code>{}</code></td></tr><tr><td><code>host</code></td><td>It is <code>string</code> which defines the from which domain collection should be load. <strong>For example:</strong> <code>https://dev.sunbirded.org</code></td><td>false</td><td><code>''</code></td></tr><tr><td><code>endpoint</code></td><td>It is <code>string</code> and Telemetry API endpoint. <strong>For example:</strong> <code>/data/v3/telemetry</code></td><td>false</td><td><code>''</code></td></tr><tr><td><code>userData</code></td><td>It is <code>object</code> and first and last name of logged in user</td><td>false</td><td><code>{}</code></td></tr></tbody></table>

#### 2. Editor Context:

The editor context is used while launching the editor. Let's understand the description of the following properties:

<table><thead><tr><th>Property Name</th><th>Description</th><th width="150">Required</th><th>Default Value</th></tr></thead><tbody><tr><td><code>framework</code></td><td>It is <code>string</code> and Organisation framework id. <strong>For example:</strong> <code>ekstep_ncert_k-12</code></td><td>true</td><td></td></tr><tr><td><code>user</code></td><td>It is an <code>object</code> which defines user data which contains users id, fullName, lastName, orgIds.</td><td>true</td><td><strong>For example:</strong> <code>{ id: '5a587cc1-e018-4859-a0a8-e842650b9d64', orgIds: [ '01309282781705830427' ], organisations: {}, fullName: 'Vaibhav Bhuva', firstName: 'Vaibhav', lastName: 'Bhuva', isRootOrgAdmin: true }</code></td></tr><tr><td><code>programId</code></td><td><p>It is <code>string</code> and program id in which questionset is created. This value required for coKreat flows.</p><p>For example: <code>f72ad8b0-36df-11ec-a56f-4b503455085f</code></p></td><td>false</td><td><code>''</code></td></tr><tr><td><code>contributionOrgId</code></td><td>It is <code>string</code> and Organisation id of the contributor. This value required for coKreat flows.</td><td>false</td><td><code>''</code></td></tr><tr><td><code>identifier</code></td><td>It is <code>string</code> and Identifier of collection. For example: <code>do_1134357224765685761203</code></td><td>false</td><td><code>''</code></td></tr><tr><td><code>defaultLicense</code></td><td>It is <code>string</code> and default license of editor. For example: <code>CC BY 4.0</code></td><td>false</td><td><code>''</code></td></tr><tr><td><code>cloudStorageUrls</code></td><td>It is <code>array</code> and Array of cloud storage urls</td><td>false</td><td><code>[]</code></td></tr><tr><td><code>additionalCategories</code></td><td>It is <code>array</code> and Array of objects of additional categories. For example: <code>[ { value: 'Classroom Teaching Video', label: 'Classroom Teaching Video' }, { value: 'Concept Map', label: 'Concept Map' }]</code></td><td>false</td><td><code>[]</code></td></tr><tr><td><code>labels</code></td><td>It is <code>object</code> and Additional labels to be used in editor</td><td>false</td><td><code>{}</code></td></tr><tr><td><code>targetFWIds</code></td><td>It is <code>array</code> and Array of target framework ids</td><td>false</td><td><code>[]</code></td></tr><tr><td><code>cloudStorage</code></td><td>It is <code>object</code> and which defines cloud storage configuration which contains presigned_headers for diff service provider for example: Azure, AWS</td><td>false</td><td><strong>For example:</strong> <code>cloudStorage: { presigned_headers: { 'x-ms-blob-type': 'BlockBlob' // This header is specific to azure storage provider. } }</code></td></tr></tbody></table>

### 2. Config - `Required`

This Required property from the questionsetEditorConfig provides the configuration for the questionset editor to enable/disable some functionalities.

```
config: {
    mode: 'string', //ex: 'edit'/'review'/'read'/'sourcingReview'/'orgReview'
    editableFields: {
      sourcingreview: string[],
      orgreview: string[],
      review: string[],
    },
    maxDepth: number, //ex: 1
    objectType: 'QuestionSet',
    primaryCategory: 'Practice Question Set',
    isRoot: boolean, //ex: true
    iconClass: 'string', //ex: 'fa fa-book'
    children: {
      Question: [
        'Multiple Choice Question',
        'Subjective Question'
      ]
    },
    hierarchy: {
      level1: {
        name: '', //ex: 'Section'
        type: '', //ex: 'Unit'
        mimeType: 'application/vnd.sunbird.questionset',
        primaryCategory: 'string', //ex: 'Practice Question Set'
        iconClass: 'string' //ex: 'fa fa-folder-o',
        children: {}
      },
      level2: {
        name: 'string', //ex: 'Sub Section'
        ...
        ...
      },
      level3: {
      ...
      ...
      }
    },
    assetProxyUrl: 'string' //ex: '/assets/public/'
    commonFrameworkLicenseUrl: 'string' //ex: 'https://creativecommons.org/licenses/'
    contentPolicyUrl: 'string' //ex: '/term-of-use.html' 
  }
```

> Note: **If the property is added in object-category-definition of questionset. It will take the config from there, otherwise questionset editor will take the mock config passed as input to the editor.**

**Description of the properties for the config:**

<table><thead><tr><th width="232">Property Name</th><th>Description</th><th width="150">Required</th><th>Default Value</th></tr></thead><tbody><tr><td><code>isRoot</code></td><td>It is <code>boolen</code> and that defines the node is root node.</td><td>true</td><td><code>true</code></td></tr><tr><td><code>objectType</code></td><td>It is <code>string</code> and that defines the object type of collection</td><td>true</td><td>'<code>QuestionSet</code>'</td></tr><tr><td><code>primaryCategory</code></td><td>It is <code>string</code> and that defines the primary category of collection</td><td></td><td><code>'Practice Question Set'</code></td></tr><tr><td><code>iconClass</code></td><td>It is <code>string</code> and that defines the icon of root node</td><td>true</td><td><code>fa fa-book</code></td></tr><tr><td><code>children</code></td><td>If maxdepth is 0 this children inside the root node defines the template of questions. <strong>For example:</strong> <code>children</code><strong><code>:</code></strong><code> { "Question": [ "Multiple Choice Question", "Subjective Question" ] }</code></td><td>true</td><td></td></tr><tr><td><code>assetProxyUrl</code></td><td>Asset proxy URL is to create a proxy URL of assets such as image/video to be used in editor with the proxy URL instead of making use actual blob storage URL to attach and display assets in questions.</td><td>false</td><td><code>'/assets/public/'</code></td></tr><tr><td><code>commonFrameworkLicenseUrl</code></td><td>It is <code>string</code> and It defines where should the common framework license link will be redirected.</td><td>false</td><td><code>'https://creativecommons.org/licenses/'</code></td></tr><tr><td><code>contentPolicyUrl</code></td><td>It is <code>string</code> and It defines where should the content policy link will be redirected.</td><td>false</td><td><code>/term-of-use.html</code></td></tr><tr><td><code>mode</code></td><td>It is <code>string</code> and that defines the mode in editor is to be loaded. <strong>For example:</strong> <code>edit / review / read / sourcingReview / orgReview</code></td><td>false</td><td><code>edit</code></td></tr><tr><td><code>editableFields</code></td><td>It is an <code>object</code> and that defines the mode in editor is to be loaded.</td><td>false</td><td><code>{ sourcingreview: [], orgreview: [], review: [], }</code></td></tr><tr><td><code>maxDepth</code></td><td>It is <code>number</code> and Defines the depth to which the question set is to be created. If the depth is 1, hierarchy should have level1 described.</td><td>false</td><td><strong>For example:</strong> <code>1</code></td></tr><tr><td><code>assetConfig</code></td><td>It is an <code>object</code> and <code>assetConfig</code> sets the max size limit and type for image and videos to be uploaded in the editor. <strong>For example:</strong> <code>{ "image": { "size": "1", "sizeType": "MB", "accepted": "png, jpeg" }, "video": { "size": "50", "sizeType": "MB", "accepted": "mp4, webm" } }</code></td><td>false</td><td><code>{}</code></td></tr><tr><td><code>hierarchy</code></td><td>It is an <code>object</code> and If maxdepth is > 0 then hierarchy should have definiton of the levels. <strong>For example:</strong> <code>{ "level1": { "name": "Section", "type": "Unit", "mimeType": "application/vnd.sunbird.questionset", "primaryCategory": "Practice Question Set", "iconClass": "fa fa-folder-o", "children": { "Question": [ "Multiple Choice Question", "Subjective Question" ] } } }</code></td><td>false</td><td><code>{}</code></td></tr><tr><td><code>enableQuestionCreation</code></td><td>It enables or disables the creation of question in questionset</td><td>false</td><td>true</td></tr><tr><td><code>questionSet. maxQuestionsLimit</code></td><td>It defines the limit of total number of question to be created inside questionset.</td><td>false</td><td>500</td></tr></tbody></table>

###

Here is the sample configuration for Practise Question Set:

[**Practise Question Set**](https://inquiry.sunbird.org/use/developer-installation/question-set-editor/installation/object-category-definition)

## **Recommended Configuration for Question Set:**

We can creation interactive as well as non-interactive type question in the Question Set. And the creation of question in Question Set is possible in "without Sections" as well as "with Sections". It is recommened that we should not enable creation of both interactive and non-interactive type question in a Question Set as both are for different use case.

### **1.) Configuration for Question Set without Sections:**

* For enabling creation of **"Multiple Choice Question"** (interactive question) in Question Set, **objectCategoryDefinition.objectMetadata.config** is to be set as:

```
{
   "sourcingSettings": {
       "collection": {
           "maxDepth": 0,
           "objectType": "QuestionSet",
           "primaryCategory": "Practice Question Set",
           "isRoot": true,
           "iconClass": "fa fa-book",
           "children": {
               "Question": [
                   "Multiple Choice Question"
               ]
           },
           "hierarchy": {}
       }
   }
}
```

* For enabling creation of **"Subjective Question"** (non-interactive question) in Question Set, **objectCategoryDefinition.objectMetadata.config** is to be set as:

```
{
   "sourcingSettings": {
       "collection": {
           "maxDepth": 0,
           "objectType": "QuestionSet",
           "primaryCategory": "Practice Question Set",
           "isRoot": true,
           "iconClass": "fa fa-book",
           "children": {
               "Question": [
                   "Subjective Question"
               ]
           },
           "hierarchy": {}
       }
   }
}

```

### **2.) Configuration for Question Set with Sections.**

* For enabling creation of **"Multiple Choice Question"** (interactive question) in the Section of Question Set, **objectCategoryDefinition.objectMetadata.config** is to be set as:

```
{
   "sourcingSettings": {
       "collection": {
           "maxDepth": 1,
           "objectType": "QuestionSet",
           "primaryCategory": "Practice Question Set",
           "isRoot": true,
           "iconClass": "fa fa-book",
           "children": {},
           "hierarchy": {
               "level1": {
                   "name": "Section",
                   "type": "Unit",
                   "mimeType": "application/vnd.sunbird.questionset",
                   "primaryCategory": "Practice Question Set",
                   "iconClass": "fa fa-folder-o",
                   "children": {
                       "Question": [
                           "Multiple Choice Question"
                       ]
                   }
               }
           }
       }
   }
}
```

* For enabling creation of **"Subjective Question"** (non-interactive question) in the Section of Question Set, **objectCategoryDefinition.objectMetadata.config** is to be set as:

```
{
   "sourcingSettings": {
       "collection": {
           "maxDepth": 1,
           "objectType": "QuestionSet",
           "primaryCategory": "Practice Question Set",
           "isRoot": true,
           "iconClass": "fa fa-book",
           "children": {},
           "hierarchy": {
               "level1": {
                   "name": "Section",
                   "type": "Unit",
                   "mimeType": "application/vnd.sunbird.questionset",
                   "primaryCategory": "Practice Question Set",
                   "iconClass": "fa fa-folder-o",
                   "children": {
                       "Question": [
                           "Subjective Question"
                       ]
                   }
               }
           }
       }
   }
}

```

**Note:-** <mark style="color:red;">**It is recommended to add  children as either of these (and not to mix "Multiple Choice Question" and "Subjective Question" questions).**</mark>

```
"children": {
               "Question": [
                   "Multiple Choice Question"
               ]
             }
```

&#x20;or&#x20;

```
"children": {
               "Question": [
                   "Subjective Question"
               ]
             }
```


# Source Code

Here is the link to the source code. Currently, inQuiry leverages collection editor source code from Sunbird Knowlg for this purpose. This will be decoupled from Knowlg in the future.

{% embed url="<https://github.com/Sunbird-inQuiry/editor>" %}

## NPM Repository

**Web component**

{% embed url="<https://www.npmjs.com/package/@project-sunbird/sunbird-questionset-editor-web-component>" %}

**Angular library**

{% embed url="<https://www.npmjs.com/package/@project-sunbird/sunbird-questionset-editor>" fullWidth="false" %}


# APIs

Below are the list of APIs that is invoked from Editor

## Knowlg Service

Below are the set of APIs from Knowlg Service that QuML Editor is dependent on.

* [Channel Service](https://knowlg.sunbird.org/learn/product-and-developer-guide/editors/collection-editor-v2/apis#channel-service)
* [Media Service](https://knowlg.sunbird.org/learn/product-and-developer-guide/editors/collection-editor-v2/apis#media-service)
* [Framework Service](https://knowlg.sunbird.org/learn/product-and-developer-guide/editors/collection-editor-v2/apis#framework-service)
* [Assets Search Service](https://knowlg.sunbird.org/learn/product-and-developer-guide/editors/collection-editor-v2/apis#assets-search-service)
* [Object Category Service](https://knowlg.sunbird.org/learn/product-and-developer-guide/editors/collection-editor-v2/apis#object-category-service)
* [Content Service](https://knowlg.sunbird.org/learn/product-and-developer-guide/editors/collection-editor-v2/apis#content-service)

## InQuiry - QuestionSet APIs

Below are the set of QuestionSet APIs from inQuiry Service that QuML Editor is dependent on.

* QuestionSet Create
* QuestionSet Read
* QuestionSet Update
* QuestionSet Hierarchy Read
* QuestionSet Hierarchy Update
* QuestionSet Review
* QuestionSet Reject
* QuestionSet Publish
* QuestionSet System Update

Details of the APIs can be found [here](https://inquiry.sunbird.org/learn/product-and-developer-guide/question-and-question-set-service/apis/questionset-apis)

## InQuiry - Question APIs

Below are the set of Question APIs from inQuiry Service that QuML Editor is dependent on.

* Question Create
* Question Update
* Question List
* Question Read
* Question Review
* Question Publish
* Question Reject
* Question System Update

Details of the APIs can be found [here](https://inquiry.sunbird.org/learn/product-and-developer-guide/question-and-question-set-service/apis/question-apis)


# FAQ's

<details>

<summary>How to configure a new metadata field and define its attributes in the question set editor?</summary>

The config for new fields has to be added in the object category definition. This can be done at the system level or at the individual channel level.

Suppose you want to add a name field in the metadata field, it can be added as:

```
"objectCategoryDefinition": {
    "identifier": "obj-cat:practice-question-set_questionset_all",
    "objectMetadata": {
        "config": {
            ...
            ...
        },
        ...
        ...
    },
    ...
    "name": "Practice Question Set",
    "forms": {
        "create": {
            ...
            ...
            "properties": [
                {
                    "code": "name",
                    "dataType": "text",
                    "description": "Name of the Practice Question Set",
                    "editable": true,
                    "inputType": "text",
                    "label": "Name",
                    "name": "Name",
                    "placeholder": "Enter name of the question set",
                    "renderingHints": {
                        "class": "sb-g-col-lg-1 required"
                    },
                    "required": true,
                    "visible": true,
                    "validations": [
                        {
                            "type": "maxLength",
                            "value": "120",
                            "message": "Input is Exceeded"
                        },
                        {
                            "type": "required",
                            "message": "Name is required"
                        }
                    ]
                }
            ]
        }
    }
}
```

</details>

<details>

<summary>How to enable Submit page?</summary>

Submit page provides users the option to review their attempt details and submit the assessment.

To enable/disable the submit page in the player, we can add the requiresSubmit field in the meta form as:&#x20;

```
{
                    "code": "requiresSubmit",
                    "visible": true,
                    "editable": true,
                    "dataType": "text",
                    "name": "Submit Confirmation",
                    "renderingHints": {
                        "class": "sb-g-col-lg-1"
                    },
                    "description": "Submit Confirmation",
                    "inputType": "checkbox",
                    "label": "Submit Confirmation",
                    "placeholder": "Submit Confirmation",
                    "required": false
                }
```

</details>

<details>

<summary>How to configure attempts?</summary>

The number of times users can play the question set can be defined using the attribute called max attempt. We can add the requiresSubmit field in the meta form as:&#x20;

```
 {
                    "code": "maxAttempts",
                    "visible": true,
                    "editable": true,
                    "dataType": "number",
                    "name": "Max Attempts",
                    "renderingHints": {
                        "class": "sb-g-col-lg-1"
                    },
                    "description": "Max Attempts",
                    "inputType": "select",
                    "label": "Max Attempts",
                    "placeholder": "Max Attempts",
                    "required": false,
                    "range": [
                        1,
                        2,
                        3,
                        4,
                        5,
                        ..
                        ..
                    ]
                }
```

</details>

<details>

<summary>How to configure Timer for a question set?</summary>

The timer is one of the question set behavior fields. It can be updated on the root node of the question set i.e. on the create form of the question set as part of the question set object category definition.

Three attributes are there wrt to the timer:

* &#x20;max time
* warning time
* show timer

#### Max Time

```
{
                    "code": "maxTime",
                    "visible": true,
                    "editable": true,
                    "dataType": "text",
                    "name": "MaxTimer",
                    "renderingHints": {
                        "class": "sb-g-col-lg-1 required"
                    },
                    "description": "MaxTime for the content",
                    "inputType": "timer",
                    "label": "Max Time",
                    "placeholder": "HH:mm:ss",
                    "required": true,
                    "validations": [
                        {
                            "type": "required",
                            "message": "Maxtime is required"
                        },
                        {
                            "type": "maxTime",
                            "value": "05:30",
                            "message": "Maxtime should be less than or equal to 05:30"
                        },
                        {
                            "type": "minTime",
                            "value": "00:01",
                            "message": "Maxtime should be greater than 00:00"
                        }
                    ]
                }
```

#### Warning Time

```
{
                    "code": "warningTime",
                    "visible": true,
                    "editable": true,
                    "dataType": "list",
                    "name": "Warning Time",
                    "renderingHints": {
                        "class": "sb-g-col-lg-1"
                    },
                    "depends": [
                        "maxTime"
                    ],
                    "description": "warning for the content",
                    "inputType": "timer",
                    "label": "Warning Time",
                    "placeholder": "hh:mm:ss",
                    "required": false,
                    "validations": [
                        {
                            "type": "compare",
                            "criteria": {
                                "<=": [
                                    "maxTime"
                                ]
                            },
                            "message": "warning time should be less than max timer"
                        }
                    ],
                    "default": null
                }
```

#### Show Timer

```
{
                    "code": "showTimer",
                    "visible": false,
                    "editable": false,
                    "dataType": "text",
                    "default": "Yes",
                    "depends": [
                        "maxTime"
                    ],
                    "name": "Show Timer",
                    "renderingHints": {
                        "class": "sb-g-col-lg-1"
                    },
                    "description": "Show Timer",
                    "inputType": "checkbox",
                    "label": "Show Timer",
                    "placeholder": "Show Timer",
                    "required": false
                }
```

</details>

<details>

<summary>How to configure Section Level configurations?</summary>

Attributes/question set behaviour can be modified based on the section level as well. It can be updated in the object category definition of the question set under the unit metadata form. Under unit metadata, the attributes or the behavior can be defined. Each field has a code and it can be updated with the question set configuration.

* **Title** - Name of section
* **Description** - Description of section
* **Max Questions** - Max number of questions which can be shown in the section in the player.
* **Show Feedback** - Show feedback whether the answer chosen is right or wrong.
* **Shuffle Questions** - It shuffles the order of questions inside the section in the player
* **Show Solution** - If the solution is added to the questions and on enabling it give the option to show solution on question attempt.

Below is the config to the section form config:

```
"objectCategoryDefinition": {
    "identifier": "obj-cat:practice-question-set_questionset_all",
    "objectMetadata": {
        "config": {
            ...
            ...
        },
        ...
        ...
    },
    ...
    "name": "Practice Question Set",
    "forms": {
        "unitMetadata": {
            "templateName": "",
            "required": [],
            "properties": [
                {
                    "code": "name",
                    "dataType": "text",
                    "description": "Name of the content",
                    "editable": true,
                    "inputType": "text",
                    "label": "Title",
                    "name": "Title",
                    "placeholder": "Title",
                    "renderingHints": {
                        "class": "sb-g-col-lg-1 required"
                    },
                    "required": true,
                    "visible": true,
                    "validations": [
                        {
                            "type": "maxLength",
                            "value": "120",
                            "message": "Input is Exceeded"
                        },
                        {
                            "type": "required",
                            "message": "Title is required"
                        }
                    ]
                },
                {
                    "code": "description",
                    "dataType": "text",
                    "description": "Description of the content",
                    "editable": true,
                    "inputType": "textarea",
                    "label": "Description",
                    "name": "Description",
                    "placeholder": "Description",
                    "renderingHints": {
                        "class": "sb-g-col-lg-1 required"
                    },
                    "required": true,
                    "visible": true,
                    "validations": [
                        {
                            "type": "maxLength",
                            "value": "500",
                            "message": "Input is Exceeded"
                        }
                    ]
                },
                {
                    "code": "maxQuestions",
                    "name": "Show Questions",
                    "label": "Show Questions",
                    "placeholder": "Number of questions to be shown",
                    "description": "Number of questions to be shown",
                    "default": "",
                    "dataType": "number",
                    "inputType": "select",
                    "editable": true,
                    "required": false,
                    "visible": true,
                    "renderingHints": {
                        "class": "sb-g-col-lg-1"
                    }
                },
                {
                    "code": "showFeedback",
                    "name": "Show Feedback",
                    "label": "Show Feedback",
                    "placeholder": "Show Correct/Incorrect Feedback",
                    "description": "Show Correct/Incorrect Feedback",
                    "default": "Yes",
                    "dataType": "text",
                    "inputType": "checkbox",
                    "editable": true,
                    "required": false,
                    "visible": true,
                    "renderingHints": {
                        "class": "sb-g-col-lg-1"
                    }
                },
                {
                    "code": "shuffle",
                    "name": "Shuffle Questions",
                    "label": "Shuffle Questions",
                    "placeholder": "Shuffle Questions",
                    "description": "Questions will be Shuffled while playing",
                    "default": "false",
                    "dataType": "boolean",
                    "inputType": "checkbox",
                    "editable": true,
                    "required": false,
                    "visible": true,
                    "renderingHints": {
                        "class": "sb-g-col-lg-1"
                    }
                },
                {
                    "code": "showSolutions",
                    "name": "Show Solution",
                    "label": "Show Solution",
                    "placeholder": "Show Solution",
                    "description": "Show Solution",
                    "default": "Yes",
                    "dataType": "text",
                    "inputType": "checkbox",
                    "editable": true,
                    "required": false,
                    "visible": true,
                    "renderingHints": {
                        "class": "sb-g-col-lg-1"
                    }
                }
            ]
        }
    }
}
```

* **Max question within the section** - Number of questions that can be created under each section can be defined on the system level configuration in the git repo with the help of DevOps under sunbird\_questionset\_children\_limit: 10

</details>

<details>

<summary>How to configure Question Set TOC?</summary>

The maximum number of levels in the question set has to be defined using the max depth property. This has to be updated in the object metadata of the primary category definition under hierarchy.

If max depth is set as 1, then we need to add the hierarchy with level 1 node details with the default section name as:&#x20;

```
"objectCategoryDefinition": {
    "identifier": "obj-cat:practice-question-set_questionset_all",
    "objectMetadata": {
        "config": {
            "sourcingSettings": {
                "collection": {
                    "objectType": "QuestionSet",
                    "primaryCategory": "Practice Question Set",
                    "maxDepth": 1,
                    "isRoot": true,
                    "iconClass": "fa fa-book",
                    "children": {
                        "Question": [
                            "Multiple Choice Question",
                            "Subjective Question"
                        ]
                    },
                    "hierarchy": {
                        "level1": {
                            "name": "Section",
                            "type": "Unit",
                            "mimeType": "application/vnd.sunbird.questionset",
                            "primaryCategory": "Practice Question Set",
                            "iconClass": "fa fa-folder-o",
                            "children": {
                                "Question": [
                                    "Multiple Choice Question",
                                    "Subjective Question"
                                ]
                            }
                        }
                    }
                }
            }
        },
        "schema": {
            "properties": {
                "mimeType": {
                    "type": "string",
                    "enum": [
                        "application/vnd.sunbird.questionset"
                    ]
                }
            }
        }
    },
    ....
    ....
}
```

</details>

<details>

<summary>How to enable Question Creation?</summary>

To enable the question creation under each section or root node, the children field needs to be enabled with required question types under each required level node.&#x20;

Currentl&#x79;**,** in the system, we have MCQ and subjective questions.&#x20;

If the children field is made empty, then "Create New" button will not be enabled on the UI.

#### To enable question creation at root:

```
"objectCategoryDefinition": {
    "identifier": "obj-cat:practice-question-set_questionset_all",
    "objectMetadata": {
        "config": {
            "sourcingSettings": {
                "collection": {
                    "objectType": "QuestionSet",
                    "primaryCategory": "Practice Question Set",
                    "maxDepth": 1,
                    "isRoot": true,
                    "iconClass": "fa fa-book",
                    "children": {
                        "Question": [
                            "Multiple Choice Question",
                            "Subjective Question"
                        ]
                    }, // to enable question creation and type of question at root node
                    "hierarchy": {
                        "level1": {
                            ....
                            ....
                        }
                    }
                }
            }
        },
        "schema": {
            ...
            ...
        }
    },
    ....
    ....
}
```

#### To enable question creation at section level 1:

```
"objectCategoryDefinition": {
    "identifier": "obj-cat:practice-question-set_questionset_all",
    "objectMetadata": {
        "config": {
            "sourcingSettings": {
                "collection": {
                    ...
                    ...
                    "maxDepth": 1,
                    "isRoot": true,
                    ...
                    ...
                    },
                    "hierarchy": {
                        "level1": {
                            ...
                            ...
                            "children": {
                                "Question": [
                                    "Multiple Choice Question",
                                    "Subjective Question"
                                ]
                            } // to enable question creation and type of question at section1
                        }
                    }
                }
            }
        },
        "schema": {
            ...
            ...
        }
    },
    ....
    ....
}
```

</details>


# Question & Question Set Service

Question and Question set service is a micro-service which provides APIs to manage the lifecycle and workflows of creation and consumption of question & question set objects.

In the current implementation, the assessment APIs from Sunbird Knowlg are utilized for this purpose. (It will be decoupled and moved as part of inQuiry in the future.)

#### Capabilities:

1. Provides APIs to manage the lifecycle of Question Set(s).
2. Enables offline consumption via generation of ECAR files in the packaging stage of the publish lifecycle.
3. A Question/QuestionSet can have the below operation throughout its creation Lifecycle:

```
Create
Update
Review
Reject
Publish
Retire
Copy
```

**Question Lifecycle:**

**Create:**

* Question can be created using question create API with minimal data like name, code, mimeType, primaryCategory
* Using Question create API, only public (visibility=default), private and protected question can be created.
* In order to create a question (visibility: Parent) which can be discoverable only within a specific QuestionSet, Question asset should be created using QuestionSet update hierarchy API.
* Asset status will be Draft.

**Update:**

* Question asset having visibility other than Parent, metadata can be updated using question update api.
* Question asset having visibility Parent, metadata can be updated using QuestionSet update hierarchy api only.
* There is no change in asset status if update operation is applied on Non Published asset or Image Node of Published assset (if exist)
* Asset status will be changed from Live to Draft, if update operation is applied on Published Version of asset. System creates a copy of published asset and apply the update.
* The data of copied asset gets populated to the original asset and then copied asset gets deleted, when the updated copied asset goes for publish operation.

**Review:**

* Question assets having visibility other than `Parent`, can be sent for review using question review API.
* Question asset having visibility Parent, cannot be set for review individually using question review API. All Children Question with visibility Parent move to Review stage when Parent QuestionSet sent for Review using QuestionSet review API.
* Asset status changed from Draft to Review.
* Reviewer can review, once the asset is having Review status.
* Reviewer can either approve the asset (send for publish operation) or reject the asset (send for reject operation)

**Reject:**

* Question assets having visibility other than Parent, can be sent for reject using question reject API.
* Question asset having visibility Parent, cannot be set for reject using question reject API. All Children Question with visibility Parent Rejected automatically when Parent QuestionSet sent for Reject using QuestionSet reject API.
* Asset status will be changed to Review to Draft

**Publish:**

* Question asset having visibility other than Parent, can be sent for publish using question publish API.
* Question asset having visibility Parent, cannot be set for publish using question publish API. All Children Question with visibility Parent published automatically when Parent QuestionSet sent for Publish using QuestionSet publish API.
* On Completion of Publish operation :
  * Question asset will have Live status.
  * Question asset will have the bundle path for offline consumption (downloadUrl, variants (Multiple Packages such as spine, online, full) )
  * It can be discovered for consumption

**Retire:**

* Question asset can be sent for retire using question retire API.
* In this operation, logical delete operation is performed on the question asset. The asset status changed from Live to Retired.
* This operation can be performed on question asset having any status (e.g: Draft, Review)
* The Question asset having the status Retired can't be discovered for consumption/adoption.

**Copy:**

* Question asset having visibility other than Parent can be copied with question copy API.
* Question asset having visibility Parent cannot be copied individually and must be copied as part of questionSet copy.
* New asset status will be set as Draft.
* Fields "createdBy" and "createdFor" are mandatory and must be provided in the request.
* Any metadata field provided in the request will be updated in the metadata of the new asset.

**QuestionSet Lifecycle:**

**Create:**

* QuestionSet can be created using QuestionSet create API with minimal data like name, code, mimeType, primaryCategory.
* Using QuestionSet create API, only public, private and protected QuestionSet (visibility: Default, Private, Protected) can be created.
* In order to create QuestionSet (visibility: Parent) which can be discoverable only within specific QuestionSet (e.g: section/units), QuestionSet object should be created using QuestionSet update hierarchy API.
* QuestionSet asset status will be Draft

**Update:**

* QuestionSet asset having visibility other than Parent, object metadata except hierarchal data can be updated using QuestionSet update API.
* QuestionSet asset having visibility Parent, metadata can be updated using QuestionSet update hierarchy API only.
* QuestionSet and its own children metadata can be updated together using QuestionSet update hierarchy API.
* Any Change in the hierarchal structure like the addition of children or removal of children can be performed using QuestionSet update hierarchy API.
* Children can be added to QuestionSet using add node API and children can be removed using delete node API of QuestionSet. Only Public children can be added/removed using these API's.
* There is no change in asset status if update operation is applied on Non Published asset or Image Node of Published asset (if exist).
* Asset status will be changed from Live to `Draft`, if update operation is applied on Published Version of asset. System creates a copy of published asset and apply the update.
* The data of copied asset gets populated to the original asset and then copied asset gets deleted, when the updated copied asset goes for publish operation.

**Review:**

* QuestionSet asset having visibility other than Parent, can be sent for review using QuestionSet review API.
* QuestionSet asset having visibility Parent, cannot be set for review individually using QuestionSet review API. All Children QuestionSet/Question with visibility Parent move to Review stage when Parent/Root QuestionSet sent for Review using QuestionSet review API.
* QuestionSet asset status changed from Draft to Review
* Reviewer can review, once the asset is having Review status.
* Reviewer can either approve the asset (send for publish operation) or reject the asset (send for reject operation)

**Reject:**

* QuestionSet asset having visibility other than Parent, can be sent for reject using QuestionSet reject API.
* QuestionSet asset having visibility Parent, cannot be set for reject using QuestionSet reject API. All Children QuestionSet/Question with visibility Parent Rejected automatically when Parent QuestionSet sent for Reject using QuestionSet reject API.
* QuestionSet asset status will be changed to Review to Draft

**Publish:**

* QuestionSet asset having visibility other than Parent, can be sent for publish using QuestionSet publish API.
* QuestionSet asset having visibility Parent, cannot be set for publish using QuestionSet publish API. All Children QuestionSet/Question with visibility Parent published automatically when Parent/Root QuestionSet sent for Publish using QuestionSet publish API.
* On Completion of Publish operation,
  * QuestionSet asset will have Live status
  * QuestionSet asset will have the bundle path for offline consumption (downloadUrl, variants (Multiple Packages such as spine, online, full) )
  * Hierarchal Structure will be enriched and stored.
  * It can be discovered for consumption

**Retire:**

* QuestionSet asset can be sent for retire using QuestionSet retire API.
* In this operation, logical delete operation performed on the QuestionSet asset.
* The asset status changed from Live to Retired.
* This operation can be performed on QuestionSet asset having any status (e.g: Draft, Review)
* The QuestionSet asset having the status Retired can't be discovered for consumption/adoption.

**Copy:**

* QuestionSet asset can be copied with questionSet copy API.
* New asset and all sub-assets will have the status as Draft, except for sub-assets having the visibility Default.
* Fields "createdBy" and "createdFor" are mandatory and must be provided in the request.
* Any metadata field provided in the request will be updated in the metadata of the new asset.

#### For Source Code, Please use the below link:

{% embed url="<https://github.com/project-sunbird/knowledge-platform>" %}
Source Code
{% endembed %}


# Architecture

Below diagram represents the components involved and their arrangement in Question and Question set service.

1. The service module has play application and its internal actor module.&#x20;
2. Graph-engine acts as an interface between databases and service module

![inQuiry Backend Architecture and Tech Stack](https://3506001968-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FWu4HIWGkb7dD4y0Kup4W%2Fuploads%2FrA9rFcWflZ5JbOcENCbA%2FInQuiry%20Backend%20Architecture.png?alt=media\&token=a12df702-71d5-4f03-b3e5-80880cf6de15)


# Features

This Page Explains Features Available With Question & QuestionSet Service

Question & QuestionSet service is a micro-service which provides APIs to manage the lifecycle and workflows of creation and consumption of Question & QuestionSet Asset.

**Offline Consumption**

The Service enables offline consumption via generation of ECAR files in the packaging stage of the publish lifecycle. Assets can be download from ***downloadUrl***. Two ***variants*** of the ECAR are available for each Asset. i.e. FULL and SPINE. ECAR can be downloaded and extracted in client (mobile and desktop) to play offline.

```
"downloadUrl": "<full ecar url>",
"variants": {
    "full": {
        "ecarUrl": "<full ecar url>",
        "size": "<size in byte>"
    },
    "spine": {
        "ecarUrl": "<spine ecar url>",
        "size": "<size in byte>"
    },
}
```

**Online** **Consumption**

The Service enables online consumption via Question Read and List API's. Question List API provides all required data for multiple Question which player can directly render.

**Auto Review & Publish**

The Service offers QuestionSet Review API, which move all children question to Review stage automatically irrespective of children visibility (Parent/Default), if the creator of both Root QuestionSet and its children is same.

Similarly, the service offers QuestionSet Publish API, which publish its children automatically if children qualifies for auto publish. \
\
**Publish control**

Question & QuestionSet Asset publishing can be done in two ways: Public (status: Live) and Private (status: Unlisted). When the Asset status is ***Live**,* it  is available for consumption publicly. When the Asset status is ***Unlisted**,* it can be accessed only by direct content link (deep link).&#x20;

**Question & QuestionSet Life Cycle**

Below diagram illustrate the status and actions during the life cycle of Question & QuestionSet Asset

![](https://3506001968-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FWu4HIWGkb7dD4y0Kup4W%2Fuploads%2FOfU5fz8QZfAEtsneu6h9%2FGeneralisation%402x.png?alt=media\&token=d3bf9092-b7b2-43ec-a602-83b7eddbe481)

For More Information on Question & QuestionSet Life Cycle, Please check [here](/learn/product-and-developer-guide/question-and-question-set-service#features)


# Schema

Assessment Service Requires Schema For Question & QuestionSet asset Type. For Reference, Schema for both asset type is given here. \
\
Any Asset schema contains two files:\
&#x20;  1\. **schema.json** - This file contains all properties field and its data type\
&#x20;  2\. **config.json** - This file contains all configuration specific to asset type. e.g:    external table name, external field names and their data types, etc\
\
Schema for Question & QuestionSet can be also found [here](https://github.com/project-sunbird/knowledge-platform/tree/master/schemas/).<br>


# Question Schema

## **schema.json:**

```
{
  "$id": "question-schema.json",
  "$schema": "http://json-schema.org/draft-07/schema#",
  "title": "Question",
  "type": "object",
  "required": [
    "name",
    "code",
    "mimeType",
    "primaryCategory"
  ],
  "properties": {
    "name": {
      "type": "string",
      "minLength": 5
    },
    "code": {
      "type": "string"
    },
    "description": {
      "type": "string"
    },
    "mimeType": {
      "type": "string",
      "enum": [
        "application/vnd.sunbird.question"
      ]
    },
    "primaryCategory": {
      "type": "string"
    },
    "additionalCategories": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "visibility": {
      "type": "string",
      "default": "Default",
      "enum": [
        "Default",
        "Parent",
        "Private",
        "Protected"
      ]
    },
    "copyright": {
      "type": "string"
    },
    "license": {
      "type": "string",
      "default": "CC BY 4.0"
    },
    "lockKey": {
      "type": "string"
    },
    "assets": {
      "type": "array"
    },
    "audience": {
      "type": "array",
      "items": {
        "type": "string",
        "enum": [
          "Student",
          "Teacher",
          "Administrator",
          "Parent"
        ],
        "default": "Student"
      }
    },
    "author": {
      "type": "string"
    },
    "owner": {
      "type": "string"
    },
    "attributions": {
      "type": "array"
    },
    "consumerId": {
      "type": "string"
    },
    "contentEncoding": {
      "type": "string",
      "enum": [
        "gzip",
        "identity"
      ],
      "default": "gzip"
    },
    "contentDisposition": {
      "type": "string",
      "enum": [
        "inline",
        "online",
        "attachment",
        "online-only"
      ],
      "default": "inline"
    },
    "appIcon": {
      "type": "string",
      "format": "url"
    },
    "publishChecklist": {
      "type": "array"
    },
    "publishComment": {
      "type": "string"
    },
    "compatibilityLevel": {
      "type": "number",
      "default": 4
    },
    "status": {
      "type": "string",
      "enum": [
        "Draft",
        "Review",
        "Live",
        "Retired"
      ],
      "default": "Draft"
    },
    "prevState": {
      "type": "string"
    },
    "prevStatus": {
      "type": "string"
    },
    "lastStatusChangedOn": {
      "type": "string"
    },
    "keywords": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "pkgVersion": {
      "type": "number"
    },
    "version": {
      "type": "number",
      "default": 1
    },
    "versionKey": {
      "type": "string"
    },
    "language": {
      "type": "array",
      "items": {
        "type": "string",
        "enum": [
          "English",
          "Hindi",
          "Assamese",
          "Bengali",
          "Gujarati",
          "Kannada",
          "Malayalam",
          "Marathi",
          "Nepali",
          "Odia",
          "Punjabi",
          "Tamil",
          "Telugu",
          "Urdu",
          "Sanskrit",
          "Maithili",
          "Other"
        ]
      },
      "default": ["English"]
    },
    "languageCode": {
      "type": "array"
    },
    "channel": {
      "type": "string"
    },
    "framework": {
      "type": "string"
    },
    "subject" : {
      "type": "array"
    },
    "medium" : {
      "type": "array"
    },
    "board" : {
      "type": "string"
    },
    "gradeLevel" : {
      "type": "array"
    },
    "topic" : {
      "type": "array"
    },
    "boardIds": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "gradeLevelIds": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "subjectIds": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "mediumIds": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "topicsIds": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "targetFWIds": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "targetBoardIds": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "targetGradeLevelIds": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "targetSubjectIds": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "targetMediumIds": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "targetTopicIds": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "se_FWIds": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "se_boardIds": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "se_subjectIds": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "se_mediumIds": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "se_topicIds": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "se_gradeLevelIds": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "se_boards": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "se_subjects": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "se_mediums": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "se_topics": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "se_gradeLevels": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "createdOn": {
      "type": "string"
    },
    "createdFor": {
      "type": "array"
    },
    "createdBy": {
      "type": "string"
    },
    "artifactUrl": {
      "type": "string",
      "format": "url"
    },
    "lastUpdatedOn": {
      "type": "string"
    },
    "lastUpdatedBy": {
      "type": "string"
    },
    "lastSubmittedOn": {
      "type": "string"
    },
    "lastSubmittedBy": {
      "type": "string"
    },
    "publisher": {
      "type": "string"
    },
    "lastPublishedOn": {
      "type": "string"
    },
    "lastPublishedBy": {
      "type": "string"
    },
    "publishError": {
      "type": "string"
    },
    "reviewError": {
      "type": "string"
    },

    "body": {
      "type": "string",
      "description": "External Property"
    },
    "editorState": {
      "type": "object",
      "description": "External Property"
    },
    "answer": {
      "type": "string",
      "description": "External Property"
    },
    "solutions": {
      "type": "array",
      "items": {
        "type": "string"
      },
      "description": "External Property"
    },
    "instructions": {
      "type": "object",
      "description": "External Property"
    },
    "hints": {
      "type": "array",
      "items": {
        "type": "string"
      },
      "description": "External Property"
    },
    "media": {
      "type": "array",
      "items": {
        "type": "object"
      },
      "description": "External Property"
    },
    "responseDeclaration": {
      "type": "object",
      "description": "External Property"
    },
    "interactions": {
      "type": "object",
      "description": "External Property"
    },


    "qType": {
      "type": "string",
      "enum": [
        "MCQ",
        "FTB",
        "SA"
      ]
    },
    "scoringMode": {
      "type": "string",
      "enum": [
        "system",
        "none"
      ]
    },
    "qumlVersion": {
      "type": "number"
    },
    "timeLimit": {
      "type": "number"
    },
    "maxScore": {
      "type": "number"
    },
    "showTimer": {
      "type": "string",
      "enum": [
        "Yes",
        "No"
      ],
      "default": "No"
    },
    "showFeedback": {
      "type": "string",
      "enum": [
        "Yes",
        "No"
      ],
      "default": "No"
    },
    "showSolutions": {
      "type": "string",
      "enum": [
        "Yes",
        "No"
      ],
      "default": "No"
    },
    "interactionTypes":{
      "type": "array",
      "items": {
        "type": "string",
        "enum": [
          "choice",
          "text",
          "select",
          "date",
          "file-upload",
          "canvas"
        ]
      }
    },
    "templateId":{
      "type": "string"
    },
    "bloomsLevel" : {
      "description": "Cognitive processes involved to answer the question set.",
      "type": "string",
      "enum": [
        "remember",
        "understand",
        "apply",
        "analyse",
        "evaluate",
        "create"
      ]
    },
    "feedback": {
      "type": "object"
    },
    "responseProcessing": {
      "type": "object"
    },
    "templateDeclaration": {
      "type": "object"
    },

    "dailySummaryReportEnabled": {
      "type": "string",
      "enum": [
        "Yes",
        "No"
      ]
    },
    "allowAnonymousAccess": {
      "type": "string",
      "enum": [
        "Yes",
        "No"
      ],
      "default": "Yes"
    },
    "termsAndConditions": {
      "type": "string"
    },
    "expectedDuration": {
      "type": "number"
    },
    "completionCriteria": {
      "type": "object"
    },
    "collaborators": {
      "type": "array"
    },
    "semanticVersion": {
      "type": "string"
    },
    "schemaVersion": {
      "type": "string"
    },
    "requestChanges": {
      "type": "string"
    },
    "variants": {
      "type": "object"
    },
    "rejectComment": {
      "type": "string"
    }
  },
  "additionalProperties": false
}
```

## **config.json:**

```
{
  "objectType": "Question",
  "relations": {
    "questionSet": {
      "type": "hasSequenceMember",
      "direction": "in",
      "objects": ["QuestionSet", "QuestionSetImage"]
    }
  },
  "restrictProps": {
    "create" : [
    ],
    "update" : [
      "visibility", "code", "status", "mimeType"
    ]
  },
  "version": "enable",
  "versionCheckMode": "ON",
  "frameworkCategories": ["board","medium","subject","gradeLevel","topic"],
  "orgFrameworkTerms": ["boardIds", "gradeLevelIds", "subjectIds", "mediumIds", "topicsIds"],
  "targetFrameworkTerms": ["targetFWIds", "targetBoardIds", "targetGradeLevelIds", "targetSubjectIds", "targetMediumIds", "targetTopicIds"],
  "cacheEnabled": false,
  "schema_restrict_api": true,
  "external": {
    "tableName": "question_data",
    "properties": {
      "body": {
        "type": "blob"
      },
      "editorState": {
        "type": "string"
      },
      "answer": {
        "type": "blob"
      },
      "solutions": {
        "type": "string"
      },
      "instructions": {
        "type": "string"
      },
      "hints": {
        "type": "string"
      },
      "media": {
        "type": "string"
      },
      "responseDeclaration": {
        "type": "string"
      },
      "interactions": {
        "type": "string"
      }
    },
    "primaryKey": ["identifier"]
  }
}
```


# QuestionSet Schema

## schema.json:

```
{
  "$id": "questionset-schema.json",
  "$schema": "http://json-schema.org/draft-07/schema#",
  "title": "QuestionSet",
  "type": "object",
  "required": [
    "name",
    "code",
    "mimeType",
    "primaryCategory"
  ],
  "properties": {
    "name": {
      "type": "string",
      "minLength": 5
    },
    "code": {
      "type": "string"
    },
    "description": {
      "type": "string"
    },
    "mimeType": {
      "type": "string",
      "enum": [
        "application/vnd.sunbird.questionset"
      ]
    },
    "primaryCategory": {
      "type": "string"
    },
    "additionalCategories": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "visibility": {
      "type": "string",
      "default": "Default",
      "enum": [
        "Default",
        "Parent",
        "Private",
        "Protected"
      ]
    },
    "copyright": {
      "type": "string"
    },
    "license": {
      "type": "string",
      "default": "CC BY 4.0"
    },
    "lockKey": {
      "type": "string"
    },
    "assets": {
      "type": "array"
    },
    "audience": {
      "type": "array",
      "items": {
        "type": "string",
        "enum": [
          "Student",
          "Teacher",
          "Administrator",
          "Parent"
        ],
        "default": "Student"
      }
    },
    "posterImage": {
      "type": "string",
      "format": "url"
    },
    "author": {
      "type": "string"
    },
    "owner": {
      "type": "string"
    },
    "attributions": {
      "type": "array"
    },
    "consumerId": {
      "type": "string"
    },
    "contentEncoding": {
      "type": "string",
      "enum": [
        "gzip",
        "identity"
      ],
      "default": "gzip"
    },
    "contentDisposition": {
      "type": "string",
      "enum": [
        "inline",
        "online",
        "attachment",
        "online-only"
      ],
      "default": "inline"
    },
    "appIcon": {
      "type": "string",
      "format": "url"
    },
    "publishChecklist": {
      "type": "array"
    },
    "publishComment": {
      "type": "string"
    },
    "compatibilityLevel": {
      "type": "number",
      "default": 5
    },
    "childNodes": {
      "type": "array"
    },
    "depth": {
      "type": "number"
    },
    "index": {
      "type": "number"
    },
    "parent": {
      "type": "string"
    },
    "downloadUrl": {
      "type": "string",
      "format": "url"
    },
    "previewUrl": {
      "type": "string",
      "format": "url"
    },
    "pdfUrl": {
      "type": "string",
      "format": "url"
    },
    "variants": {
      "type": "object"
    },
    "size": {
      "type": "number"
    },
    "checksum": {
      "type": "string"
    },
    "status": {
      "type": "string",
      "enum": [
        "Draft",
        "Review",
        "Live",
        "Retired"
      ],
      "default": "Draft"
    },
    "prevState": {
      "type": "string"
    },
    "prevStatus": {
      "type": "string"
    },
    "lastStatusChangedOn": {
      "type": "string"
    },
    "keywords": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "pkgVersion": {
      "type": "number"
    },
    "version": {
      "type": "number",
      "default": 1
    },
    "versionKey": {
      "type": "string"
    },
    "language": {
      "type": "array",
      "items": {
        "type": "string",
        "enum": [
          "English",
          "Hindi",
          "Assamese",
          "Bengali",
          "Gujarati",
          "Kannada",
          "Malayalam",
          "Marathi",
          "Nepali",
          "Odia",
          "Punjabi",
          "Tamil",
          "Telugu",
          "Urdu",
          "Sanskrit",
          "Maithili",
          "Other"
        ]
      },
      "default": ["English"]
    },
    "languageCode": {
      "type": "array"
    },
    "channel": {
      "type": "string"
    },
    "framework": {
      "type": "string"
    },
    "subject" : {
      "type": "array"
    },
    "medium" : {
      "type": "array"
    },
    "board" : {
      "type": "string"
    },
    "gradeLevel" : {
      "type": "array"
    },
    "topic" : {
      "type": "array"
    },
    "boardIds": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "gradeLevelIds": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "subjectIds": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "mediumIds": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "topicsIds": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "targetFWIds": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "targetBoardIds": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "targetGradeLevelIds": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "targetSubjectIds": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "targetMediumIds": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "targetTopicIds": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "se_FWIds": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "se_boardIds": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "se_subjectIds": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "se_mediumIds": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "se_topicIds": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "se_gradeLevelIds": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "se_boards": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "se_subjects": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "se_mediums": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "se_topics": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "se_gradeLevels": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "createdOn": {
      "type": "string"
    },
    "createdFor": {
      "type": "array"
    },
    "createdBy": {
      "type": "string"
    },
    "lastUpdatedOn": {
      "type": "string"
    },
    "lastUpdatedBy": {
      "type": "string"
    },
    "lastSubmittedOn": {
      "type": "string"
    },
    "lastSubmittedBy": {
      "type": "string"
    },
    "publisher": {
      "type": "string"
    },
    "lastPublishedOn": {
      "type": "string"
    },
    "lastPublishedBy": {
      "type": "string"
    },
    "publishError": {
      "type": "string"
    },
    "reviewError": {
      "type": "string"
    },
    "dailySummaryReportEnabled": {
      "type": "string",
      "enum": [
        "Yes",
        "No"
      ]
    },
    "allowAnonymousAccess": {
      "type": "string",
      "enum": [
        "Yes",
        "No"
      ],
      "default": "Yes"
    },
    "termsAndConditions": {
      "type": "string"
    },
    "expectedDuration": {
      "type": "number"
    },
    "completionCriteria": {
      "type": "object"
    },
    "collaborators": {
      "type": "array"
    },
    "semanticVersion": {
      "type": "string"
    },
    "schemaVersion": {
      "type": "string"
    },
    "maxScore": {
      "type": "number"
    },
    "setType": {
      "type": "string",
      "enum": [
        "materialised",
        "dynamic"
      ],
      "default": "materialised"
    },
    "setCriteria": {
      "type": "object"
    },
    "feedback": {
      "type": "object"
    },
    "scoringMode": {
      "type": "string",
      "enum": [
        "system",
        "none"
      ]
    },
    "qumlVersion": {
      "type": "number"
    },
    "timeLimits": {
      "type": "object"
    },
    "showTimer": {
      "type": "string",
      "enum": [
        "Yes",
        "No"
      ],
      "default": "No"
    },
    "showHints": {
      "type": "string",
      "enum": [
        "Yes",
        "No"
      ],
      "default": "No"
    },
    "showFeedback": {
      "type": "string",
      "enum": [
        "Yes",
        "No"
      ],
      "default": "No"
    },
    "showSolutions": {
      "type": "string",
      "enum": [
        "Yes",
        "No"
      ],
      "default": "No"
    },
    "bloomsLevel" : {
      "description": "Cognitive processes involved to answer the question set.",
      "type": "string",
      "enum": [
        "remember",
        "understand",
        "apply",
        "analyse",
        "evaluate",
        "create"
      ]
    },
    "navigationMode": {
      "type": "string",
      "enum": [
        "linear",
        "non-linear"
      ],
      "default": "non-linear"
    },
    "allowSkip": {
      "type": "string",
      "enum": [
        "Yes",
        "No"
      ],
      "default": "Yes"
    },
    "outcomeProcessing": {
      "type": "object"
    },
    "requiresSubmit": {
      "type": "string",
      "enum": [
        "Yes",
        "No"
      ],
      "default": "No"
    },
    "summaryType": {
      "type": "string",
      "enum": [
        "Complete",
        "Score",
        "Duration",
        "Score & Duration"
      ]
    },
    "shuffle": {
      "type": "boolean",
      "default": true
    },
    "totalQuestions": {
      "type": "number"
    },
    "maxQuestions": {
      "type": "number"
    },
    "containsUserData": {
      "type": "string",
      "enum": [
        "Yes",
        "No"
      ],
      "default": "No"
    },
    "maxAttempts": {
      "type": "number"
    },
    "instructions": {
      "type": "object",
      "description": "External Property"
    },
    "requestChanges": {
      "type": "string"
    },
    "generateDIALCodes": {
      "type": "string",
      "enum": [
        "Yes",
        "No"
      ],
      "default": "No"
    },
    "rejectComment": {
      "type": "string"
    }
  },
  "additionalProperties": false
}

```

## config.json

```
{
  "objectType": "QuestionSet",
  "relations": {
    "children": {
      "type": "hasSequenceMember",
      "direction": "out",
      "objects": [
        "Question",
        "QuestionImage",
        "QuestionSet",
        "QuestionSetImage"
      ]
    },
    "collection": {
      "type": "hasSequenceMember",
      "direction": "in",
      "objects": [
        "QuestionSet",
        "QuestionSetImage"
      ]
    }
  },
  "version": "enable",
  "versionCheckMode": "OFF",
  "frameworkCategories": [
    "board",
    "medium",
    "subject",
    "gradeLevel",
    "topic"
  ],
  "orgFrameworkTerms": [
    "boardIds",
    "gradeLevelIds",
    "subjectIds",
    "mediumIds",
    "topicsIds"
  ],
  "targetFrameworkTerms": [
    "targetFWIds",
    "targetBoardIds",
    "targetGradeLevelIds",
    "targetSubjectIds",
    "targetMediumIds",
    "targetTopicIds"
  ],
  "cacheEnabled": false,
  "schema_restrict_api": true,
  "restrictProps": {
    "create": [
      "children"
    ],
    "update": [
      "children",
      "visibility",
      "code",
      "status",
      "mimeType"
    ],
    "updateHierarchy": [
      "variants",
      "config",
      "reservedDialcodes"
    ]
  },
  "external": {
    "tableName": "questionset_hierarchy",
    "properties": {
      "hierarchy": {
        "type": "string"
      },
      "instructions": {
        "type": "string"
      }
    },
    "primaryKey": [
      "identifier"
    ]
  }
}

```


# APIs

This page provides details about Question & QuestionSet API's

Question & QuestionSet Service has the API's to manage Question & QuestionSet type Asset.

{% content-ref url="/pages/C3ZfONcpDelE32QkNri9" %}
[V1](/learn/product-and-developer-guide/question-and-question-set-service/apis/v1)
{% endcontent-ref %}

{% content-ref url="/pages/nvOpAvwF4kksa1QksNnG" %}
[V2](/learn/product-and-developer-guide/question-and-question-set-service/apis/v2)
{% endcontent-ref %}

{% embed url="<https://youtu.be/yoHBowTh4OQ?si=wO5aqNrp_H9ieLff&t=919>" %}


# V1

Captures information about the v1 APIs

Question & QuestionSet Service has below API's to manage Question & QuestionSet type Asset.

### **Question Management API's**

{% content-ref url="/pages/n3bSsGC8Wyuf0oYZRYsa" %}
[Create Question](/learn/product-and-developer-guide/question-and-question-set-service/apis/v1/question-apis/create-question)
{% endcontent-ref %}

{% content-ref url="/pages/Yqgw1f2dXaT5DzFKQJdq" %}
[Update Question](/learn/product-and-developer-guide/question-and-question-set-service/apis/v1/question-apis/update-question)
{% endcontent-ref %}

{% content-ref url="/pages/bAST7fqEvLR1GCZCZfJg" %}
[Read Question](/learn/product-and-developer-guide/question-and-question-set-service/apis/v1/question-apis/read-question)
{% endcontent-ref %}

{% content-ref url="/pages/2CIiM09hjd6uS9rnv8bp" %}
[Read Private Question](/learn/product-and-developer-guide/question-and-question-set-service/apis/v1/question-apis/read-private-question)
{% endcontent-ref %}

{% content-ref url="/pages/rJZha7lqfpb5cbKJLAoz" %}
[Submit for Review Question](/learn/product-and-developer-guide/question-and-question-set-service/apis/v1/question-apis/submit-for-review-question)
{% endcontent-ref %}

{% content-ref url="/pages/es8GDxDOFPwXFoicNL9K" %}
[Reject Question](/learn/product-and-developer-guide/question-and-question-set-service/apis/v1/question-apis/reject-question)
{% endcontent-ref %}

{% content-ref url="/pages/uhuq1ejFnwRi67hR1fkL" %}
[Publish Question](/learn/product-and-developer-guide/question-and-question-set-service/apis/v1/question-apis/publish-question)
{% endcontent-ref %}

{% content-ref url="/pages/Y2tPvAq6bG2Lc8hXgJbL" %}
[Retire Question](/learn/product-and-developer-guide/question-and-question-set-service/apis/v1/question-apis/retire-question)
{% endcontent-ref %}

{% content-ref url="/pages/100V9OqZaPFXQ6l54fmR" %}
[Question List](/learn/product-and-developer-guide/question-and-question-set-service/apis/v1/question-apis/question-list)
{% endcontent-ref %}

{% content-ref url="/pages/qv4fev2OReDbOisDTA2T" %}
[Import Question](/learn/product-and-developer-guide/question-and-question-set-service/apis/v1/question-apis/import-question)
{% endcontent-ref %}

{% content-ref url="/pages/zkaCe4gx3zFdJ8H9wjpR" %}
[Copy Question](/learn/product-and-developer-guide/question-and-question-set-service/apis/v1/question-apis/copy-question)
{% endcontent-ref %}

### **Question Set Management API's**

{% content-ref url="/pages/8nLajYRvfy6PdFzU88hT" %}
[Create QuestionSet](/learn/product-and-developer-guide/question-and-question-set-service/apis/v1/questionset-apis/create-questionset)
{% endcontent-ref %}

{% content-ref url="/pages/mKGkv0B3dwUmlqh4Ugjt" %}
[Update QuestionSet](/learn/product-and-developer-guide/question-and-question-set-service/apis/v1/questionset-apis/update-questionset)
{% endcontent-ref %}

{% content-ref url="/pages/TI6hjzfmUDsK2sREZ4Mg" %}
[Read QuestionSet](/learn/product-and-developer-guide/question-and-question-set-service/apis/v1/questionset-apis/read-questionset)
{% endcontent-ref %}

{% content-ref url="/pages/F0c8nbKbOZVWcGKSSF2s" %}
[Read Private QuestionSet](/learn/product-and-developer-guide/question-and-question-set-service/apis/v1/questionset-apis/read-private-questionset)
{% endcontent-ref %}

{% content-ref url="/pages/xVgIIQUnFizup7vzVJIs" %}
[Review QuestionSet](/learn/product-and-developer-guide/question-and-question-set-service/apis/v1/questionset-apis/review-questionset)
{% endcontent-ref %}

{% content-ref url="/pages/qKVtq0AuwKYavzo8YyP4" %}
[Reject QuestionSet](/learn/product-and-developer-guide/question-and-question-set-service/apis/v1/questionset-apis/reject-questionset)
{% endcontent-ref %}

{% content-ref url="/pages/H0FeAB5PegsBzZgGx4oL" %}
[Publish QuestionSet](/learn/product-and-developer-guide/question-and-question-set-service/apis/v1/questionset-apis/publish-questionset)
{% endcontent-ref %}

{% content-ref url="/pages/kZcll5nUTQ8Vd0lwwI3b" %}
[Retire QuestionSet](/learn/product-and-developer-guide/question-and-question-set-service/apis/v1/questionset-apis/retire-questionset)
{% endcontent-ref %}

{% content-ref url="/pages/RdBZEqIkOMe0TreeNLCQ" %}
[Import QuestionSet](/learn/product-and-developer-guide/question-and-question-set-service/apis/v1/questionset-apis/import-questionset)
{% endcontent-ref %}

{% content-ref url="/pages/umVE1j3Y4vU7cO7JjXiz" %}
[Update Hierarchy QuestionSet](/learn/product-and-developer-guide/question-and-question-set-service/apis/v1/questionset-apis/update-hierarchy-questionset)
{% endcontent-ref %}

{% content-ref url="/pages/l2VrjnSVN3l3u4wgrqpQ" %}
[Read QuestionSet Hierarchy](/learn/product-and-developer-guide/question-and-question-set-service/apis/v1/questionset-apis/read-questionset-hierarchy)
{% endcontent-ref %}

{% content-ref url="/pages/nL045W4qNyj68P3mDpGP" %}
[Copy QuestionSet](/learn/product-and-developer-guide/question-and-question-set-service/apis/v1/questionset-apis/copy-questionset)
{% endcontent-ref %}


# Question API's

List of question related API's


# Create Question

This API is used to create Questions on the Sunbird-inQuiry Platform.

## This API is used to create Question on the Sunbird-inQuiry Platform.

<mark style="color:green;">`POST`</mark> `/question/v1/create`

• It points to inquiry-api-service (assessment service) - <mark style="color:orange;">/question/v4/create</mark>\
• It is mandatory to provide values for parameters marked with <mark style="color:red;">\*</mark>.\
• Mandatory fields cannot be null or empty.\
• Question schema check [here](https://github.com/project-sunbird/knowledge-platform/blob/release-4.4.0/schemas/question/1.0/schema.json)\
• Appropriate fields need to be passed to work questions functionally well.

#### Headers

| Name                                            | Type   | Description                                                                                                                                                                                                                                                |
| ----------------------------------------------- | ------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Content-Type<mark style="color:red;">\*</mark>  | String | The Content-Type entity is the media type of the resource. It should be<mark style="color:green;">`Application/json`</mark>                                                                                                                                |
| Authorization<mark style="color:red;">\*</mark> | String | <p>You require authorization to make use of the API. Raise a request to the administrator for the use of the API. You will receive the authorization key. Specify the key received, here.<br>Set <mark style="color:green;">Bearer {{api\_key}}</mark></p> |
| x-channel-id                                    | String | Unique identification number associated with a root organization.                                                                                                                                                                                          |

#### Request Body

| Name                                      | Type   | Description                                                                                                                                                                                          |
| ----------------------------------------- | ------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| request<mark style="color:red;">\*</mark> | object | <p><mark style="color:orange;"><code>request</code></mark> is the representation of the resource object for creating questions, which is an object of parameters that describes the question<br></p> |

{% tabs %}
{% tab title="200: OK The Create Question operation was successful!" %}
{% code overflow="wrap" %}

```javascript
{
  "id": "api.question.create",
  "ver": "3.0",
  "ts": "2021-02-02T19:28:24ZZ",
  "params": {
    "resmsgid": "8b75d237-1028-4e38-a94a-9ff4ca784d76",
    "msgid": null,
    "err": null,
    "status": "successful",
    "errmsg": null
  },
  "responseCode": "OK",
  "result": {
    "identifier": "do_11320791330308096015",
    "versionKey": "1612294104382"
  }
}
```

{% endcode %}
{% endtab %}

{% tab title="400: Bad Request The Create Question operation failed. You may have missed providing input for a mandatory parameter.'" %}

```javascript
{
  "id": "api.question.create",
  "ver": "3.0",
  "ts": "2021-02-02T19:41:56ZZ",
  "params": {
    "resmsgid": "86481a2f-513e-4fd4-a1dd-46a7ebcb1e65",
    "msgid": null,
    "err": "CLIENT_ERROR",
    "status": "failed",
    "errmsg": "Validation Errors"
  },
  "responseCode": "CLIENT_ERROR",
  "result": {
    "messages": [
      "Metadata mimeType should be one of: [application/vnd.sunbird.question]"
    ]
  }
}
```

{% endtab %}

{% tab title="500: Internal Server Error We track these errors automatically and try to set it right at the earliest. Try refreshing the page." %}

```javascript
{
  "id": "api.question.create",
  "ver": "1.0",
  "ts": "2020-12-10T08:51:51.647Z",
  "params": {
    "resmsgid": "f234a6f0-3ac4-11eb-b0a2-8d5c9f561887",
    "msgid": null,
    "status": "failed",
    "err": null,
    "errmsg": null
  },
  "responseCode": "SERVER_ERROR",
  "result": {}
}
```

{% endtab %}
{% endtabs %}

#### Sample Request

```
{
    "request": {
        "question": {
            "name": "string",
            "code": "string",
            "mimeType": "string",
            "primaryCategory": "string"
        }
    }
```

#### Request Schema

<table><thead><tr><th width="182">Attribute</th><th width="104">Type</th><th width="249.33333333333331">Description</th><th>Required</th></tr></thead><tbody><tr><td>name</td><td>String</td><td>Represents the name of the question</td><td>Yes</td></tr><tr><td>code</td><td>String</td><td>Represents the unique code for the question</td><td>Yes</td></tr><tr><td>mimeType</td><td>String</td><td>Question mime type</td><td>Yes</td></tr><tr><td>primaryCategory</td><td>String</td><td>PrimaryCategory agains which question schema will be validated</td><td>Yes</td></tr></tbody></table>

#### Success Result Schema

<table><thead><tr><th width="156">Attribute</th><th width="112.33333333333331">Type</th><th width="345.6666666666667">Description</th></tr></thead><tbody><tr><td>identifier</td><td>String</td><td>Unique Question Identifier</td></tr><tr><td>versionKey</td><td>String</td><td>Unique version key of Question</td></tr></tbody></table>

#### cURL:

```json
curl --location -g --request POST '{{host}}/question/v1/create' \
--header 'Content-Type: application/json' \
--header 'X-Channel-Id: {{channel_id}}' \
--header 'Authorization: Bearer {{api_key}}' \
--data-raw '{
    "request": {
        "question": {
            "name": "Question 1",
            "code": "question.code",
            "mimeType": "application/vnd.sunbird.question",
            "primaryCategory": "Subjective Question"
        }
    }
}'
```

#### Full Request Example

Following is the complete request example of creating **Multiple Choice Questions (MCQ).**&#x20;

This includes all the required fields to create a question object, as well as to work this question functionally some other fields were also added such as `editorState`, `responseDeclaration`, `qType` etc.

```json
{
  "question": {
    "code": "f23d981a-e1db-2753-ebf3-f2a20c1578e3",
    "mimeType": "application/vnd.sunbird.question",
    "media": [],
    "editorState": {
      "options": [
        {
          "answer": true,
          "value": {
            "body": "<p>answer1</p>",
            "value": 0
          }
        },
        {
          "answer": false,
          "value": {
            "body": "<p>answer2</p>",
            "value": 1
          }
        },
        {
          "answer": false,
          "value": {
            "body": "<p>answer3</p>",
            "value": 2
          }
        },
        {
          "answer": false,
          "value": {
            "body": "<p>answer4</p>",
            "value": 3
          }
        }
      ],
      "question": "<p>question</p>"
    },
    "templateId": "mcq-vertical",
    "answer": "0",
    "bloomsLevel": "application",
    "maxScore": 1,
    "name": "1",
    "responseDeclaration": {
      "response1": {
        "maxScore": 1,
        "cardinality": "single",
        "type": "integer",
        "correctResponse": {
          "value": "0",
          "outcomes": {
            "SCORE": 1
          }
        },
        "mapping": []
      }
    },
    "interactionTypes": [
      "choice"
    ],
    "interactions": {
      "response1": {
        "type": "choice",
        "options": [
          {
            "label": "<p>answer1</p>",
            "value": 0
          },
          {
            "label": "<p>answer2</p>",
            "value": 1
          },
          {
            "label": "<p>answer3</p>",
            "value": 2
          },
          {
            "label": "<p>answer4</p>",
            "value": 3
          }
        ]
      }
    },
    "qType": "MCQ",
    "primaryCategory": "Multiple Choice Question",
    "body": "<div class='question-body' tabindex='-1'><div class='mcq-title' tabindex='0'><p>question</p></div><div data-choice-interaction='response1' class='mcq-vertical'></div></div>",
    "solutions": [],
    "creator": "N118",
    "createdBy": "b6640bfe-e294-4a54-8c75-589472324624",
    "board": "CBSE",
    "medium": [
      "English"
    ],
    "gradeLevel": [
      "Class 2"
    ],
    "subject": [
      "Mathematics"
    ],
    "author": "n11@yopmail.com",
    "channel": "01309282781705830427",
    "framework": "ekstep_ncert_k-12",
    "copyright": "NIT123",
    "audience": [
      "Student"
    ],
    "license": "CC BY 4.0",
    "programId": "18730310-5144-11ed-be8b-9962d8844469",
    "collectionId": "do_11365081180508160011559",
    "organisationId": "e7328d77-42a7-44c8-84f4-8cfea235f07d",
    "topic": [
      "Grouping and Counting"
    ],
    "isReviewModificationAllowed": false
  }
}
```


# Read Question

This API is used to read the question on the Sunbird-inQuiry Platform.

## This API is used to read the question on the Sunbird-inQuiry Platform.

<mark style="color:blue;">`GET`</mark> `/question/v1/read/{Question_Id}`

• It points to inquiry-api-service (assessment service)  - <mark style="color:orange;">`/question/v4/read`</mark>\
• You need to provide a valid Question Id value in <mark style="color:orange;">{Question\_Id}</mark> field of the API URL.\
• It is mandatory to provide values for parameters marked with <mark style="color:red;">\*</mark>.\
• Mandatory fields cannot be null or empty.

#### Path Parameters

| Name                                           | Type   | Description                                   |
| ---------------------------------------------- | ------ | --------------------------------------------- |
| Question\_Id<mark style="color:red;">\*</mark> | String | Append a valid Question ID To the Request URL |

#### Query Parameters

| Name                                  | Type   | Description                                                                                   |
| ------------------------------------- | ------ | --------------------------------------------------------------------------------------------- |
| mode=edit                             | String | To fetch the latest version of node from the database for edit purpose                        |
| fields=comma separated metadata names | String | To fetch the specific fields, this query parameter can be used eg. fields=name,body,answer... |

#### Headers

| Name                                            | Type   | Description                                                                                                                                                                                                                                                     |
| ----------------------------------------------- | ------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Content-Type                                    | String | The Content-Type entity is the media type of the resource. It should be <mark style="color:green;">Application/json</mark>                                                                                                                                      |
| Authorization<mark style="color:red;">\*</mark> | String | <p>To make use of the API, you require authorization. Raise a request to the administrator, for the use of the API. You will receive the authorization key. Specify the key received, here.</p><p>Set <mark style="color:green;">Bearer {{api\_key}}</mark></p> |
| x-channel-id                                    | String | Unique identification number associated with a root organization.                                                                                                                                                                                               |

{% tabs %}
{% tab title="200: OK Successful operation" %}
{% code overflow="wrap" %}

```javascript
{
  "id": "api.question.read",
  "ver": "3.0",
  "ts": "2022-12-22T10:50:02ZZ",
  "params": {
    "resmsgid": "47933f43-3aa0-42cf-8eda-495993039869",
    "msgid": null,
    "err": null,
    "status": "successful",
    "errmsg": null
  },
  "responseCode": "OK",
  "result": {
    "question": {
      "copyright": "NIT123",
      "subject": [
        "Mathematics"
      ],
      "isReviewModificationAllowed": false,
      "responseDeclaration": {
        "response1": {
          "maxScore": 2,
          "cardinality": "single",
          "type": "integer",
          "correctResponse": {
            "value": "0",
            "outcomes": {
              "SCORE": 2
            }
          },
          "mapping": [

          ]
        }
      },
      "mimeType": "application/vnd.sunbird.question",
      "body": "<div class='question-body' tabindex='-1'><div class='mcq-title' tabindex='0'><p>color of apple is ?</p></div><div data-choice-interaction='response1' class='mcq-vertical'></div></div>",
      "editorState": {
        "options": [
          {
            "answer": true,
            "value": {
              "body": "<p>red</p>",
              "value": 0
            }
          },
          {
            "answer": false,
            "value": {
              "body": "<p>blue</p>",
              "value": 1
            }
          },
          {
            "answer": false,
            "value": {
              "body": "<p>green</p>",
              "value": 2
            }
          },
          {
            "answer": false,
            "value": {
              "body": "<p>yellow</p>",
              "value": 3
            }
          }
        ],
        "question": "<p>color of apple is ?</p>"
      },
      "templateId": "mcq-vertical",
      "gradeLevel": [
        "Class 2"
      ],
      "primaryCategory": "Multiple Choice Question",
      "identifier": "do_11365083124405043211564",
      "author": "n11@yopmail.com",
      "solutions": [

      ],
      "qType": "MCQ",
      "maxScore": 2,
      "languageCode": [
        "en"
      ],
      "interactionTypes": [
        "choice"
      ],
      "name": "MCQ",
      "topic": [
        "Identify Non Linear Shapes",
        "Counting in Groups",
        "Addition and Subtraction of Two Digit Numbers",
        "Patterns",
        "Concept of Units and Number System",
        "Addition",
        "Weights",
        "Different Lines and their Directions",
        "Counting in Tens",
        "Volumes and Capacity",
        "Days, Weeks, Months",
        "Grouping and Counting",
        "Length",
        "Shapes",
        "Addition through Carry Forward"
      ],
      "medium": [
        "English"
      ],
      "media": [

      ],
      "interactions": {
        "response1": {
          "type": "choice",
          "options": [
            {
              "label": "<p>red</p>",
              "value": 0
            },
            {
              "label": "<p>blue</p>",
              "value": 1
            },
            {
              "label": "<p>green</p>",
              "value": 2
            },
            {
              "label": "<p>yellow</p>",
              "value": 3
            }
          ]
        }
      },
      "bloomsLevel": "knowledge",
      "answer": "0",
      "board": "CBSE"
    }
  }
}
```

{% endcode %}
{% endtab %}

{% tab title="404: Not Found Resource not found" %}

```javascript
{
  "id": "api.question.read",
  "ver": "3.0",
  "ts": "2021-02-02T20:01:13ZZ",
  "params": {
    "resmsgid": "815b341a-7984-45a1-b1f9-4335da18985e",
    "msgid": null,
    "err": "NOT_FOUND",
    "status": "failed",
    "errmsg": "Error! Node(s) doesn't Exists. | [Invalid Node Id.]: do_1132079240377466881101"
  },
  "responseCode": "RESOURCE_NOT_FOUND",
  "result": {
    "messages": null
  }
}
```

{% endtab %}

{% tab title="500: Internal Server Error Looks like something went wrong" %}

```javascript
{
  "result": {},
  "id": "string",
  "ver": "string",
  "ts": "string",
  "params": {
    "resmsgid": "string",
    "msgid": "string",
    "err": "string",
    "status": "string",
    "errmsg": "string"
  },
  "responseCode": "string"
}
```

{% endtab %}
{% endtabs %}

#### Success Result Schema

<table><thead><tr><th width="232">Attribute</th><th width="109.33333333333331">Type</th><th>Description</th></tr></thead><tbody><tr><td>identifier</td><td>string</td><td>Unique Question Identifier</td></tr><tr><td>name</td><td>string</td><td>Question name</td></tr><tr><td>versionKey</td><td>string</td><td>Question versionKey</td></tr><tr><td>code</td><td>string</td><td>Unique Question code</td></tr><tr><td>lastStatusChangedOn</td><td>string</td><td>Last status changed time</td></tr><tr><td>visibility</td><td>string</td><td>Question visibility eg. parent</td></tr><tr><td>mimeType</td><td>string</td><td>Question mimeType eg. application/vnd.sunbird.question</td></tr><tr><td>createdOn</td><td>string</td><td>Question createdOn Time</td></tr><tr><td>objectType</td><td>string</td><td>Question objectType</td></tr><tr><td>primaryCategory</td><td>string</td><td>Type of question (Multiple Choice Question or Subjective Question)</td></tr><tr><td>lastUpdatedOn</td><td>string</td><td>Question lastUpdatedOn</td></tr><tr><td>status</td><td>string</td><td>Question status Draft/Review/Live</td></tr></tbody></table>

#### cURL

**sample curl to read the metadata**

```shell
curl --location -g --request GET '{{host}}/question/v1/read/{{question_id}}' \
--header 'Authorization: Bearer {{api_key}}
```

**Sample curl to read specific metadata**

```
curl --location -g --request GET '{{host}}/question/v1/read/{{question_id}}?fields=name,body,editorState' \
--header 'Authorization: Bearer {{api_key}}
```


# Read Private Question

This API is used to read the private question on the Sunbird-inQuiry Platform.

## This API is used to read the private question on the Sunbird-inQuiry Platform.

<mark style="color:blue;">`GET`</mark> `/question/v1/private/read/{Question_Id}`

*Private Questions* are created within a specific channel. The user can fetch the question by providing that channel id in a request header.\
\
• It points to inquiry-api-service (assessment service)  - <mark style="color:orange;">/question/v4/private/read</mark>\
• You need to provide a valid Question Id value in <mark style="color:orange;">{Question\_Id}</mark> field of the API URL.\
• It is mandatory to provide values for parameters marked with <mark style="color:red;">\*</mark>.\
• Mandatory fields cannot be null or empty.

#### Path Parameters

| Name                                           | Type   | Description                                   |
| ---------------------------------------------- | ------ | --------------------------------------------- |
| Question\_Id<mark style="color:red;">\*</mark> | String | Append a valid Question ID To the Request URL |

#### Headers

| Name                                            | Type   | Description                                                                                                                                                                                                                                                     |
| ----------------------------------------------- | ------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Content-Type                                    | String | The Content-Type entity is the media type of the resource. It should be <mark style="color:green;">Application/json</mark>                                                                                                                                      |
| Authorization<mark style="color:red;">\*</mark> | String | <p>To make use of the API, you require authorization. Raise a request to the administrator, for the use of the API. You will receive the authorization key. Specify the key received, here.</p><p>Set <mark style="color:green;">Bearer {{api\_key}}</mark></p> |
| x-channel-id<mark style="color:red;">\*</mark>  | String | Unique identification number associated with a root organization.                                                                                                                                                                                               |

{% tabs %}
{% tab title="200: OK Successful Operation. The "Read Private Question" operation was successfully executed" %}
{% code overflow="wrap" %}

```json
{
  "id": "api.question.private.read",
  "ver": "3.0",
  "ts": "2021-09-20T21:31:31Z+05:30",
  "params": {
    "resmsgid": "452d3641-49ae-4f2c-b1a5-8fccd81b6550",
    "msgid": null,
    "err": null,
    "status": "successful",
    "errmsg": null
  },
  "responseCode": "OK",
  "result": {
    "question": {
      "code": "name",
      "channel": "abc-123",
      "language": [
        "English"
      ],
      "mimeType": "application/vnd.sunbird.question",
      "createdOn": "2021-09-18T13:12:00.309+0530",
      "objectType": "Question",
      "primaryCategory": "Practice Question Set",
      "contentDisposition": "inline",
      "lastUpdatedOn": "2021-09-18T13:12:00.309+0530",
      "contentEncoding": "gzip",
      "showSolutions": "No",
      "trackable": "{\"enabled\":\"No\",\"autoBatch\":\"No\"}",
      "allowAnonymousAccess": "Yes",
      "identifier": "do_11336894193858150417",
      "lastStatusChangedOn": "2021-09-18T13:12:00.309+0530",
      "visibility": "Private",
      "showTimer": "No",
      "languageCode": [
        "en"
      ],
      "version": 1,
      "versionKey": "1631950920309",
      "showFeedback": "No",
      "license": "CC BY 4.0",
      "compatibilityLevel": 4,
      "name": "question five",
      "status": "Draft"
    }
  }
}
```

{% endcode %}
{% endtab %}

{% tab title="404: Not Found Question Private Read operation failed! The possible reason for failure is that you may have provided the wrong question ID." %}

```json
{
  "id": "api.question.private.read",
  "ver": "3.0",
  "ts": "2021-09-20T21:44:37Z+05:30",
  "params": {
    "resmsgid": "edec7fd2-2ce7-4e99-af58-995c00074b4e",
    "msgid": null,
    "err": "NOT_FOUND",
    "status": "failed",
    "errmsg": "Error! Node(s) doesn't Exists. | [Invalid Node Id.]: do_11336894193858150418"
  },
  "responseCode": "RESOURCE_NOT_FOUND",
  "result": {
    "messages": null
  }
}
```

{% endtab %}

{% tab title="500: Internal Server Error Looks like something went wrong! These errors are tracked automatically." %}

```json
{
  "result": {},
  "id": "string",
  "ver": "string",
  "ts": "string",
  "params": {
    "resmsgid": "string",
    "msgid": "string",
    "err": "string",
    "status": "string",
    "errmsg": "string"
  },
  "responseCode": "string"
}
```

{% endtab %}
{% endtabs %}

#### Sample Response

```json
{
  "id": "api.question.private.read",
  "ver": "3.0",
  "ts": "2021-09-20T21:31:31Z+05:30",
  "params": {
    "resmsgid": "452d3641-49ae-4f2c-b1a5-8fccd81b6550",
    "msgid": null,
    "err": null,
    "status": "successful",
    "errmsg": null
  },
  "responseCode": "OK",
  "result": {
    "question": {
      "code": "name",
      "channel": "abc-123",
      "language": [
        "English"
      ],
      "mimeType": "application/vnd.sunbird.question",
      "createdOn": "2021-09-18T13:12:00.309+0530",
      "objectType": "Question",
      "primaryCategory": "Practice Question Set",
      "contentDisposition": "inline",
      "lastUpdatedOn": "2021-09-18T13:12:00.309+0530",
      "contentEncoding": "gzip",
      "showSolutions": "No",
      "trackable": "{\"enabled\":\"No\",\"autoBatch\":\"No\"}",
      "allowAnonymousAccess": "Yes",
      "identifier": "do_11336894193858150417",
      "lastStatusChangedOn": "2021-09-18T13:12:00.309+0530",
      "visibility": "Private",
      "showTimer": "No",
      "languageCode": [
        "en"
      ],
      "version": 1,
      "versionKey": "1631950920309",
      "showFeedback": "No",
      "license": "CC BY 4.0",
      "compatibilityLevel": 4,
      "name": "question five",
      "status": "Draft"
    }
  }
}
```

#### Success Result Schema

<table><thead><tr><th width="230">Name</th><th width="133.33333333333331">Type</th><th>Description</th></tr></thead><tbody><tr><td>identifier</td><td>String</td><td>Unique Question Identifier</td></tr><tr><td>name</td><td>String</td><td>Name of the Question</td></tr><tr><td>versionKey</td><td>String</td><td>Unique version key of Question</td></tr><tr><td>code</td><td>String</td><td>Unique Code for Question</td></tr><tr><td>lastStatusChangedOn</td><td>String</td><td>Last status changed time</td></tr><tr><td>visibility</td><td>String</td><td>Question Visibility eg. parent</td></tr><tr><td>mimeType</td><td>String</td><td>Question mimeType eg. <code>application/vnd.sunbird.question</code></td></tr><tr><td>createdOn</td><td>String</td><td>Time of question creation</td></tr><tr><td>objectType</td><td>String</td><td>Question objectType</td></tr><tr><td>primaryCategory</td><td>String</td><td>Type of question - <code>Multiple Choice Question</code> or <code>Subjective Question</code></td></tr><tr><td>status</td><td>String</td><td>Question status <code>Draft/Review/Live</code></td></tr><tr><td>lastUpdatedOn</td><td>String</td><td>Last Updated time</td></tr></tbody></table>

#### &#x20;

#### cURL

```shell
curl --location -g --request GET '{{host}}/question/v1/read/{{question_id}}' \
--header 'X-Channel-ID: {{channel_id}}' \
--header 'Authorization: Bearer {{api_key}}'
```


# Update Question

This API is used to update the existing question on the Sunbird-inQuiry Platform.

## This API is used to update the existing question on the Sunbird-inQuiry Platform.

<mark style="color:purple;">`PATCH`</mark> `/question/v1/update/{Question_Id}`

• <mark style="color:orange;">/update</mark> endpoint executes the "Update Question" request based on parameters provided as metadata in the request body. Users can provide updated attributes and their values in a request.\
• It points to inquiry-api-service (assessment service) - <mark style="color:orange;">/question/v4/update</mark>\
• You need to provide a valid Question Id value in <mark style="color:orange;">{Question\_Id}</mark> field of the API URL.\
• It is mandatory to provide values for parameters marked with <mark style="color:red;">\*</mark>.\
• Mandatory fields cannot be null or empty.\
• Question schema check [here](https://github.com/project-sunbird/knowledge-platform/blob/release-4.4.0/schemas/question/1.0/schema.json)

#### Path Parameters

| Name                                           | Type   | Description                                   |
| ---------------------------------------------- | ------ | --------------------------------------------- |
| Question\_Id<mark style="color:red;">\*</mark> | String | Append a valid Question ID To the Request URL |

#### Headers

| Name                                            | Type   | Description                                                                                                                                                                                                                                                     |
| ----------------------------------------------- | ------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Content-Type<mark style="color:red;">\*</mark>  | String | The Content-Type entity is the media type of the resource. It should be <mark style="color:green;">Application/json</mark>                                                                                                                                      |
| Authorization<mark style="color:red;">\*</mark> | String | <p>To make use of the API, you require authorization. Raise a request to the administrator, for the use of the API. You will receive the authorization key. Specify the key received, here.</p><p>Set <mark style="color:green;">Bearer {{api\_key}}</mark></p> |
| x-channel-id                                    | String | Unique identification number associated with a root organization.                                                                                                                                                                                               |

#### Request Body

| Name                                      | Type   | Description                                            |
| ----------------------------------------- | ------ | ------------------------------------------------------ |
| request<mark style="color:red;">\*</mark> | Object | It contains metadata about the question to be updated. |

{% tabs %}
{% tab title="200: OK Successful operation. The 'Update Question' operation was successfuly executed." %}

```javascript
{
  "id": "api.question.update",
  "ver": "3.0",
  "ts": "2021-02-02T19:55:07ZZ",
  "params": {
    "resmsgid": "9d9d4824-cc40-4ac7-a3d6-6da61c0240e9",
    "msgid": null,
    "err": null,
    "status": "successful",
    "errmsg": null
  },
  "responseCode": "OK",
  "result": {
    "identifier": "do_113207924037746688110",
    "versionKey": "1612295707004"
  }
}
```

{% endtab %}

{% tab title="400: Bad Request The 'Update Question' operation failed! The possible reason for failure is that you may have missed providing input for a mandatory parameter." %}

```javascript
{
  "id": "api.question.update",
  "ver": "3.0",
  "ts": "2021-02-02T19:56:20ZZ",
  "params": {
    "resmsgid": "fcfcf6d6-84f1-43f5-b573-c3b6cf69ef53",
    "msgid": null,
    "err": "CLIENT_ERROR",
    "status": "failed",
    "errmsg": "Invalid version Key"
  },
  "responseCode": "CLIENT_ERROR",
  "result": {
    "messages": null
  }
}
```

{% endtab %}

{% tab title="404: Not Found The Update Question operation failed! The possible reason for failure is that you may have provided wrong question ID." %}

```javascript
{
  "id": "api.question.update",
  "ver": "3.0",
  "ts": "2021-02-02T19:57:35ZZ",
  "params": {
    "resmsgid": "2b139ee9-f091-4cca-b466-32af45f49a65",
    "msgid": null,
    "err": "NOT_FOUND",
    "status": "failed",
    "errmsg": "Error! Node(s) doesn't Exists. | [Invalid Node Id.]: do_1132079240377466881101"
  },
  "responseCode": "RESOURCE_NOT_FOUND",
  "result": {
    "messages": null
  }
}
```

{% endtab %}

{% tab title="500: Internal Server Error Looks like something went wrong! These errors are tracked automatically." %}

```javascript
{
  "result": {},
  "id": "string",
  "ver": "string",
  "ts": "string",
  "params": {
    "resmsgid": "string",
    "msgid": "string",
    "err": "string",
    "status": "string",
    "errmsg": "string"
  },
  "responseCode": "string"
}
```

{% endtab %}
{% endtabs %}

#### Sample Request

```json
{
   "request": {
      "question":{
        "name": "Updated value",
        "versionKey": "{{versionKey}}"
      }
    }
}
```

#### Request Schema

<table><thead><tr><th width="146">Attribute</th><th width="92">Type</th><th width="401">Description</th><th>Required</th></tr></thead><tbody><tr><td>versionKey</td><td>string</td><td>Represents the transaction update version key of the Question</td><td>Yes</td></tr></tbody></table>

#### Success Result Schema

<table><thead><tr><th width="154.33333333333331">Attribute</th><th width="104">Type</th><th>Description</th></tr></thead><tbody><tr><td>identidier</td><td>String</td><td>Unique Question identifier</td></tr><tr><td>versionKey</td><td>String</td><td>Unique version key for question</td></tr></tbody></table>

#### cURL

```shell
curl --location -g --request PATCH '{{host}}/question/v1/update/{{question_id}}' \
--header 'Accept: application/json' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer {{api_key}}' \
--data-raw '{
   "request": {
      "question":{
        "name": "Updated value",
        "versionKey": "{{versionKey}}"
      }
    }
}'
```

#### Full Request Example

Following is the complete request example of updating an existing Question. This is a **Multiple Choice Questions (MCQ)** type of question.

<pre class="language-json"><code class="lang-json">{
  "request": {
    "question": {
      "media": [],
<strong>      "editorState": {
</strong>        "options": [
          {
            "answer": true,
            "value": {
              "body": "&#x3C;p>a1&#x3C;/p>",
              "value": 0
            }
          },
          {
            "answer": false,
            "value": {
              "body": "&#x3C;p>a2&#x3C;/p>",
              "value": 1
            }
          },
          {
            "answer": false,
            "value": {
              "body": "&#x3C;p>a3&#x3C;/p>",
              "value": 2
            }
          },
          {
            "answer": false,
            "value": {
              "body": "&#x3C;p>a4&#x3C;/p>",
              "value": 3
            }
          }
        ],
        "question": "&#x3C;p>question&#x3C;/p>"
      },
      "templateId": "mcq-vertical",
      "answer": "0",
      "bloomsLevel": "knowledge",
      "maxScore": 1,
      "name": "a1",
      "responseDeclaration": {
        "response1": {
          "maxScore": 1,
          "cardinality": "single",
          "type": "integer",
          "correctResponse": {
            "value": "0",
            "outcomes": {
              "SCORE": 1
            }
          },
          "mapping": []
        }
      },
      "interactionTypes": [
        "choice"
      ],
      "interactions": {
        "response1": {
          "type": "choice",
          "options": [
            {
              "label": "&#x3C;p>a1&#x3C;/p>",
              "value": 0
            },
            {
              "label": "&#x3C;p>a2&#x3C;/p>",
              "value": 1
            },
            {
              "label": "&#x3C;p>a3&#x3C;/p>",
              "value": 2
            },
            {
              "label": "&#x3C;p>a4&#x3C;/p>",
              "value": 3
            }
          ]
        }
      },
      "qType": "MCQ",
      "primaryCategory": "Multiple Choice Question",
      "body": "&#x3C;div class='question-body' tabindex='-1'>&#x3C;div class='mcq-title' tabindex='0'>&#x3C;p>question&#x3C;/p>&#x3C;/div>&#x3C;div data-choice-interaction='response1' class='mcq-vertical'>&#x3C;/div>&#x3C;/div>",
      "solutions": [

      ],
      "board": "CBSE",
      "medium": [
        "English"
      ],
      "gradeLevel": [
        "Class 2"
      ],
      "subject": [
        "Mathematics"
      ],
      "author": "n11@yopmail.com",
      "channel": "01309282781705830427",
      "framework": "ekstep_ncert_k-12",
      "copyright": "NIT123",
      "audience": [
        "Student"
      ],
      "license": "CC BY 4.0",
      "programId": "18730310-5144-11ed-be8b-9962d8844469",
      "collectionId": "do_11365081180508160011559",
      "topic": [
        "Addition through Carry Forward"
      ],
      "isReviewModificationAllowed": false
    }
  }
}
</code></pre>


# Submit for Review Question

This API is used to submit question for review on the Sunbird-inQuiry Platform.

## This API is used to submit question for review on the Sunbird-inQuiry Platform.

<mark style="color:green;">`POST`</mark> `/question/v1/review/{Question_Id}`

• <mark style="color:orange;">/question/v1/review/{Question\_Id}</mark> endpoint executes the "Submit for Review" request based on parameters provided as metadata in the request body\
• It points to inquiry-api-service (assessment service) - <mark style="color:orange;">/question/v4/review</mark>\
• You need to provide a valid Question Id value in <mark style="color:orange;">{Question\_Id}</mark> field of the API URL.\
• It is mandatory to provide values for parameters marked with <mark style="color:red;">\*</mark>\
• Mandatory fields cannot be null or empty.\
• Question schema check [here](https://github.com/project-sunbird/knowledge-platform/blob/release-4.4.0/schemas/question/1.0/schema.json)

#### Path Parameters

| Name                                           | Type   | Description                                   |
| ---------------------------------------------- | ------ | --------------------------------------------- |
| Question\_Id<mark style="color:red;">\*</mark> | String | Append a valid Question ID To the Request URL |

#### Headers

| Name                                            | Type   | Description                                                                                                                                                                                                                                                     |
| ----------------------------------------------- | ------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Content-Type<mark style="color:red;">\*</mark>  | String | The Content-Type entity is the media type of the resource. It should be <mark style="color:green;">Application/json</mark>                                                                                                                                      |
| Authorization<mark style="color:red;">\*</mark> | String | <p>To make use of the API, you require authorization. Raise a request to the administrator, for the use of the API. You will receive the authorization key. Specify the key received, here.</p><p>Set <mark style="color:green;">Bearer {{api\_key}}</mark></p> |
| x-channel-id                                    | String | Unique identification number associated with a root organization.                                                                                                                                                                                               |

#### Request Body

| Name                                      | Type   | Description                                        |
| ----------------------------------------- | ------ | -------------------------------------------------- |
| request<mark style="color:red;">\*</mark> | Object | metadata about the question to be sent for review. |

{% tabs %}
{% tab title="200: OK Question sent for review operation successful!" %}

```javascript
{
  "id": "api.question.review",
  "ver": "3.0",
  "ts": "2021-02-02T20:06:22ZZ",
  "params": {
    "resmsgid": "6a00ef94-b63d-4fb6-818a-8dfc66680577",
    "msgid": null,
    "err": null,
    "status": "successful",
    "errmsg": null
  },
  "responseCode": "OK",
  "result": {
    "identifier": "do_113207931921555456111",
    "versionKey": "1612296382041"
  }
}
```

{% endtab %}

{% tab title="400: Bad Request The Review Question operation failed. The possible reason for failure is that you may have missed providing input for a mandatory parameter" %}

```javascript
{
  "id": "api.question.review",
  "ver": "3.0",
  "ts": "2021-02-02T20:09:24ZZ",
  "params": {
    "resmsgid": "db7fd0f9-4aa5-4f06-b43b-1b89bec45c50",
    "msgid": null,
    "err": "ERR_QUESTION_REVIEW",
    "status": "failed",
    "errmsg": "Question with status other than Draft can't be sent for review."
  },
  "responseCode": "CLIENT_ERROR",
  "result": {
    "messages": null
  }
}
```

{% endtab %}

{% tab title="404: Not Found The Review Question operation failed. The possible reason for failure is that you may have provided wrong question ID" %}

```javascript
{
  "id": "api.question.review",
  "ver": "3.0",
  "ts": "2021-02-02T20:07:24ZZ",
  "params": {
    "resmsgid": "852b878c-a607-4d72-9458-6239e36adb9e",
    "msgid": null,
    "err": "NOT_FOUND",
    "status": "failed",
    "errmsg": "Error! Node(s) does not Exist. | [Invalid Node Id.]: do_1132079319215554561111"
  },
  "responseCode": "RESOURCE_NOT_FOUND",
  "result": {
    "messages": null
  }
}
```

{% endtab %}

{% tab title="500: Internal Server Error Looks like something went wrong! These errors are tracked automatically." %}

```javascript
{
  "result": {},
  "id": "string",
  "ver": "string",
  "ts": "string",
  "params": {
    "resmsgid": "string",
    "msgid": "string",
    "err": "string",
    "status": "string",
    "errmsg": "string"
  },
  "responseCode": "string"
}
```

{% endtab %}
{% endtabs %}

#### Success result schema

<table><thead><tr><th width="178.33333333333331">Attribute</th><th width="104">Type</th><th>Description</th></tr></thead><tbody><tr><td>identidier</td><td>String</td><td>Unique Question identifier</td></tr><tr><td>versionKey</td><td>String</td><td>Unique version key for question</td></tr></tbody></table>

#### cURL

```shell
curl --location -g --request POST '{{host}}/question/v1/review/{{question_id}}' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer {{api_key}}' \
--header 'X-Channel-Id: {{channel_id}}' \
--data-raw '{
  "request": {
    "question": {}
  }
}'
```


# Publish Question

This API is used to publish the question on Sunbird platform.

## This API is used to publish the question on Sunbird-inQuiry platform.

<mark style="color:green;">`POST`</mark> `/question/v1/publish/{Question_Id}`

• <mark style="color:orange;">/publish</mark> endpoint executes the "Publish Question" request based on parameters provided       as metadata in the request body\
• It points to inquiry-api-service (assessment service)- <mark style="color:orange;">/question/v4/publish</mark>\
• You need to provide a valid Question Id value in <mark style="color:orange;">{Question\_Id}</mark> field of the API URL.\
• It is mandatory to provide values for parameters marked with <mark style="color:red;">\*</mark>.\
• Mandatory fields cannot be null or empty.\
• Question schema check [here](https://github.com/project-sunbird/knowledge-platform/blob/release-4.4.0/schemas/question/1.0/schema.json)\ <mark style="color:green;">•</mark> <mark style="color:orange;">Asynchronous flink job : async-questionset-publish will takes care of the publishing activity.</mark>

#### Path Parameters

| Name                                           | Type   | Description                                   |
| ---------------------------------------------- | ------ | --------------------------------------------- |
| Question\_Id<mark style="color:red;">\*</mark> | String | Append a valid Question ID To the Request URL |

#### Headers

| Name                                            | Type   | Description                                                                                                                                                                                                                                                     |
| ----------------------------------------------- | ------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Content-Type<mark style="color:red;">\*</mark>  | String | The Content-Type entity is the media type of the resource. It should be <mark style="color:green;">Application/json</mark>                                                                                                                                      |
| Authorization<mark style="color:red;">\*</mark> | String | <p>To make use of the API, you require authorization. Raise a request to the administrator, for the use of the API. You will receive the authorization key. Specify the key received, here.</p><p>Set <mark style="color:green;">Bearer {{api\_key}}</mark></p> |
| x-channel-id                                    | String | Unique identification number associated with a root organization.                                                                                                                                                                                               |

#### Request Body

| Name    | Type   | Description                                 |
| ------- | ------ | ------------------------------------------- |
| request | Object | metadata about the question to be published |

{% tabs %}
{% tab title="200: OK The Publish Question operation was successful!" %}

```javascript
{
  "id": "api.question.publish",
  "ver": "3.0",
  "ts": "2021-02-02T20:15:02ZZ",
  "params": {
    "resmsgid": "9c64cc9c-bed5-44c7-85bf-4918c3a42f58",
    "msgid": null,
    "err": null,
    "status": "successful",
    "errmsg": null
  },
  "responseCode": "OK",
  "result": {
    "message": "Question is successfully sent for Publish",
    "identifier": "do_113207931921555456111"
  }
}
```

{% endtab %}

{% tab title="404: Not Found The Publish Question operation failed. The possible reason for failure is that you may have provided wrong question ID" %}

```javascript
{
  "id": "api.question.publish",
  "ver": "3.0",
  "ts": "2021-02-02T20:15:32ZZ",
  "params": {
    "resmsgid": "b084af8b-706b-4079-8ec2-0beb0753931c",
    "msgid": null,
    "err": "NOT_FOUND",
    "status": "failed",
    "errmsg": "Error! Node(s) doesn't Exists. | [Invalid Node Id.]: do_1132079319215554561111"
  },
  "responseCode": "RESOURCE_NOT_FOUND",
  "result": {
    "messages": null
  }
}
```

{% endtab %}

{% tab title="500: Internal Server Error Looks like something went wrong! These errors are tracked automatically." %}

```javascript
{
  "result": {},
  "id": "string",
  "ver": "string",
  "ts": "string",
  "params": {
    "resmsgid": "string",
    "msgid": "string",
    "err": "string",
    "status": "string",
    "errmsg": "string"
  },
  "responseCode": "string"
}
```

{% endtab %}
{% endtabs %}

#### Success result schema

| Attribute  | Type   | Description                |
| ---------- | ------ | -------------------------- |
| identidier | String | Unique Question identifier |
| message    | String | Publish success message    |

#### cURL

```shell
curl --location -g --request POST '{{host}}/question/v1/publish/{{question_id}}' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer {{api_key}}' \
--header 'X-Channel-Id: {{channel_id}}' \
--data-raw '{
    "request": {}
}'
```


# Retire Question

This API is used to retiring a questions on the Sunbird-inQuiry Platform.

## This API is used to retiring a questions on the Sunbird-inQuiry Platform.

<mark style="color:red;">`DELETE`</mark> `/question/v1/retire/{Question_Id}`

• It points to inquiry-api-service (assessment service)- <mark style="color:orange;">/question/v4/retire</mark>\
• You need to provide a valid Question Id value in <mark style="color:orange;">{Question\_Id}</mark> field of the API URL.\
• It is mandatory to provide values for parameters marked with <mark style="color:red;">\*</mark>\
• Mandatory fields cannot be null or empty.\
• Question schema check [here](https://github.com/project-sunbird/knowledge-platform/blob/release-4.4.0/schemas/question/1.0/schema.json)

#### Path Parameters

| Name                                           | Type   | Description                                   |
| ---------------------------------------------- | ------ | --------------------------------------------- |
| Question\_Id<mark style="color:red;">\*</mark> | String | Append a valid Question ID To the Request URL |

#### Headers

| Name                                            | Type   | Description                                                                                                                                                                                                                                                     |
| ----------------------------------------------- | ------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Authorization<mark style="color:red;">\*</mark> | String | <p>To make use of the API, you require authorization. Raise a request to the administrator, for the use of the API. You will receive the authorization key. Specify the key received, here.</p><p>Set <mark style="color:green;">Bearer {{api\_key}}</mark></p> |
| x-channel-id                                    | String | Unique identification number associated with a root organization.                                                                                                                                                                                               |

{% tabs %}
{% tab title="200: OK The Retire Question operation was successful!" %}

```javascript
{
  "id": "api.question.retire",
  "ver": "3.0",
  "ts": "2021-02-02T20:20:56ZZ",
  "params": {
    "resmsgid": "98c9f97d-f9d6-4da9-be88-2852294c2aaa",
    "msgid": null,
    "err": null,
    "status": "successful",
    "errmsg": null
  },
  "responseCode": "OK",
  "result": {
    "identifier": "do_113207939069968384112",
    "versionKey": "1612297249754"
  }
}
```

{% endtab %}

{% tab title="400: Bad Request Question is already retired" %}

```javascript
{
  "id": "api.question.retire",
  "ver": "3.0",
  "ts": "2021-02-02T20:21:26ZZ",
  "params": {
    "resmsgid": "0608b59d-dfb9-4c0e-807f-1a19c9a163fe",
    "msgid": null,
    "err": "ERR_QUESTION_RETIRE",
    "status": "failed",
    "errmsg": "Question with identifier : do_113207939069968384112 is already Retired."
  },
  "responseCode": "CLIENT_ERROR",
  "result": {
    "messages": null
  }
}
```

{% endtab %}

{% tab title="404: Not Found The Retire Question operation failed. The possible reason for failure is that you may have provided wrong question ID" %}

```javascript
{
  "id": "api.question.retire",
  "ver": "3.0",
  "ts": "2021-02-02T20:22:03ZZ",
  "params": {
    "resmsgid": "da7af22e-bdce-48f0-8743-f50fa6c2cd21",
    "msgid": null,
    "err": "NOT_FOUND",
    "status": "failed",
    "errmsg": "Error! Node(s) does not Exist. | [Invalid Node Id.]: do_1132079390699683841121"
  },
  "responseCode": "RESOURCE_NOT_FOUND",
  "result": {
    "messages": null
  }
}
```

{% endtab %}

{% tab title="500: Internal Server Error Looks like something went wrong! These errors are tracked automatically." %}

```javascript
{
  "result": {},
  "id": "string",
  "ver": "string",
  "ts": "string",
  "params": {
    "resmsgid": "string",
    "msgid": "string",
    "err": "string",
    "status": "string",
    "errmsg": "string"
  },
  "responseCode": "string"
}
```

{% endtab %}
{% endtabs %}

#### Success result Schema

<table><thead><tr><th width="172.33333333333331">Attribute</th><th width="152">Type</th><th>Description</th></tr></thead><tbody><tr><td>identidier</td><td>String</td><td>Unique Question identifier</td></tr><tr><td>versionKey</td><td>String</td><td>Unique version key for question</td></tr></tbody></table>

#### cURL

```
curl --location -g --request DELETE '{{host}}/question/v1/retire/{Question_Id}' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer {{api_key}}' \
--header 'X-Channel-Id: {{channel_id}}' \
```


# Question List

This API is used to get the list of Questions on the Sunbird-inQuiry Platform.

## This API is used to get the list of Questions on the Sunbird-inQuiry Platform.

<mark style="color:green;">`POST`</mark> `/question/v1/list`

• It gives all metadata of requested question identifiers\
• It points to inquiry-api-service (assessment service)- <mark style="color:orange;">/question/v4/list</mark>\
• You need to provide list of valid question identifiers in the request body\
• It is mandatory to provide values for parameters marked with <mark style="color:red;">\*</mark>\
• Mandatory fields cannot be null or empty.

#### Headers

| Name                                           | Type   | Description                                                                                                                |
| ---------------------------------------------- | ------ | -------------------------------------------------------------------------------------------------------------------------- |
| Content-Type<mark style="color:red;">\*</mark> | String | The Content-Type entity is the media type of the resource. It should be <mark style="color:green;">Application/json</mark> |
| x-channel-id                                   | String | Unique identification number associated with a root organization.                                                          |

#### Request Body

| Name                                      | Type   | Description                  |
| ----------------------------------------- | ------ | ---------------------------- |
| request<mark style="color:red;">\*</mark> | Object | List of question identifiers |

{% tabs %}
{% tab title="200: OK The Question List operation was successful" %}

```javascript
{
  "id": "api.questions.list",
  "ver": "3.0",
  "ts": "2023-01-04T05:04:45ZZ",
  "params": {
    "resmsgid": "73af0b89-94a6-430a-91dd-ee73146934e6",
    "msgid": null,
    "err": null,
    "status": "successful",
    "errmsg": null
  },
  "responseCode": "OK",
  "result": {
    "questions": [
      {
        "instructions": null,
        "copyright": "G123",
        "subject": [
          "Hindi"
        ],
        "downloadUrl": "https://sunbirddevbbpublic.blob.core.windows.net/sunbird-content-staging/question/do_2136939243599380481334/q3_1671700086471_do_2136939243599380481334_2.ecar",
        "responseDeclaration": {
          "response1": {
            "maxScore": 2,
            "cardinality": "single",
            "type": "integer",
            "correctResponse": {
              "value": "2",
              "outcomes": {
                "SCORE": 2
              }
            },
            "mapping": [

            ]
          }
        },
        "language": [
          "English"
        ],
        "mimeType": "application/vnd.sunbird.question",
        "variants": {
          "full": {
            "ecarUrl": "https://sunbirddevbbpublic.blob.core.windows.net/sunbird-content-staging/question/do_2136939243599380481334/q3_1671700086471_do_2136939243599380481334_2.ecar",
            "size": "1546"
          },
          "online": {
            "ecarUrl": "https://sunbirddevbbpublic.blob.core.windows.net/sunbird-content-staging/question/do_2136939243599380481334/q3_1671700087966_do_2136939243599380481334_2_ONLINE.ecar",
            "size": "1546"
          }
        },
        "body": "<div class='question-body' tabindex='-1'><div class='mcq-title' tabindex='0'><p>Venation is a term used to describe the pattern of arrangment of:&nbsp;</p></div><div data-choice-interaction='response1' class='mcq-vertical'></div></div>",
        "editorState": {
          "options": [
            {
              "answer": false,
              "value": {
                "body": "<p>Floral organs</p>",
                "value": 0
              }
            },
            {
              "answer": false,
              "value": {
                "body": "<p>Flower in infloresence</p>",
                "value": 1
              }
            },
            {
              "answer": true,
              "value": {
                "body": "<p>Veins and veinlets in a lamina</p>",
                "value": 2
              }
            },
            {
              "answer": false,
              "value": {
                "body": "<p>All of them</p>",
                "value": 3
              }
            }
          ],
          "question": "<p>Venation is a term used to describe the pattern of arrangment of:&nbsp;</p>"
        },
        "templateId": "mcq-vertical",
        "objectType": "Question",
        "se_mediums": [
          "English"
        ],
        "gradeLevel": [
          "Class 4"
        ],
        "primaryCategory": "Multiple Choice Question",
        "contentEncoding": "gzip",
        "se_gradeLevels": [
          "Class 4"
        ],
        "showSolutions": "No",
        "identifier": "do_2136939243599380481334",
        "audience": [
          "Student"
        ],
        "visibility": "Default",
        "showTimer": "No",
        "author": "n131",
        "solutions": [

        ],
        "hints": null,
        "consumerId": "6968004d-c67e-434a-a350-773aa1e068a3",
        "qType": "MCQ",
        "maxScore": 2,
        "languageCode": [
          "en"
        ],
        "version": 1,
        "se_subjects": [
          "Hindi"
        ],
        "license": "CC BY 4.0",
        "interactionTypes": [
          "choice"
        ],
        "name": "Q3",
        "topic": [
          "कर चले हम फ़िदा"
        ],
        "status": "Live",
        "code": "ec875076-c74c-ec36-eb6c-9b6c0a0a196b",
        "prevStatus": "Live",
        "medium": [
          "English"
        ],
        "media": [

        ],
        "createdOn": "2022-12-21T11:20:26.001+0000",
        "interactions": {
          "response1": {
            "type": "choice",
            "options": [
              {
                "label": "<p>Floral organs</p>",
                "value": 0
              },
              {
                "label": "<p>Flower in infloresence</p>",
                "value": 1
              },
              {
                "label": "<p>Veins and veinlets in a lamina</p>",
                "value": 2
              },
              {
                "label": "<p>lets in a lamina</p>",
                "value": 3
              }
            ]
          }
        },
        "se_boards": [
          "CBSE"
        ],
        "contentDisposition": "inline",
        "lastUpdatedOn": "2022-12-22T09:08:08.295+0000",
        "allowAnonymousAccess": "Yes",
        "lastStatusChangedOn": "2022-12-22T09:08:08.295+0000",
        "se_FWIds": [
          "ekstep_ncert_k-12"
        ],
        "pkgVersion": 2,
        "versionKey": "1671700063322",
        "showFeedback": "No",
        "framework": "ekstep_ncert_k-12",
        "answer": "2",
        "createdBy": "de89c5d8-3df6-432b-ac13-3a2e7a510979",
        "se_topics": [
          "कर चले हम फ़िदा"
        ],
        "compatibilityLevel": 4,
        "board": "CBSE"
      },
      {
        "copyright": "NIT123",
        "subject": [
          "Hindi"
        ],
        "channel": "01309282781705830427",
        "downloadUrl": "https://sunbirddevbbpublic.blob.core.windows.net/sunbird-content-staging/question/do_2137002417093918721507/1_1672392935109_do_2137002417093918721507_1.ecar",
        "responseDeclaration": {
          "response1": {
            "maxScore": 1,
            "cardinality": "single",
            "type": "integer",
            "correctResponse": {
              "value": "0",
              "outcomes": {
                "SCORE": 1
              }
            },
            "mapping": [

            ]
          }
        },
        "language": [
          "English"
        ],
        "mimeType": "application/vnd.sunbird.question",
        "variants": {
          "full": {
            "ecarUrl": "https://sunbirddevbbpublic.blob.core.windows.net/sunbird-content-staging/question/do_2137002417093918721507/1_1672392935109_do_2137002417093918721507_1.ecar",
            "size": "2704"
          },
          "online": {
            "ecarUrl": "https://sunbirddevbbpublic.blob.core.windows.net/sunbird-content-staging/question/do_2137002417093918721507/1_1672392935163_do_2137002417093918721507_1_ONLINE.ecar",
            "size": "1306"
          }
        },
        "body": "<div class='question-body' tabindex='-1'><div class='mcq-title' tabindex='0'><p>mcq1</p></div><div data-choice-interaction='response1' class='mcq-vertical'></div></div>",
        "editorState": {
          "options": [
            {
              "answer": true,
              "value": {
                "body": "<p>1</p>",
                "value": 0
              }
            },
            {
              "answer": false,
              "value": {
                "body": "<p>2</p>",
                "value": 1
              }
            }
          ],
          "question": "<p>mcq1</p>"
        },
        "templateId": "mcq-vertical",
        "objectType": "Question",
        "se_mediums": [
          "English"
        ],
        "gradeLevel": [
          "Class 3"
        ],
        "primaryCategory": "Multiple Choice Question",
        "contentEncoding": "gzip",
        "artifactUrl": "https://sunbirddevbbpublic.blob.core.windows.net/sunbird-content-staging/question/do_2137002417093918721507/do_2137002417093918721507_1672392934125.zip",
        "se_gradeLevels": [
          "Class 3"
        ],
        "showSolutions": "No",
        "identifier": "do_2137002417093918721507",
        "audience": [
          "Student"
        ],
        "visibility": "Parent",
        "showTimer": "No",
        "author": "N11",
        "solutions": [

        ],
        "qType": "MCQ",
        "maxScore": 1,
        "lastPublishedBy": "ae94b68c-a535-4dce-8e7a-fb9662b0ad68",
        "languageCode": [
          "en"
        ],
        "version": 1,
        "se_subjects": [
          "Hindi"
        ],
        "license": "CC BY 4.0",
        "interactionTypes": [
          "choice"
        ],
        "name": "1",
        "status": "Live",
        "code": "c15abfde-b87f-d55f-5a03-4ef46781362b",
        "prevStatus": "Draft",
        "medium": [
          "English"
        ],
        "media": [

        ],
        "createdOn": "2022-12-30T09:33:06.791+0000",
        "interactions": {
          "response1": {
            "type": "choice",
            "options": [
              {
                "label": "<p>1</p>",
                "value": 0
              },
              {
                "label": "<p>2</p>",
                "value": 1
              }
            ]
          },
          "validation": {
            "required": "Yes"
          }
        },
        "se_boards": [
          "CBSE"
        ],
        "contentDisposition": "inline",
        "lastUpdatedOn": "2022-12-30T09:35:35.382+0000",
        "allowAnonymousAccess": "Yes",
        "lastStatusChangedOn": "2022-12-30T09:35:35.382+0000",
        "se_FWIds": [
          "inquiry_k-12"
        ],
        "pkgVersion": 1,
        "versionKey": "1672392786812",
        "showFeedback": "No",
        "framework": "inquiry_k-12",
        "answer": "0",
        "createdBy": "5a587cc1-e018-4859-a0a8-e842650b9d64",
        "compatibilityLevel": 4,
        "board": "CBSE"
      }
    ],
    "count": 2
  }
}
```

{% endtab %}

{% tab title="400: Bad Request The Question List  operation failed. You may have missed providing input for a mandatory parameter.'" %}

```javascript
{
  "id": "api.question.list",
  "ver": "1.0",
  "ts": "2021-02-02T19:41:56ZZ",
  "params": {
    "resmsgid": "86481a2f-513e-4fd4-a1dd-46a7ebcb1e65",
    "msgid": null,
    "err": "CLIENT_ERROR",
    "status": "failed",
    "errmsg": "Either identifier is missing or it is not list type"
  },
  "responseCode": "CLIENT_ERROR",
  "result": {}
}
```

{% endtab %}

{% tab title="500: Internal Server Error Looks like something went wrong! These errors are tracked automatically." %}

```javascript
{
  "id": "api.question.list",
  "ver": "1.0",
  "ts": "2020-12-10T08:51:51.647Z",
  "params": {
    "resmsgid": "f234a6f0-3ac4-11eb-b0a2-8d5c9f561887",
    "msgid": null,
    "status": "failed",
    "err": null,
    "errmsg": null
  },
  "responseCode": "SERVER_ERROR",
  "result": {}
}
```

{% endtab %}
{% endtabs %}

#### Sample Request&#x20;

```json
{
  "request": {
    "search": {
      "identifier": [
        "do_1131687689003827201864",
        "do_0987632323234356522345"
      ]
    }
  }
}
```

#### Success result schema

Below is the list of possible fields which will occur in the question list API

<table><thead><tr><th width="219">Attribute</th><th width="149.33333333333331">Type</th><th>Description</th></tr></thead><tbody><tr><td>mimeType</td><td>string</td><td>MimeType of Question eg. application/vnd.sunbird.question</td></tr><tr><td>audience</td><td>Array of strings</td><td>List of Audience eg. Student/Teacher/Administrator</td></tr><tr><td>lastStatusChangedOn</td><td>string</td><td>Timestamp of last status change</td></tr><tr><td>createdBy</td><td>string</td><td>UserId of creator</td></tr><tr><td>compatibilityLevel</td><td>integer</td><td>compatibility Level</td></tr><tr><td>language</td><td>Array of string</td><td>Language of Question</td></tr><tr><td>lastUpdatedOn</td><td>string</td><td>Timestamp of last question update</td></tr><tr><td>name</td><td>string</td><td>Name of question</td></tr><tr><td>version</td><td>integer</td><td>Version number</td></tr><tr><td>license</td><td>string</td><td>License under it is created</td></tr><tr><td>framework</td><td>string</td><td>Framework in which questiton created</td></tr><tr><td>code</td><td>string</td><td>Unique code for question</td></tr><tr><td>objectType</td><td>string</td><td>Typeof object eg. Question</td></tr><tr><td>identifier</td><td>string</td><td>Unique identifier of Question</td></tr><tr><td>languageCode</td><td>Array of strings</td><td>List of language codes</td></tr><tr><td>channel</td><td>string</td><td>Channel ID from which question is belongs to</td></tr><tr><td>visibility</td><td>string</td><td>visibility of question eg. Parent/Default</td></tr><tr><td>versionKey</td><td>string</td><td>Uniuque version key of  question for specific version</td></tr><tr><td>status</td><td>string</td><td>Staus or state of the question eg. Draft/Review/Live</td></tr><tr><td>createdOn</td><td>string</td><td>Timestamp of creation of question</td></tr><tr><td>primaryCategory</td><td>string</td><td>Main category of question eg. Multiple Choice Question/ Subjective Questions</td></tr></tbody></table>

#### cURL

```shell
curl --location -g --request POST '{{host}}/question/v1/list' \
  -H 'Content-Type: application/json' \
  --data-raw '{"request":{"search":{"identifier":["question_id_1","question_id_2"]}}}' \
  --compressed
```


# Import Question

This API is used to import Question from one instance to another instance of sunbird

## This API is used to import Question from one instance to another instance of sunbird

<mark style="color:green;">`POST`</mark> `/question/v1/import`

• <mark style="color:orange;">/question/v1/import</mark> endpoint executes the "Import Question" request based on parameters provided as metadata in the request body\
• It points to inquiry-api-service (assessment service) - <mark style="color:orange;">/question/v4/import</mark>\
• It is mandatory to provide values for parameters marked with <mark style="color:red;">\*</mark>\
• Mandatory fields cannot be null or empty.

#### Headers

| Name                                            | Type   | Description                                                                                                                                                                                                                                                     |
| ----------------------------------------------- | ------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Content-Type<mark style="color:red;">\*</mark>  | String | The Content-Type entity is the media type of the resource. It should be <mark style="color:green;">Application/json</mark>                                                                                                                                      |
| Authorization<mark style="color:red;">\*</mark> | String | <p>To make use of the API, you require authorization. Raise a request to the administrator, for the use of the API. You will receive the authorization key. Specify the key received, here.</p><p>Set <mark style="color:green;">Bearer {{api\_key}}</mark></p> |
| x-channel-id                                    | String | Unique identification number associated with a root organization.                                                                                                                                                                                               |

#### Request Body

| Name                                      | Type   | Description                                 |
| ----------------------------------------- | ------ | ------------------------------------------- |
| request<mark style="color:red;">\*</mark> | Object | Metadata about the questions to be imported |

{% tabs %}
{% tab title="200: OK The Import Question operation was successful" %}

```javascript
{
  "id": "api.question.import",
  "ver": "3.0",
  "ts": "2020-12-17T16:29:11ZZ",
  "params": {
    "resmsgid": "7cce8934-0a2f-46bf-a0ee-be5f49874cae",
    "msgid": null,
    "err": null,
    "status": "successful",
    "errmsg": null
  },
  "responseCode": "OK",
  "result": {
    "processId": "80a765c7-2202-4b3f-b473-448b5c2cd20e"
  }
}
```

{% endtab %}

{% tab title="400: Bad Request The Import Question operation failed. You may have missed providing input for a mandatory parameter.'" %}

```javascript
{
  "id": "api.question.import",
  "ver": "3.0",
  "ts": "2020-12-17T16:30:16ZZ",
  "params": {
    "resmsgid": "31f88a39-2514-4d86-b424-240166e315be"
  },
  "msgid": null,
  "err": "ERR_REQUIRED_PROPS_VALIDATION",
  "status": "failed",
  "errmsg": "Validation Failed! Mandatory Properties Are [name, code, mimeType, primaryCategory, framework]",
  "responseCode": "CLIENT_ERROR",
  "result": {
    "messages": null
  }
}
```

{% endtab %}

{% tab title="500: Internal Server Error Looks like something went wrong! These errors are tracked automatically." %}

```javascript
{
  "id": "api.question.import",
  "ver": "1.0",
  "ts": "2020-12-10T08:51:51.647Z",
  "params": {
    "resmsgid": "f234a6f0-3ac4-11eb-b0a2-8d5c9f561887",
    "msgid": null,
    "status": "failed",
    "err": null,
    "errmsg": null
  },
  "responseCode": "SERVER_ERROR",
  "result": {}
}
```

{% endtab %}
{% endtabs %}

#### Sample Request

```javascript
{
  "request": {
    "question": [
      {
        "source": "https://dock.sunbirded.org/api/question/v1/read/do_1132390225275781121622",
        "metadata": {
          "framework": "ekstep_ncert_k-12",
          "channel": "01309282781705830427",
          "name": "Question 1",
          "code": "9ae33d1e-a682-f30c-04b5-9bda236650ac",
          "lastPublishedBy": "5a587cc1-e018-4859-a0a8-e842650b9d64"
        },
        "collection": [
          {
            "identifier": "do_11324642736155033614",
            "unitId": "do_11324642761348710417"
          }
        ],
        "stage": "Review"
      }
    ]
  }
}
```

#### Success result schema

| Attribute | Type   | Description                            |
| --------- | ------ | -------------------------------------- |
| processId | String | Unique ID assigned to import operation |

#### cURL

```shell
curl --location -g --request POST '{{host}}/question/v1/import' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer {{api_key}}' \
--header 'X-Channel-Id: {{channel_id}}' \
--data-raw '{
  "request": {
    "question": [
      {
        "source": "https://dock.sunbirded.org/api/question/v1/read/do_1132390225275781121622",
        "metadata": {
          "framework": "ekstep_ncert_k-12",
          "channel": "01309282781705830427",
          "name": "Question 1",
          "code": "9ae33d1e-a682-f30c-04b5-9bda236650ac",
          "lastPublishedBy": "5a587cc1-e018-4859-a0a8-e842650b9d64"
        },
        "collection": [
          {
            "identifier": "do_11324642736155033614",
            "unitId": "do_11324642761348710417"
          }
        ]
      }
    ]
  }
}'
```


# Copy Question

This API is associated with copying question on the Sunbird Platform.

## This API is associated with copying question on the Sunbird Platform.

<mark style="color:green;">`POST`</mark> `/question/v1/copy/{Question_Id}`

• The endpoint for **Copy Question** is <mark style="color:orange;">/question/v1/copy</mark>\
• It points to inquiry-api-service (assessment service) - <mark style="color:orange;">/question/v4/copy</mark> \
• You need to provide a valid Question Id value in <mark style="color:orange;">{Question\_Id}</mark> field of the API URL.\
• All parameters marked with <mark style="color:red;">\*</mark> are mandatory. You must provide values for these parameters. \
• Mandatory fields cannot be null or empty.

#### Path Parameters

| Name                                           | Type   | Description                                   |
| ---------------------------------------------- | ------ | --------------------------------------------- |
| Question\_Id<mark style="color:red;">\*</mark> | String | Append a valid Question ID to the Request URL |

#### Headers

| Name                                            | Type   | Description                                                                                                                                                                                                                                                |
| ----------------------------------------------- | ------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Content-Type<mark style="color:red;">\*</mark>  | String | The Content-Type entity is the media type of the resource. The possible media types can be: <mark style="color:green;">Application/json</mark>                                                                                                             |
| Authorization<mark style="color:red;">\*</mark> | String | <p>You require authorization to make use of the API. Raise a request to the administrator for the use of the API. You will receive the authorization key. Specify the key received, here.<br>Set <mark style="color:green;">Bearer {{api\_key}}</mark></p> |
| x-channel-id                                    | String | Unique identification number associated with a root organisation.                                                                                                                                                                                          |

#### Request Body

| Name                                      | Type   | Description                                                                        |
| ----------------------------------------- | ------ | ---------------------------------------------------------------------------------- |
| request<mark style="color:red;">\*</mark> | Object | The body is the representation of the resource object for importing a question set |

{% tabs %}
{% tab title="200: OK The Copy Question operation was successful!" %}

```javascript
{
    "id": "api.question.copy",
    "ver": "3.0",
    "ts": "2023-06-23T06:41:31ZZ",
    "params": {
        "resmsgid": "8bba3dda-f81e-4659-8c05-55caed20d174",
        "msgid": null,
        "err": null,
        "status": "successful",
        "errmsg": null
    },
    "responseCode": "OK",
    "result": {
        "node_id": {
            "do_2138240203066900481600": "do_2138240204082216961601"
        },
        "versionKey": "1687502491400"
    }
}
```

{% endtab %}

{% tab title="400: Bad Request The Copy Question operation failed. You may have missed providing input for a mandatory parameter.'" %}

```javascript
{
    "id": "api.question.copy",
    "ver": "3.0",
    "ts": "2023-06-23T06:40:01ZZ",
    "params": {
        "resmsgid": "d078ab42-7650-4e5f-8c30-43f37d3ac244",
        "msgid": null,
        "err": "ERR_INVALID_REQUEST",
        "status": "failed",
        "errmsg": "Please provide valid value for [createdFor]"
    },
    "responseCode": "CLIENT_ERROR",
    "result": {
        "messages": null
    }
}
```

{% endtab %}

{% tab title="500: Internal Server Error We track these errors automatically and try to set it right at the earliest." %}

```javascript
{
  "id": "api.question.copy",
  "ver": "3.0",
  "ts": "2020-12-10T08:51:51.647Z",
  "params": {
    "resmsgid": "f234a6f0-3ac4-11eb-b0a2-8d5c9f561887",
    "msgid": null,
    "status": "failed",
    "err": null,
    "errmsg": null
  },
  "responseCode": "SERVER_ERROR",
  "result": {}
}
```

{% endtab %}

{% tab title="404: Not Found The Copy Question operation failed. You may have requested a resource that is not existing in the server.'" %}

{% endtab %}
{% endtabs %}

#### Sample Request

```json
{
  "request": {
    "question": {
      "createdBy": "User001",
      "createdFor": [
        "Sunbird"
      ],
      "name": "Sunbird-Question"
    }
  }
}
```

#### Request schema

<table><thead><tr><th width="139.33333333333331">Attribute</th><th width="486">Description</th><th>Type</th></tr></thead><tbody><tr><td>createdBy</td><td>Represents the the user who triggered the copy operation</td><td>string</td></tr><tr><td>createdFor</td><td>Represents the organization on behalf the request was triggered</td><td>Object</td></tr><tr><td>name</td><td>Represents the name of the Question to be copied.</td><td>string</td></tr></tbody></table>

#### Success result schema

| Attribute | Type            | Description               |
| --------- | --------------- | ------------------------- |
| node\_id  | Array of Object | Node Ids that were copied |

**cURL**

```
curl --location -g --request POST '{{host}}/question/v1/copy/{Question_Id}' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer {{api_key}}' \
--header 'X-Channel-Id: {{channel_id}}' \
--data-raw '{
  "request": {
    "question": {
      "createdBy": "User001",
      "createdFor": [
        "Sunbird"
      ],
      "name": "Sunbird-Question"
    }
  }
}'
```


# Reject Question

This API is used to reject the questions on the Sunbird-inQuiry Platform.

## This API is used to reject the questions on the Sunbird-inQuiry Platform.

<mark style="color:red;">`DELETE`</mark> `/question/reject/{Question_Id}`

• *<mark style="color:orange;">/question/reject/{Question\_Id}</mark>* endpoint executes the "Reject Question" request based on parameters provided as metadata in the request body\
• This API is used to send back the question to the creator by the reviewer. The API changes the question object status from review to draft.\
• It points to inquiry-api-service (assessment service) - <mark style="color:orange;">/question/v4/reject</mark>\
• It is mandatory to provide values for parameters marked with <mark style="color:red;">\*</mark>.\
• Mandatory fields cannot be null or empty.

#### Path Parameters

| Name                                           | Type   | Description                                   |
| ---------------------------------------------- | ------ | --------------------------------------------- |
| Question\_Id<mark style="color:red;">\*</mark> | String | Append a valid Question ID To the Request URL |

#### Headers

| Name                                            | Type   | Description                                                                                                                                                                                                                                                     |
| ----------------------------------------------- | ------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Authorization<mark style="color:red;">\*</mark> | String | <p>To make use of the API, you require authorization. Raise a request to the administrator, for the use of the API. You will receive the authorization key. Specify the key received, here.</p><p>Set <mark style="color:green;">Bearer {{api\_key}}</mark></p> |
| x-channel-id                                    | String | Unique identification number associated with a root organization.                                                                                                                                                                                               |

#### Request Body

| Name                                      | Type   | Description                                 |
| ----------------------------------------- | ------ | ------------------------------------------- |
| request<mark style="color:red;">\*</mark> | Object | Metadata about the question to be rejected. |

{% tabs %}
{% tab title="200: OK The Reject Question operation was successfully executed" %}

```javascript
{
  "id": "api.question.reject",
  "ver": "3.0",
  "ts": "2021-10-19T12:49:25Z+05:30",
  "params": {
    "resmsgid": "70dc4cef-b7d0-4794-ae78-e80cc85b4770",
    "msgid": null,
    "err": null,
    "status": "successful",
    "errmsg": null
  },
  "responseCode": "OK",
  "result": {
    "identifier": "do_11336893480941158415",
    "versionKey": "1634627965206"
  }
}
```

{% endtab %}

{% tab title="400: Bad Request The Reject Question operation was unsuccessful. You may have missed providing input for a mandatory parameter.'" %}

```javascript
{
  "id": "api.question.reject",
  "ver": "3.0",
  "ts": "2021-10-20T12:33:25Z+05:30",
  "params": {
    "resmsgid": "415e19d2-01e3-4690-b5c7-040316c56f5b",
    "msgid": null,
    "err": "ERR_QUESTION_REJECT",
    "status": "failed",
    "errmsg": "Question is not in Review state for identifier: do_11336893480941158415"
  },
  "responseCode": "CLIENT_ERROR",
  "result": {
    "messages": null
  }
}
```

{% endtab %}

{% tab title="404: Not Found The Reject Question operation failed. The possible reason for failure is that you may have provided wrong question ID" %}

```javascript
{
  "id": "api.question.reject",
  "ver": "3.0",
  "ts": "2021-10-20T12:37:00Z+05:30",
  "params": {
    "resmsgid": "da7af22e-bdce-48f0-8743-f50fa6c2cd21",
    "msgid": null,
    "err": "NOT_FOUND",
    "status": "failed",
    "errmsg": "Error! Node(s) does not Exist. | [Invalid Node Id.]: do_11336893480941158908"
  },
  "responseCode": "RESOURCE_NOT_FOUND",
  "result": {
    "messages": null
  }
}
```

{% endtab %}

{% tab title="500: Internal Server Error Looks like something went wrong! These errors are tracked automatically." %}

```javascript
{
  "result": {},
  "id": "string",
  "ver": "string",
  "ts": "string",
  "params": {
    "resmsgid": "string",
    "msgid": "string",
    "err": "string",
    "status": "string",
    "errmsg": "string"
  },
  "responseCode": "string"
}
```

{% endtab %}
{% endtabs %}

#### Success result schema

<table><thead><tr><th width="189.33333333333331">Attribute</th><th width="142">Type</th><th>Description</th></tr></thead><tbody><tr><td>identidier</td><td>String</td><td>Unique Question identifier</td></tr><tr><td>versionKey</td><td>String</td><td>Unique version key for question</td></tr></tbody></table>

#### cURL

```shell
curl --location -g --request POST '{{host}}/question/v1/reject/{{question_id}}' \
--header 'Authorization: Bearer {{api_key}}' \
--header 'X-Channel-ID: {{channel_id}}' \
--header 'Content-Type: application/json' \
--data-raw '{
    "request": {
        "question": {
            "rejectComment":"Rejected for testing"
        }
    }
}'
```


# QuestionSet API's

List questionset related API's


# Create QuestionSet

This API is used to create a question set on the Sunbird-inQuiry Platform.

## This API is used to create a question set on the Sunbird-inQuiry Platform.

<mark style="color:green;">`POST`</mark> `/questionset/v1/create`

• The endpoint for Create QuestionSet is <mark style="color:orange;">/questionset/v1/create</mark>\
• It points to inquiry-api-service (assessment service) - <mark style="color:orange;">/questionset/v4/create</mark>\
• It is mandatory to provide values for parameters marked with <mark style="color:red;">\*</mark>\
• Mandatory fields cannot be null or empty.

#### Headers

| Name                                            | Type   | Description                                                                                                                                                                                                                                                 |
| ----------------------------------------------- | ------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Content-Type<mark style="color:red;">\*</mark>  | String | The Content-Type entity is the media type of the resource. The possible media types can be:- <mark style="color:green;">Application/json</mark>                                                                                                             |
| Authorization<mark style="color:red;">\*</mark> | String | <p>To make use of the API, you require authorization. Raise a request to the administrator for the use of the API. You will receive the authorization key. Specify the key received, here.<br>Set <mark style="color:green;">Bearer {{api\_key}}</mark></p> |
| x-channel-id                                    | String | Unique identification number associated with a root organization.                                                                                                                                                                                           |

#### Request Body

| Name                                      | Type   | Description                                                                    |
| ----------------------------------------- | ------ | ------------------------------------------------------------------------------ |
| request<mark style="color:red;">\*</mark> | Object | The body is the representation of the resource object for creating questionset |

{% tabs %}
{% tab title="200: OK The Create Questionset operation was successful!" %}

```javascript
{
  "id": "api.questionset.create",
  "ver": "3.0",
  "ts": "2021-02-03T08:17:28ZZ",
  "params": {
    "resmsgid": "4c45a5e2-c3b4-47c1-95a2-3a31f7e7c1ca",
    "msgid": null,
    "err": null,
    "status": "successful",
    "errmsg": null
  },
  "responseCode": "OK",
  "result": {
    "identifier": "do_113208291312132096114",
    "versionKey": "1612340248069"
  }
}
```

{% endtab %}

{% tab title="400: Bad Request The Create Questionset operation was failed! You may have missed input for the mandatory field" %}

```javascript
{
  "id": "api.questionset.create",
  "ver": "3.0",
  "ts": "2021-02-03T08:22:49ZZ",
  "params": {
    "resmsgid": "6cc7bb1c-330e-4da5-9075-1ac69cddf225",
    "msgid": null,
    "err": "CLIENT_ERROR",
    "status": "failed",
    "errmsg": "Validation Errors"
  },
  "responseCode": "CLIENT_ERROR",
  "result": {
    "messages": [
      "Metadata mimeType should be one of: [application/vnd.sunbird.questionset]"
    ]
  }
}
```

{% endtab %}

{% tab title="500: Internal Server Error We track these errors automatically and try to set it right at the earliest. Try refreshing the page." %}

```javascript
{
  "id": "api.questionset.create",
  "ver": "1.0",
  "ts": "2020-12-10T08:51:51.647Z",
  "params": {
    "resmsgid": "f234a6f0-3ac4-11eb-b0a2-8d5c9f561887",
    "msgid": null,
    "status": "failed",
    "err": null,
    "errmsg": null
  },
  "responseCode": "SERVER_ERROR",
  "result": {}
}
```

{% endtab %}
{% endtabs %}

#### Sample Request

```json
{
  "request": {
    "questionset": {
      "code": "asa1212",
      "mimeType": "application/vnd.sunbird.questionset",
      "primaryCategory": "Practice Question Set",
      "name": "Test Question Set"
    }
  }
}
```

#### Request Schema

<table><thead><tr><th width="180">Attribute</th><th width="99">Type</th><th>Description</th><th width="102">Required</th></tr></thead><tbody><tr><td>name</td><td>String</td><td>Represents the name of the questionset</td><td>Yes</td></tr><tr><td>code</td><td>String</td><td>Represents the unique code for the questionset</td><td>Yes</td></tr><tr><td>mimeType</td><td>String</td><td>questionset mime type</td><td>Yes</td></tr><tr><td>primaryCategory</td><td>String</td><td>PrimaryCategory agains which questionset schema will be validated</td><td>Yes</td></tr></tbody></table>

#### Success result schema

<table><thead><tr><th width="184">Attribute</th><th width="158.33333333333331">Type</th><th>Description</th></tr></thead><tbody><tr><td>identidier</td><td>String</td><td>Unique Question identifier</td></tr><tr><td>versionKey</td><td>String</td><td>Unique version key for question</td></tr></tbody></table>

#### cURL

```shell
curl --location -g --request POST '{{host}}/questionset/v1/create' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer {{api_key}}' \
--header 'X-Channel-Id: {{channel_id}}' \
--data-raw '{
    "request": {
        "questionset": {
            "code": "skhasa3232",
            "mimeType": "application/vnd.sunbird.questionset",
            "primaryCategory": "Practice Question Set",
            "name": "Test Question Set"
        }
    }
}'
```

#### Complete example

The following request is to create a question set object with basic information. To add additional metadata, and questions, please use the question-set update hierarchy API.

```json
{
  "request": {
    "questionset": {
      "name": "My QuestionSet",
      "mimeType": "application/vnd.sunbird.questionset",
      "primaryCategory": "Practice Question Set",
      "createdBy": "5a587cc1-e018-4859-a0a8-e842650b9d64",
      "createdFor": [
        "01309282781705830427"
      ],
      "framework": "inquiry_k-12",
      "code": "7d5aaa70-ffb8-d062-ba10-1db445a11dbc"
    }
  }
}
```


# Update QuestionSet

This API is used to update an existing question set on the Sunbird-inQuiry Platform.

## This API is used to update an existing question set on the Sunbird-inQuiry Platform.

<mark style="color:purple;">`PATCH`</mark> `/questionset/v1/update`

• <mark style="color:orange;">/Update/</mark> endpoint executes the "Update QuestionSet" request based on parameters provided as metadata in the request body.\
• It points to inquiry-api-service (assessment service) - <mark style="color:orange;">/questionset/v4/update</mark>\
• It is mandatory to provide values for parameters marked with <mark style="color:red;">\*</mark>. \
• Mandatory fields cannot be null or empty.

#### Path Parameters

| Name                                              | Type   | Description                                        |
| ------------------------------------------------- | ------ | -------------------------------------------------- |
| QuestionSet\_Id<mark style="color:red;">\*</mark> | String | Append a valid QuestionSet ID to the requested URL |

#### Headers

| Name                                            | Type   | Description                                                                                                                                                                                                                     |
| ----------------------------------------------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Content-Type<mark style="color:red;">\*</mark>  | String | The Content-Type entity is the media type of the resource. Possible media types can be:-<mark style="color:green;">Application/json</mark>                                                                                      |
| Authorization<mark style="color:red;">\*</mark> | String | <p>All question APIs require authorization for use. Specify the authorization key received from the administrator when placing the request for use of the API.<br>Set <mark style="color:green;">Bearer {{api\_key}}</mark></p> |
| x-channel-id                                    | String | Unique identification number associated with a root organization.                                                                                                                                                               |

#### Request Body

| Name                                      | Type   | Description                                               |
| ----------------------------------------- | ------ | --------------------------------------------------------- |
| request<mark style="color:red;">\*</mark> | Object | It contains metadata about the questionset to be updated. |

{% tabs %}
{% tab title="200: OK The Update Question Set operation was successfuly executed." %}

```javascript
{
  "id": "api.questionset.update",
  "ver": "3.0",
  "ts": "2021-02-02T19:55:07ZZ",
  "params": {
    "resmsgid": "9d9d4824-cc40-4ac7-a3d6-6da61c0240e9",
    "msgid": null,
    "err": null,
    "status": "successful",
    "errmsg": null
  },
  "responseCode": "OK",
  "result": {
    "identifier": "do_113207924037746688110",
    "versionKey": "1612295707004"
  }
}
```

{% endtab %}

{% tab title="400: Bad Request The 'Update QuestionSet' operation failed ! The possible reason for failure is that you may have missed providing input for a mandatory parameter." %}

```javascript
{
  "id": "api.questionset.update",
  "ver": "3.0",
  "ts": "2021-02-02T19:56:20ZZ",
  "params": {
    "resmsgid": "fcfcf6d6-84f1-43f5-b573-c3b6cf69ef53",
    "msgid": null,
    "err": "CLIENT_ERROR",
    "status": "failed",
    "errmsg": "Invalid version Key"
  },
  "responseCode": "CLIENT_ERROR",
  "result": {
    "messages": null
  }
}
```

{% endtab %}

{% tab title="404: Not Found The Update Question Set operation failed !The possible reason for failure is that you may have provided wrong question ID." %}

```javascript
{
  "id": "api.questionset.update",
  "ver": "3.0",
  "ts": "2021-02-02T19:57:35ZZ",
  "params": {
    "resmsgid": "2b139ee9-f091-4cca-b466-32af45f49a65",
    "msgid": null,
    "err": "NOT_FOUND",
    "status": "failed",
    "errmsg": "Error! Node(s) does not exist. | [Invalid Node Id.]: do_1132079240377466881101"
  },
  "responseCode": "RESOURCE_NOT_FOUND",
  "result": {
    "messages": null
  }
}
```

{% endtab %}

{% tab title="500: Internal Server Error Looks like something went wrong! These errors are tracked automatically" %}

```javascript
{
  "result": {},
  "id": "string",
  "ver": "string",
  "ts": "string",
  "params": {
    "resmsgid": "string",
    "msgid": "string",
    "err": "string",
    "status": "string",
    "errmsg": "string"
  },
  "responseCode": "string"
}
```

{% endtab %}
{% endtabs %}

#### Sample Request

```json
{
  "request": {
    "questionset": {
      "description": "Updated description",
      "versionKey": "1612295414767"
    }
  }
}
```

#### Request schema

<table><thead><tr><th width="168">Attribute</th><th width="111">Type</th><th width="353">Description</th><th>Required</th></tr></thead><tbody><tr><td>versionKey</td><td>String</td><td>Represents the transaction update version key of the Questionset</td><td>Yes</td></tr><tr><td>description</td><td>String</td><td>Represents the description of the Questionset</td><td>No</td></tr></tbody></table>

#### Success result schema

| Attribute  | Type   | Description                     |
| ---------- | ------ | ------------------------------- |
| identidier | String | Unique Question identifier      |
| versionKey | String | Unique version key for question |

####

#### cURL

```shell
curl --location -g --request PATCH '{{host}}/questionset/v1/update/{{questionSet_id}}' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer {{api_key}}' \
--data-raw '{
  "request": {
      "questionset":{
        "versionKey": {{versionKey}},
        "description": "Updated description"
      }
  }
}'
```


# Read QuestionSet

This API is used to read an existing question set on the Sunbird-inQuiry Platform.

## This API is used to read an existing question set on the Sunbird-inQuiry Platform.

<mark style="color:blue;">`GET`</mark> `/read/{QuestionSet_Id}`

• The <mark style="color:orange;">/questionset/v1/read/{QuestionSet\_Id}</mark> endpoint executes a request for fetching the question to read.\
• This API returns only the metadata of the question set not the hierarchical structure. To read  hierarchical structure please use **read** **questionset hierarchy** API\
• The endpoint for reading QuestionSet is <mark style="color:orange;">`/questionset/v1/read`</mark>\
• It points to inquiry-api-service (assessment service)  - <mark style="color:orange;">/questionset/v4/read</mark>\
• You need to provide a valid QuestionSet Id value in <mark style="color:orange;">{QuestionSet\_Id}</mark> field of the API URL. \
• It is mandatory to provide values for parameters marked with <mark style="color:red;">\*</mark>\
• Mandatory fields cannot be null or empty.

#### Path Parameters

| Name                                              | Type   | Description                                       |
| ------------------------------------------------- | ------ | ------------------------------------------------- |
| QuestionSet\_Id<mark style="color:red;">\*</mark> | String | Append a valid Question Set Id To the Request URL |

#### Query Parameters

| Name                                  | Type   | Description                                                                                                     |
| ------------------------------------- | ------ | --------------------------------------------------------------------------------------------------------------- |
| mode=edit                             | String | To fetch the latest version of node from the database for edit purpose                                          |
| fields=comma separated metadata names | String | To fetch the specific fields, this query parameter can be used eg. fields=name,description,outcomDeclaration... |

#### Headers

| Name          | Type   | Description                                                                                                                                                                                                                                                 |
| ------------- | ------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Content-Type  | String | The Content-Type entity is the media type of the resource. Possible media types can be: <mark style="color:green;">Application/json</mark>                                                                                                                  |
| Authorization | String | <p>To make use of the API, you require authorization. Raise a request to the administrator for the use of the API. You will receive the authorization key. Specify the key received, here.<br>Set <mark style="color:green;">Bearer {{api\_key}}</mark></p> |
| x-channel-id  | String | Unique identification number associated with a root organization.                                                                                                                                                                                           |

{% tabs %}
{% tab title="200: OK The "Read Question Set" operation was successfully executed" %}

```javascript
{
  "id": "api.questionset.read",
  "ver": "3.0",
  "ts": "2021-02-03T09:23:51ZZ",
  "params": {
    "resmsgid": "e9e05900-793b-4231-af75-ffa1a7a0b4c6",
    "msgid": null,
    "err": null,
    "status": "successful",
    "errmsg": null
  },
  "responseCode": "OK",
  "result": {
    "questionset": {
      "code": "finemanfine",
      "allowSkip": "Yes",
      "containsUserData": "No",
      "description": "hey",
      "language": [
        "English"
      ],
      "mimeType": "application/vnd.sunbird.questionset",
      "showHints": "No",
      "createdOn": "2021-02-03T09:23:34.060+0000",
      "objectType": "QuestionSet",
      "primaryCategory": "Practice Question Set",
      "contentDisposition": "inline",
      "lastUpdatedOn": "2021-02-03T09:23:34.060+0000",
      "contentEncoding": "gzip",
      "showSolutions": "Yes",
      "allowAnonymousAccess": "Yes",
      "identifier": "do_113208323801554944120",
      "lastStatusChangedOn": "2021-02-03T09:23:34.060+0000",
      "requiresSubmit": "Yes",
      "visibility": "Default",
      "showTimer": "No",
      "summaryType": "Complete",
      "consumerId": "fa13b438-8a3d-41b1-8278-33b0c50210e4",
      "setType": "materialised",
      "languageCode": [
        "en"
      ],
      "version": 1,
      "versionKey": "1612344214060",
      "showFeedback": "Yes",
      "license": "CC BY 4.0",
      "compatibilityLevel": 4,
      "name": "Test Question Set",
      "navigationMode": "linear",
      "shuffle": "Yes",
      "status": "Draft"
    }
  }
}
```

{% endtab %}

{% tab title="404: Not Found The Read Question Set operation failed! The possible reason for failure is that you may have provided wrong question set ID." %}

```javascript
{
  "id": "api.questionset.read",
  "ver": "3.0",
  "ts": "2021-02-02T20:01:13ZZ",
  "params": {
    "resmsgid": "815b341a-7984-45a1-b1f9-4335da18985e",
    "msgid": null,
    "err": "NOT_FOUND",
    "status": "failed",
    "errmsg": "Error! Node(s) does not exist. | [Invalid Node Id.]: do_1132083238015549441201"
  },
  "responseCode": "RESOURCE_NOT_FOUND",
  "result": {
    "messages": null
  }
}
```

{% endtab %}

{% tab title="500: Internal Server Error Looks like something went wrong! These errors are tracked automatically" %}

```javascript
{
  "result": {},
  "id": "string",
  "ver": "string",
  "ts": "string",
  "params": {
    "resmsgid": "string",
    "msgid": "string",
    "err": "string",
    "status": "string",
    "errmsg": "string"
  },
  "responseCode": "string"
}
```

{% endtab %}
{% endtabs %}

#### Success response schema

<table><thead><tr><th width="223">Attribute</th><th width="121.33333333333331">Type</th><th>Description</th></tr></thead><tbody><tr><td>identifier</td><td>String</td><td>Unique Question set Identifier</td></tr><tr><td>name</td><td>String</td><td>Name of the Question set</td></tr><tr><td>versionKey</td><td>String</td><td>Unique version key of Question set</td></tr><tr><td>code</td><td>String</td><td>Unique Code for Question set</td></tr><tr><td>lastStatusChangedOn</td><td>String</td><td>Last status changed time</td></tr><tr><td>visibility</td><td>String</td><td>Question set Visibility eg. parent or default</td></tr><tr><td>mimeType</td><td>String</td><td>Question mimeType eg. application/vnd.sunbird.questionset</td></tr><tr><td>createdOn</td><td>String</td><td>Time of question set creation</td></tr><tr><td>objectType</td><td>String</td><td>QuestionSet objectType</td></tr><tr><td>primaryCategory</td><td>String</td><td>Eg - <code>Practice Question set</code> or <code>Exam Question set</code></td></tr><tr><td>status</td><td>String</td><td>Question status <code>Draft/Review/Live</code></td></tr><tr><td>lastUpdatedOn</td><td>String</td><td>Last updated time</td></tr></tbody></table>

#### cURL

**Sample CURL to read all metadata**

```shell
curl --location -g --request GET '{{host}}/questionset/v1/read/{{questionSet_id}}' \
--header 'Authorization: Bearer {{api_key}}'
```

**Sample CURL to read all metadata**

```
curl --location -g --request GET '{{host}}/questionset/v1/read/{{questionSet_id}}?fields=name,description' \
--header 'Authorization: Bearer {{api_key}}'
```


# Read Private QuestionSet

This API is used to read an existing private question set on the Sunbird-inQuiry Platform.

## This API is used to read an existing private question set on the Sunbird-inQuiry Platform.

<mark style="color:blue;">`GET`</mark> `/questionset/v1/private/read`

• The <mark style="color:orange;">/private/read/{QuestionSet\_Id}</mark> endpoint executes a request for fetching the private and public question sets to be viewed and read. \
• The endpoint for reading Private QuestionSet is <mark style="color:orange;">/questionset/v1/private/read</mark>\
• It points to inquiry-api-service (assessment service) - <mark style="color:orange;">/questionset/v4/private/read</mark> \
• You need to provide a valid QuestionSet Id value in <mark style="color:orange;">{QuestionSet\_Id}</mark> field of the API URL.\
• It is mandatory to provide values for parameters marked with <mark style="color:red;">\*</mark>\
• Mandatory fields cannot be null or empty.

#### Path Parameters

| Name                                              | Type   | Description                                       |
| ------------------------------------------------- | ------ | ------------------------------------------------- |
| QuestionSet\_Id<mark style="color:red;">\*</mark> | String | Append a valid Question Set Id To the Request URL |

#### Headers

| Name                                            | Type   | Description                                                                                                                                                                                                                                                 |
| ----------------------------------------------- | ------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Content-Type                                    | String | The Content-Type entity is the media type of the resource. Possible media types can be: <mark style="color:green;">Application/json</mark>                                                                                                                  |
| Authorization<mark style="color:red;">\*</mark> | String | <p>To make use of the API, you require authorization. Raise a request to the administrator for the use of the API. You will receive the authorization key. Specify the key received, here.<br>Set <mark style="color:green;">Bearer {{api\_key}}</mark></p> |
| x-channel-id<mark style="color:red;">\*</mark>  | String | Unique identification number associated with a root organization.                                                                                                                                                                                           |

{% tabs %}
{% tab title="200: OK The "Read Private Question Set" operation was successfully executed" %}

```javascript
{
  "id": "api.questionset.private.read",
  "ver": "3.0",
  "ts": "2021-09-20T21:53:00Z+05:30",
  "params": {
    "resmsgid": "33f5a33f-5b2a-43ef-a3e8-67a6fffad675",
    "msgid": null,
    "err": null,
    "status": "successful",
    "errmsg": null
  },
  "responseCode": "OK",
  "result": {
    "questionset": {
      "copyright": "2021",
      "code": "c288ea98-0a8d-c927-5ec3-e879a90e9e43",
      "allowSkip": "Yes",
      "keywords": [
        "Hindi QuestionSet"
      ],
      "containsUserData": "No",
      "channel": "abc-123",
      "description": "Hindi QuestionSet",
      "language": [
        "English"
      ],
      "mimeType": "application/vnd.sunbird.questionset",
      "showHints": "No",
      "createdOn": "2021-09-18T13:55:52.003+0530",
      "objectType": "QuestionSet",
      "primaryCategory": "Practice Question Set",
      "contentDisposition": "inline",
      "additionalCategories": [
        "Textbook"
      ],
      "lastUpdatedOn": "2021-09-18T20:01:49.833+0530",
      "contentEncoding": "gzip",
      "generateDIALCodes": "No",
      "showSolutions": "No",
      "allowAnonymousAccess": "Yes",
      "identifier": "do_11336896348850585611",
      "lastStatusChangedOn": "2021-09-18T13:55:52.003+0530",
      "createdFor": [
        "01309282781705830427"
      ],
      "audience": [
        "Teacher"
      ],
      "requiresSubmit": "Yes",
      "visibility": "Private",
      "showTimer": "Yes",
      "author": "Test",
      "childNodes": [
        "do_11336896498434048013"
      ],
      "setType": "materialised",
      "lastPublishedBy": "testing",
      "languageCode": [
        "en"
      ],
      "version": 1,
      "versionKey": "1631975509833",
      "showFeedback": "Yes",
      "license": "CC BY 4.0",
      "maxAttempts": 3,
      "framework": "tn_k-12",
      "depth": 0,
      "createdBy": "5a587cc1-e018-4859-a0a8-e842650b9d64",
      "compatibilityLevel": 5,
      "name": "Hindi QuestionSet",
      "navigationMode": "non-linear",
      "timeLimits": [
        {
          "maxTime": "18549"
        },
        {
          "warningTime": "7200"
        }
      ],
      "shuffle": true,
      "attributions": [
        "VB",
        " Nk"
      ],
      "status": "Draft"
    }
  }
}
```

{% endtab %}

{% tab title="404: Not Found The Read Private Question Set operation failed! The possible reason for failure is that you may have provided wrong question set ID." %}

```javascript
{
  "id": "api.questionset.private.read",
  "ver": "3.0",
  "ts": "2021-09-20T22:00:42Z+05:30",
  "params": {
    "resmsgid": "50bd44a0-ccc8-48fd-9361-3a2990f44e16",
    "msgid": null,
    "err": "NOT_FOUND",
    "status": "failed",
    "errmsg": "Error! Node(s) doesn't Exists. | [Invalid Node Id.]: do_11336896348850585612"
  },
  "responseCode": "RESOURCE_NOT_FOUND",
  "result": {
    "messages": null
  }
}
```

{% endtab %}

{% tab title="500: Internal Server Error Looks like something went wrong! These errors are tracked automatically" %}

```javascript
{
  "result": {},
  "id": "string",
  "ver": "string",
  "ts": "string",
  "params": {
    "resmsgid": "string",
    "msgid": "string",
    "err": "string",
    "status": "string",
    "errmsg": "string"
  },
  "responseCode": "string"
}
```

{% endtab %}
{% endtabs %}

#### cURL

```shell
curl --location -g --request GET '{{host}}/questionset/v1/private/read/{{questionSet_id}}' \
--header 'Authorization: Bearer {{api_key}}' \
--header 'X-Channel-ID: {{channel_id}}'
```


# Review QuestionSet

This API is used to send question set for review on the Sunbird-inQuiry Platform.

## This API is used to send question set for review on the Sunbird-inQuiry Platform.

<mark style="color:green;">`POST`</mark> `/review/{QuestionSet_Id}`

• The <mark style="color:orange;">/review/{QuestionSet\_Id}</mark> endpoint executes the "***Submit for Review***" request based on parameters provided as metadata in the request body. \
• It points to inquiry-api-service (assessment service) - <mark style="color:orange;">/questionset/v4/review</mark>\
• You need to provide a valid QuestionSet Id value in <mark style="color:orange;">{QuestionSet\_Id}</mark> field of the API URL. \
• It is mandatory to provide values for parameters marked with <mark style="color:red;">\*</mark>\
• Mandatory fields cannot be null or empty.

#### Path Parameters

| Name                                              | Type   | Description                                       |
| ------------------------------------------------- | ------ | ------------------------------------------------- |
| QuestionSet\_Id<mark style="color:red;">\*</mark> | String | Append a valid Question Set Id To the Request URL |

#### Headers

| Name                                            | Type   | Description                                                                                                                                                                                                                                                    |
| ----------------------------------------------- | ------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Content-Type<mark style="color:red;">\*</mark>  | String | The Content-Type entity is the media type of the resource. Possible media types can be: <mark style="color:green;">Application/json</mark>                                                                                                                     |
| Authorization<mark style="color:red;">\*</mark> | String | <p>To make use of the API, you require authorization. Raise a request to the administrator for the use of the API. You will receive the authorization key. Specify the key received, here.</p><p>Set <mark style="color:green;">Bearer {{api\_key}}</mark></p> |
| x-channel-id                                    | String | Unique identification number associated with a root organization.                                                                                                                                                                                              |

#### Request Body

| Name    | Type   | Description                                               |
| ------- | ------ | --------------------------------------------------------- |
| request | Object | It contains metadata about the questionset to be updated. |

{% tabs %}
{% tab title="200: OK  The 'Review Question Set' operation failed ! The possible reason for failure is that you may have missed providing input for a mandatory parameter." %}

```javascript
{
  "id": "api.questionset.review",
  "ver": "3.0",
  "ts": "2021-02-03T09:30:21ZZ",
  "params": {
    "resmsgid": "679a458f-cd12-4dee-a6b4-5aea11fbe426",
    "msgid": null,
    "err": null,
    "status": "successful",
    "errmsg": null
  },
  "responseCode": "OK",
  "result": {
    "identifier": "do_113208323801554944120",
    "versionKey": "1612344214060"
  }
}
```

{% endtab %}

{% tab title="400: Bad Request The 'Review Question Set' operation failed ! The possible reason for failure is that you may have missed providing input for a mandatory parameter." %}

```javascript
{
  "id": "api.questionset.review",
  "ver": "3.0",
  "ts": "2021-02-03T09:33:32ZZ",
  "params": {
    "resmsgid": "95670d2a-764c-489f-bf27-b4acedc4b465",
    "msgid": null,
    "err": "ERR_QUESTION_SET_REVIEW",
    "status": "failed",
    "errmsg": "A question set with status other than Draft can't be sent for review."
  },
  "responseCode": "CLIENT_ERROR",
  "result": {
    "messages": null
  }
}
```

{% endtab %}

{% tab title="404: Not Found The Send Question Set for Review operation failed! The possible reason for failure is that you may have provided wrong question set ID." %}

```javascript
{
  "id": "api.questionset.review",
  "ver": "3.0",
  "ts": "2021-02-02T20:07:24ZZ",
  "params": {
    "resmsgid": "852b878c-a607-4d72-9458-6239e36adb9e",
    "msgid": null,
    "err": "NOT_FOUND",
    "status": "failed",
    "errmsg": "Error! Node(s) does not exist. | [Invalid Node Id.]: do_1132079319215554561111"
  },
  "responseCode": "RESOURCE_NOT_FOUND",
  "result": {
    "messages": null
  }
}
```

{% endtab %}

{% tab title="500: Internal Server Error Looks like something went wrong! We track these errors automatically" %}

```javascript
{
  "id": "api.questionset.review",
  "ver": "3.0",
  "ts": "2021-02-02T20:07:24ZZ",
  "params": {
    "resmsgid": "852b878c-a607-4d72-9458-6239e36adb9e",
    "msgid": null,
    "err": "NOT_FOUND",
    "status": "failed",
    "errmsg": "Error! Node(s) does not exist. | [Invalid Node Id.]: do_1132079319215554561111"
  },
  "responseCode": "RESOURCE_NOT_FOUND",
  "result": {
    "messages": null
  }
}
```

{% endtab %}
{% endtabs %}

#### Success result schema

<table><thead><tr><th width="154.33333333333331">Attribute</th><th width="257">Type</th><th>Description</th></tr></thead><tbody><tr><td>identidier</td><td>String</td><td>Unique Question identifier</td></tr><tr><td>versionKey</td><td>String</td><td>Unique version key for question</td></tr></tbody></table>

#### cURL

```shell
curl --location -g --request POST '{{host}}/questionset/v1/review/{{questionSet_id}}' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer {{api_key}}' \
--header 'X-Channel-Id: {{channel_id}}' \
--data-raw '{
  "request": {
    "questionset": {}
  }
}'
```


# Reject QuestionSet

This API is used to reject the question set, which is sent for review on the Sunbird-inQuiry Platform.

## This API is used to reject the question set, which is sent for review on the Sunbird-inQuiry Platform.

<mark style="color:green;">`POST`</mark> `/questionset/v1/reject/{QuestionSet_Id}}`

• The  <mark style="color:orange;">/reject/{QuestionSet\_Id}</mark> endpoint executes the "Rejecting QuestionSet" request based on parameters provided as metadata in the request body.\
• It points to inquiry-api-service (assessment service) - <mark style="color:orange;">/questionset/v4/reject/QuestionSet\_Id</mark>\
• You need to provide a valid QuestionSet Id value in the <mark style="color:orange;">{QuestionSet\_Id}</mark> field of the API URL. \
• It is mandatory to provide values for parameters marked with <mark style="color:red;">\*</mark>\
• Mandatory fields cannot be null or empty.

#### Path Parameters

| Name                                              | Type   | Description                                       |
| ------------------------------------------------- | ------ | ------------------------------------------------- |
| QuestionSet\_Id<mark style="color:red;">\*</mark> | String | Append a valid Question Set Id To the Request URL |

#### Headers

| Name                                            | Type   | Description                                                                                                                                                                                                                    |
| ----------------------------------------------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| Content-Type<mark style="color:red;">\*</mark>  | String | The Content-Type entity is the media type of the resource. Possible media types can be: <mark style="color:green;">Application/json</mark>                                                                                     |
| Authorization<mark style="color:red;">\*</mark> | String | <p>All content APIs require authorization for use. Specify the authorization key received from the administrator when placing the request for use of the API.<br>Set <mark style="color:green;">Bearer {{api\_key}}</mark></p> |
| x-channel-id                                    | String | Unique identification number associated with a root organization.                                                                                                                                                              |

#### Request Body

| Name    | Type   | Description                                       |
| ------- | ------ | ------------------------------------------------- |
| request | Object | The metadata about the questionset to be rejected |

{% tabs %}
{% tab title="200: OK  Reject QuestionSet review operation was successfully executed." %}

```javascript
{
  "id": "api.questionset.reject",
  "ver": "3.0",
  "ts": "2021-02-03T12:11:35ZZ",
  "params": {
    "resmsgid": "a505a723-616f-4e3f-9a52-2f0d9924f732",
    "msgid": null,
    "err": null,
    "status": "successful",
    "errmsg": null
  },
  "responseCode": "OK",
  "result": {
    "identifier": "do_113208406116417536122",
    "versionKey": "1612354279918"
  }
}
```

{% endtab %}

{% tab title="400: Bad Request The 'Review Reject QuestionSet' operation failed ! The possible reason for failure is that you may have missed providing input for a mandatory parameter." %}

```javascript
{
  "id": "api.questionset.reject",
  "ver": "3.0",
  "ts": "2021-02-03T12:16:59ZZ",
  "params": {
    "resmsgid": "cbcaa290-e132-47e6-b4d9-94212037195d",
    "msgid": null,
    "err": "ERR_QUESTION_SET_REJECT",
    "status": "failed",
    "errmsg": "QuestionSet is not in 'Review' state for identifier: do_113208406116417536122"
  },
  "responseCode": "CLIENT_ERROR",
  "result": {
    "messages": null
  }
}
```

{% endtab %}

{% tab title="404: Not Found The 'Review Reject QuestionSet' operation failed ! The possible reason for failure is that you may have missed providing input for a mandatory parameter." %}

```javascript
{
  "id": "api.questionset.reject",
  "ver": "3.0",
  "ts": "2021-02-03T12:15:36ZZ",
  "params": {
    "resmsgid": "6fc0bd55-e99e-4ae1-80e2-7275458258ab",
    "msgid": null,
    "err": "NOT_FOUND",
    "status": "failed",
    "errmsg": "Error! Node(s) doesn't Exists. | [Invalid Node Id.]: do_1132084061164175361221"
  },
  "responseCode": "RESOURCE_NOT_FOUND",
  "result": {
    "messages": null
  }
}
```

{% endtab %}

{% tab title="500: Internal Server Error Looks like something went wrong! We track these errors automatically, but if the problem persists feel free to contact us. In the meantime, try refreshing." %}

```javascript
{
  "result": {},
  "id": "string",
  "ver": "string",
  "ts": "string",
  "params": {
    "resmsgid": "string",
    "msgid": "string",
    "err": "string",
    "status": "string",
    "errmsg": "string"
  },
  "responseCode": "string"
}
```

{% endtab %}
{% endtabs %}

#### Request Sample

```json
{
  "request": {
    "questionset": {
      "rejectComment": "Rejected for testing"
    }
  }
}
```

#### Request Schema

<table><thead><tr><th>Attribute</th><th width="122">Type</th><th>Description</th><th>Required</th></tr></thead><tbody><tr><td>rejectComment</td><td>String</td><td>Question set rejection comment/reason</td><td>Yes</td></tr></tbody></table>

#### Success result schema

<table><thead><tr><th width="189">Attribute</th><th width="120.33333333333331">Type</th><th>Description</th></tr></thead><tbody><tr><td>identidier</td><td>String</td><td>Unique Question identifier</td></tr><tr><td>versionKey</td><td>String</td><td>Unique version key for question</td></tr></tbody></table>

#### cURL

```shell
curl '{{host}}/questionset/v1/reject/{{questionSet_id}}' \
  -H 'Authorization: Bearer {{api_key}}' \
  -H 'Content-Type: application/json' \
  --data-raw '{"request":{"questionset":{"rejectComment":"Not aligned"}}}' \
  --compressed
```


# Publish QuestionSet

This API is used to publish the question set on the Sunbird-inQuiry Platform.

## This API is used to publish the question set on the Sunbird-inQuiry Platform.

<mark style="color:green;">`POST`</mark> `/questionset/v1/publish/QuestionSet_Id`

• <mark style="color:orange;">/publish/QuestionSet\_Id</mark> endpoint executes the "Publish QuestionSet" request based on parameters provided as metadata in the request body. \
• It points to inquiry-api-service (assessment service) - <mark style="color:orange;">/questionset/v4/publish/QuestionSet\_Id</mark>\
• It is mandatory to provide values for parameters marked with <mark style="color:red;">\*</mark>\
• Mandatory fields cannot be null or empty.\ <mark style="color:green;">•</mark> <mark style="color:orange;">Asynchronous flink job : async-questionset-publish will takes care of the publishing activity.</mark>

#### Path Parameters

| Name            | Type   | Description                                       |
| --------------- | ------ | ------------------------------------------------- |
| QuestionSet\_Id | String | Append a valid Question Set Id To the Request URL |

#### Headers

| Name                                            | Type   | Description                                                                                                                                                                                                                    |
| ----------------------------------------------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| Content-Type<mark style="color:red;">\*</mark>  | String | The Content-Type entity is the media type of the resource. Possible media types can be: <mark style="color:green;">Application/json</mark>                                                                                     |
| Authorization<mark style="color:red;">\*</mark> | String | <p>All content APIs require authorization for use. Specify the authorization key received from the administrator when placing the request for use of the API.<br>Set <mark style="color:green;">Bearer {{api\_key}}</mark></p> |
| x-channel-id                                    | String | Unique identification number associated with a root organization.                                                                                                                                                              |

#### Request Body

| Name    | Type   | Description                                                                       |
| ------- | ------ | --------------------------------------------------------------------------------- |
| request | Object | The body is the representation of the resource object for publishing question set |

{% tabs %}
{% tab title="200: OK QuestionSet publish operation was successfully executed." %}

```javascript
{
  "id": "api.questionset.publish",
  "ver": "3.0",
  "ts": "2021-02-03T09:39:14ZZ",
  "params": {
    "resmsgid": "62f7e310-39e1-4287-bc9f-f8e6ac5f5bd3",
    "msgid": null,
    "err": null,
    "status": "successful",
    "errmsg": null
  },
  "responseCode": "OK",
  "result": {
    "message": "Question is successfully sent for Publish",
    "identifier": "do_113208323801554944120"
  }
}
```

{% endtab %}

{% tab title="404: Not Found QuestionSet Send for publish operation failed !The possible reason for failure is that you may have provided wrong questionset id." %}

```javascript
{
  "id": "api.questionset.publish",
  "ver": "3.0",
  "ts": "2021-02-03T09:39:14ZZ",
  "params": {
    "resmsgid": "62f7e310-39e1-4287-bc9f-f8e6ac5f5bd3",
    "msgid": null,
    "err": null,
    "status": "successful",
    "errmsg": null
  },
  "responseCode": "OK",
  "result": {
    "message": "Question is successfully sent for Publish",
    "identifier": "do_113208323801554944120"
  }
}
```

{% endtab %}

{% tab title="500: Internal Server Error Looks like something went wrong! We track these errors automatically" %}

```javascript
{
  "result": {},
  "id": "string",
  "ver": "string",
  "ts": "string",
  "params": {
    "resmsgid": "string",
    "msgid": "string",
    "err": "string",
    "status": "string",
    "errmsg": "string"
  },
  "responseCode": "string"
}
```

{% endtab %}
{% endtabs %}

#### Request Sample

```json
{
  "request": {
    "questionset": {
      "lastPublishedBy": "ae94b68c-a535-4dce-8e7a-fb9662b0ad68"
    }
  }
}
```

#### Success result schema

<table><thead><tr><th width="183">Attribute</th><th width="141.33333333333331">Type</th><th>Description</th></tr></thead><tbody><tr><td>identidier</td><td>String</td><td>Unique Question identifier</td></tr><tr><td>message</td><td>String</td><td>Publish success message</td></tr></tbody></table>

#### cURL

```shell
curl --location -g --request POST '{{host}}/questionset/v1/publish/{{questionSet_id}}' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer {{api_key}}' \
--header 'X-Channel-Id: {{channel_id}}' \
--data-raw '{
  "request": {
    "questionset": {}
  }
}'
```


# Retire QuestionSet

This API is used to retire the question set on the Sunbird-inQuiry Platform.

## This API is used to retire the question set on the Sunbird-inQuiry Platform.

<mark style="color:red;">`DELETE`</mark> `/retire/{QuestionSet_Id}`

• The <mark style="color:orange;">/retire/{QuestionSet\_Id}</mark> endpoint executes a "Retire QuestionSet" request based on <mark style="color:orange;">QuestionSet\_Id</mark> to delete the specific Question set.\
• The endpoint for Retire QuestionSet is <mark style="color:orange;">/questionset/v1/retire</mark> \
•  It points to inquiry-api-service (assessment service) - <mark style="color:orange;">/questionset/v4/retire</mark> \
• It is mandatory to provide values for parameters. \
• Mandatory fields cannot be null or empty.

#### Path Parameters

| Name                                              | Type   | Description                                             |
| ------------------------------------------------- | ------ | ------------------------------------------------------- |
| QuestionSet\_Id<mark style="color:red;">\*</mark> | String | Please append a valid QuestionSet Id to the Request URL |

#### Headers

| Name                                            | Type   | Description                                                                                                                                                                                                                        |
| ----------------------------------------------- | ------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Authorization<mark style="color:red;">\*</mark> | String | <p>All questionset APIs require authorization for use. Specify the authorization key received from the administrator when placing the request for use of the API.<br>Set <mark style="color:green;">Bearer {{api\_key}}</mark></p> |
| x-channel-id                                    | String | Unique identification number associated with a root organization.                                                                                                                                                                  |

#### Request Body

| Name    | Type   | Description                                                                       |
| ------- | ------ | --------------------------------------------------------------------------------- |
| request | Object | The body is the representation of the resource object for retiring a question set |

{% tabs %}
{% tab title="200: OK QuestionSet deletion operation was successfully executed." %}

```javascript
{
  "id": "api.questionset.retire",
  "ver": "3.0",
  "ts": "2021-02-02T20:20:56ZZ",
  "params": {
    "resmsgid": "98c9f97d-f9d6-4da9-be88-2852294c2aaa",
    "msgid": null,
    "err": null,
    "status": "successful",
    "errmsg": null
  },
  "responseCode": "OK",
  "result": {
    "identifier": "do_113207939069968384112",
    "versionKey": "1612297249754"
  }
}
```

{% endtab %}

{% tab title="400: Bad Request QuestionSet is already retired." %}

```javascript
{
  "id": "api.questionset.retire",
  "ver": "3.0",
  "ts": "2021-02-02T20:21:26ZZ",
  "params": {
    "resmsgid": "0608b59d-dfb9-4c0e-807f-1a19c9a163fe",
    "msgid": null,
    "err": "ERR_QUESTION_RETIRE",
    "status": "failed",
    "errmsg": "QuestionSet with identifier : do_113207939069968384112 is already Retired."
  },
  "responseCode": "CLIENT_ERROR",
  "result": {
    "messages": null
  }
}
```

{% endtab %}

{% tab title="404: Not Found QuestionSet Send for Retire operation failed! The possible reason for failure is that you may have provided wrong questionset id." %}

```javascript
{
  "id": "api.questionset.retire",
  "ver": "3.0",
  "ts": "2021-02-02T20:22:03ZZ",
  "params": {
    "resmsgid": "da7af22e-bdce-48f0-8743-f50fa6c2cd21",
    "msgid": null,
    "err": "NOT_FOUND",
    "status": "failed",
    "errmsg": "Error! Node(s) doesn't Exists. | [Invalid Node Id.]: do_1132079390699683841121"
  },
  "responseCode": "RESOURCE_NOT_FOUND",
  "result": {
    "messages": null
  }
}
```

{% endtab %}

{% tab title="500: Internal Server Error Looks like something went wrong! These errors are tracked automatically" %}

```javascript
{
  "result": {},
  "id": "string",
  "ver": "string",
  "ts": "string",
  "params": {
    "resmsgid": "string",
    "msgid": "string",
    "err": "string",
    "status": "string",
    "errmsg": "string"
  },
  "responseCode": "string"
}
```

{% endtab %}
{% endtabs %}

#### Success result schema

<table><thead><tr><th width="188">Attribute</th><th width="159.33333333333331">Type</th><th>Description</th></tr></thead><tbody><tr><td>identidier</td><td>String</td><td>Unique Question identifier</td></tr><tr><td>versionKey</td><td>String</td><td>Unique version key for question</td></tr></tbody></table>

#### cURL

```shell
curl --location -g --request DELETE '{{host}}/questionset/v1/retire/{{questionSet_id}}' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer {{api_key}}' \
--header 'X-Channel-Id: {{channel_id}}' \
--data-raw '{
  "request": {
    "questionset": {
    }
  }
}'
```


# Update Hierarchy QuestionSet

This API is used to update the existing question set on the Sunbird-inQuiry Platform.

## This API is used to update the existing question set on the Sunbird-inQuiry Platform.

<mark style="color:purple;">`PATCH`</mark> `/hierarchy/update`

• <mark style="color:orange;">/hierarchy/update/</mark> endpoint executes the "Update Hierarchy QuestionSet" request based on parameters provided as metadata in the request body.\
•This API is used to add new children and update the existing children or update a hierarchical structure of the question set.\
• It points to inquiry-api-service (assessment service) - <mark style="color:orange;">/questionset/v4/hierarchy/update</mark> \
• It is mandatory to provide values for parameters marked with <mark style="color:red;">\*</mark>\
• Mandatory fields cannot be null or empty.

#### Headers

| Name                                            | Type   | Description                                                                                                                                                                                                                     |
| ----------------------------------------------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Content-Type<mark style="color:red;">\*</mark>  | String | The Content Type entity is the media type of the resource.Possible media types can be: <mark style="color:green;">Application/json</mark>                                                                                       |
| Authorization<mark style="color:red;">\*</mark> | String | <p>All question APIs require authorization for use. Specify the authorization key received from the administrator when placing the request for use of the API.<br>Set <mark style="color:green;">Bearer {{api\_key}}</mark></p> |
| x-channel-id                                    | String | Unique identification number associated with a root organization.                                                                                                                                                               |

#### Request Body

| Name                                      | Type   | Description                                                             |
| ----------------------------------------- | ------ | ----------------------------------------------------------------------- |
| request<mark style="color:red;">\*</mark> | Object | It contains metadata and a hierarchy of the question set to be updated. |

{% tabs %}
{% tab title="200: OK QuestionSet update hierarchy operation was successfuly executed." %}

```javascript
{
  "id": "api.questionset.hierarchy.update",
  "ver": "3.0",
  "ts": "2021-02-03T13:06:12ZZ",
  "params": {
    "resmsgid": "221f9cdb-c220-4d3f-a579-4e7b82facf89",
    "msgid": null,
    "err": null,
    "status": "successful",
    "errmsg": null
  },
  "responseCode": "OK",
  "result": {
    "identifier": "do_113208431570984960123",
    "identifiers": {
      "section-1": "do_113208433229889536126",
      "question-1": "do_113208433229873152124"
    }
  }
}
```

{% endtab %}

{% tab title="400: Bad Request The 'Update Hierarchy QuestionSet' operation failed ! The possible reason for failure is that you may have missed providing input for a mandatory parameter." %}

```javascript
{
  "id": "api.questionset.hierarchy.update",
  "ver": "3.0",
  "ts": "2021-02-03T13:11:14ZZ",
  "params": {
    "resmsgid": "04e218fc-76bc-4fd3-b98d-5ed947a30b8b",
    "msgid": null,
    "err": "ERR_QS_UPDATE_HIERARCHY",
    "status": "failed",
    "errmsg": "Question cannot have children in hierarchy"
  },
  "responseCode": "CLIENT_ERROR",
  "result": {
    "messages": null
  }
}
```

{% endtab %}

{% tab title="404: Not Found QuestionSet Update Hierarchy operation failed !The possible reason for failure is that you may have provided wrong questionset id." %}

```javascript
{
  "id": "api.questionset.hierarchy.update",
  "ver": "3.0",
  "ts": "2021-02-03T13:27:12ZZ",
  "params": {
    "resmsgid": "0fbe77de-a612-4406-bcd2-a63de5b29b6d",
    "msgid": null,
    "err": "NOT_FOUND",
    "status": "failed",
    "errmsg": "Error! Node(s) doesn't Exists. | [Invalid Node Id.]: do_1132084315709849601231"
  },
  "responseCode": "RESOURCE_NOT_FOUND",
  "result": {
    "messages": null
  }
}
```

{% endtab %}

{% tab title="500: Internal Server Error Looks like something went wrong! These errors are tracked automatically" %}

```javascript
{
  "result": {},
  "id": "string",
  "ver": "string",
  "ts": "string",
  "params": {
    "resmsgid": "string",
    "msgid": "string",
    "err": "string",
    "status": "string",
    "errmsg": "string"
  },
  "responseCode": "string"
}
```

{% endtab %}
{% endtabs %}

#### Request Sample

```json
{
  "request": {
    "data": {
      "nodesModified": {
        "do_213683948732522496129": {
          "root": true,
          "objectType": "QuestionSet",
          "metadata": {
            "appIcon": "https://sunbirddevbbpublic.blob.core.windows.net/sunbird-content-staging/content/assets/do_2136839488184156161188/istockphoto-184276818-612x612.jpg",
            "name": "QuestionSet-Draft5",
            "description": "test",
            "instructions": {
              "default": "<p>test</p>"
            },
            "primaryCategory": "Practice Question Set",
            "additionalCategories": [

            ],
            "board": "CBSE",
            "medium": [
              "English"
            ],
            "gradeLevel": [
              "Class 4"
            ],
            "subject": [
              "Math"
            ],
            "audience": [
              "Student"
            ],
            "showTimer": "No",
            "requiresSubmit": "No",
            "author": "N11",
            "copyright": "NIT123",
            "license": "CC BY 4.0",
            "attributions": [

            ],
            "maxScore": 1
          },
          "isNew": false
        },
        "do_213683949640613888132": {
          "root": false,
          "objectType": "QuestionSet",
          "metadata": {
            "name": "Section-101",
            "description": "test",
            "shuffle": true,
            "showFeedback": "Yes",
            "showSolutions": "Yes",
            "primaryCategory": "Practice Question Set",
            "attributions": [

            ]
          },
          "isNew": false
        }
      },
      "hierarchy": {
        "do_213683948732522496129": {
          "name": "QuestionSet-Draft5",
          "children": [
            "do_213683949640613888132"
          ],
          "root": true
        },
        "do_213683949640613888132": {
          "name": "Section-101",
          "children": [
            "do_21368395028149862413"
          ],
          "root": false
        },
        "do_21368395028149862413": {
          "name": "sub",
          "children": [

          ],
          "root": false
        }
      },
      "lastUpdatedBy": "5a587cc1-e018-4859-a0a8-e842650b9d64"
    }
  }
}
```

#### Request Shema

<table><thead><tr><th width="169">Attribute</th><th width="87">Type</th><th width="344">Description</th><th>Required</th></tr></thead><tbody><tr><td>nodesModified</td><td>Object</td><td>objects details to be created or updated</td><td>Yes</td></tr><tr><td>hierarchy</td><td>Object</td><td>objects hierarchy details</td><td>Yes</td></tr></tbody></table>

#### Success result schema

<table><thead><tr><th width="164">Attribute</th><th width="136.33333333333331">Type</th><th>Description</th></tr></thead><tbody><tr><td>identidier</td><td>String</td><td>Unique Question identifier</td></tr><tr><td>identifiers</td><td>String</td><td>Object mapping i.e. created or updated</td></tr></tbody></table>

#### cURL

```shell
curl --location -g --request PATCH '{{host}}/questionset/v1/hierarchy/update' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer {{api_key}}' \
--data-raw '{
  "request": {
    "data": {
      "nodesModified": {
        "{questionSet-id}}": {
          "metadata": {
            "code": "updated_code_of_root"
          },
          "root": true,
          "isNew": false
        },
        "section-1": {
          "metadata": {
            "code": "section-1",
            "name": "Section-1",
            "description": "Section-1",
            "mimeType": "application/vnd.sunbird.questionset",
            "visibility":"Parent",
            "primaryCategory": "Practice Question Set"
          },
          "root": false,
          "isNew": true
        },
        "question-1": {
          "metadata": {
            "code": "question-1",
            "name": "Question-1",
            "description": "Question-1",
            "mimeType": "application/vnd.sunbird.question",
            "visibility": "Parent",
            "primaryCategory": "Multiple Choice Question"
          },
          "root": false,
          "isNew": true
        }
      },
      "hierarchy": {
        "{{questionSet-id}}": {
          "children": [
            "section-1"
          ],
          "root": true
        },
        "section-1": {
          "children": [
          "question-1"
          ],
          "root": false
        }
      }
    }
  }
}'
```

**Complete example**

The following request is for updating the existing question set. Here, a new question (MCQ) is added to one of the sections of the question set.

```json
{
  "request": {
    "data": {
      "nodesModified": {
        "75da35b2-3359-4f7c-82e3-7d40d13acd96": {
          "metadata": {
            "mimeType": "application/vnd.sunbird.question",
            "media": [
            ],
            "editorState": {
              "options": [
                {
                  "answer": true,
                  "value": {
                    "body": "<p>Yellow</p>",
                    "value": 0
                  }
                },
                {
                  "answer": false,
                  "value": {
                    "body": "<p>Red</p>",
                    "value": 1
                  }
                },
                {
                  "answer": false,
                  "value": {
                    "body": "<p>Orange</p>",
                    "value": 2
                  }
                }
              ],
              "question": "<p>What is the color of lemon?</p>"
            },
            "templateId": "mcq-vertical",
            "answer": "0",
            "maxScore": 1,
            "name": "1",
            "responseDeclaration": {
              "response1": {
                "maxScore": 1,
                "cardinality": "single",
                "type": "integer",
                "correctResponse": {
                  "value": "0",
                  "outcomes": {
                    "SCORE": 1
                  }
                },
                "mapping": [

                ]
              }
            },
            "interactionTypes": [
              "choice"
            ],
            "interactions": {
              "response1": {
                "type": "choice",
                "options": [
                  {
                    "label": "<p>Yellow</p>",
                    "value": 0
                  },
                  {
                    "label": "<p>Red</p>",
                    "value": 1
                  },
                  {
                    "label": "<p>Orange</p>",
                    "value": 2
                  }
                ]
              },
              "validation": {
                "required": "Yes"
              }
            },
            "qType": "MCQ",
            "primaryCategory": "Multiple Choice Question",
            "body": "<div class='question-body' tabindex='-1'><div class='mcq-title' tabindex='0'><p>What is the color of lemon?</p></div><div data-choice-interaction='response1' class='mcq-vertical'></div></div>",
            "solutions": [

            ],
            "createdBy": "5a587cc1-e018-4859-a0a8-e842650b9d64",
            "board": "CBSE",
            "medium": [
              "English"
            ],
            "gradeLevel": [
              "Class 4"
            ],
            "subject": [
              "Geography"
            ],
            "author": "N11",
            "channel": "01309282781705830427",
            "framework": "inquiry_k-12",
            "copyright": "NIT123",
            "audience": [
              "Administrator"
            ],
            "license": "CC BY 4.0"
          },
          "objectType": "Question",
          "root": false,
          "isNew": true
        }
      },
      "hierarchy": {
        "do_213703055622299648111": {
          "name": "Test QuestionSet",
          "children": [
            "do_213703056367386624112"
          ],
          "root": true
        },
        "do_213703056367386624112": {
          "name": "Section 1",
          "children": [
            "75da35b2-3359-4f7c-82e3-7d40d13acd96"
          ],
          "root": false
        }
      }
    }
  }
}
```

<br>


# Read QuestionSet Hierarchy

This API is used to read the question set on the Sunbird-inQuiry Platform.

## This API is used to read the question set on the Sunbird-inQuiry Platform.

<mark style="color:blue;">`GET`</mark> `/hierarchy/{QuestionSet_Id}`

• The <mark style="color:orange;">/hierarchy/{QuestionSet\_Id}</mark> endpoint executes a request for fetching the question set hierarchical structure. \
• By default, this API tries to fetch a question set with live status. If you need to fetch the hierarchy of qustion set having any other status please use mode=edit query parameter.\
• The endpoint for reading QuestionSet Hierarchy is <mark style="color:orange;">/questionset/v1/hierarchy</mark> \
• It points to inquiry-api-service (assessment service) - <mark style="color:orange;">/questionset/v4/hierarchy</mark> \
• You need to provide a valid QuestionSet Id value in {<mark style="color:orange;">QuestionSet\_Id}</mark> field of the API URL. \
• It is mandatory to provide values for parameters marked with <mark style="color:red;">\*</mark>\
• Mandatory fields cannot be null or empty.

#### Path Parameters

| Name                                              | Type   | Description                                             |
| ------------------------------------------------- | ------ | ------------------------------------------------------- |
| QuestionSet\_Id<mark style="color:red;">\*</mark> | String | Please append a valid QuestionSet Id to the Request URL |

#### Query Parameters

| Name      | Type   | Description                                                                                |
| --------- | ------ | ------------------------------------------------------------------------------------------ |
| mode=edit | String | To fetch the latest version of a questionSet hierarchy from the Database for edit purposes |

#### Headers

| Name                                            | Type   | Description                                                                                                                                                                                                                                                    |
| ----------------------------------------------- | ------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Content-Type                                    | String | The Content-Type entity is the media type of the resource. Possible media types can be: <mark style="color:green;">Application/json</mark>                                                                                                                     |
| Authorization<mark style="color:red;">\*</mark> | String | <p>To make use of the API, you require authorization. Raise a request to the administrator for the use of the API. You will receive the authorization key. Specify the key received, here.</p><p>Set <mark style="color:green;">Bearer {{api\_key}}</mark></p> |
| x-channel-id                                    | String | Unique identification number associated with a root organization.                                                                                                                                                                                              |

{% tabs %}
{% tab title="200: OK "Read QuestionSet Hierarchy" operation was successfully executed" %}

```javascript
{
  "id": "api.questionset.hierarchy.get",
  "ver": "3.0",
  "ts": "2021-02-03T13:55:21ZZ",
  "params": {
    "resmsgid": "b810c4fd-231e-4b26-9be6-6345c49bde14",
    "msgid": null,
    "err": null,
    "status": "successful",
    "errmsg": null
  },
  "responseCode": "OK",
  "result": {
    "questionSet": {
      "code": "finemanfine",
      "allowSkip": "Yes",
      "containsUserData": "No",
      "description": "updated_code_of_root",
      "language": [
        "English"
      ],
      "mimeType": "application/vnd.sunbird.questionset",
      "showHints": "No",
      "createdOn": "2021-02-03T13:02:49.507+0000",
      "objectType": "QuestionSet",
      "primaryCategory": "Practice Question Set",
      "children": [
        {
          "parent": "do_113208431570984960123",
          "code": "QS_Visibility_Parent",
          "allowSkip": "Yes",
          "containsUserData": "No",
          "description": "QS_Visibility_Parent",
          "language": [
            "English"
          ],
          "mimeType": "application/vnd.sunbird.questionset",
          "showHints": "No",
          "createdOn": "2021-02-03T13:47:27.074+0000",
          "objectType": "QuestionSet",
          "primaryCategory": "Practice Question Set",
          "children": [
            {
              "parent": "do_113208453505630208144",
              "code": "Q_Visibility_Parent",
              "language": [
                "English"
              ],
              "mimeType": "application/vnd.sunbird.question",
              "createdOn": "2021-02-03T13:47:27.072+0000",
              "objectType": "Question",
              "primaryCategory": "Multiple Choice Question",
              "contentDisposition": "inline",
              "lastUpdatedOn": "2021-02-03T13:47:27.072+0000",
              "contentEncoding": "gzip",
              "showSolutions": "No",
              "allowAnonymousAccess": "Yes",
              "identifier": "do_113208453505613824142",
              "lastStatusChangedOn": "2021-02-03T13:47:27.072+0000",
              "visibility": "Parent",
              "showTimer": "No",
              "index": 1,
              "qType": "MCQ",
              "languageCode": [
                "en"
              ],
              "version": 1,
              "versionKey": "1612360047074",
              "showFeedback": "No",
              "license": "CC BY 4.0",
              "depth": 2,
              "compatibilityLevel": 4,
              "name": "MCQ",
              "status": "Draft"
            }
          ],
          "contentDisposition": "inline",
          "lastUpdatedOn": "2021-02-03T13:47:27.074+0000",
          "contentEncoding": "gzip",
          "showSolutions": "No",
          "allowAnonymousAccess": "Yes",
          "identifier": "do_113208453505630208144",
          "lastStatusChangedOn": "2021-02-03T13:47:27.074+0000",
          "requiresSubmit": "No",
          "visibility": "Parent",
          "showTimer": "No",
          "index": 1,
          "setType": "materialised",
          "languageCode": [
            "en"
          ],
          "version": 1,
          "versionKey": "1612360047074",
          "showFeedback": "No",
          "license": "CC BY 4.0",
          "depth": 1,
          "compatibilityLevel": 4,
          "name": "QS_Visibility_Parent",
          "navigationMode": "non-linear",
          "shuffle": "Yes",
          "status": "Draft"
        }
      ],
      "contentDisposition": "inline",
      "lastUpdatedOn": "2021-02-03T13:47:27.108+0000",
      "contentEncoding": "gzip",
      "showSolutions": "Yes",
      "allowAnonymousAccess": "Yes",
      "identifier": "do_113208431570984960123",
      "lastStatusChangedOn": "2021-02-03T13:02:49.507+0000",
      "requiresSubmit": "Yes",
      "visibility": "Default",
      "showTimer": "No",
      "summaryType": "Complete",
      "consumerId": "fa13b438-8a3d-41b1-8278-33b0c50210e4",
      "childNodes": [
        "do_113208453505613824142",
        "do_113208453505630208144"
      ],
      "setType": "materialised",
      "languageCode": [
        "en"
      ],
      "version": 1,
      "versionKey": "1612360047108",
      "showFeedback": "Yes",
      "license": "CC BY 4.0",
      "depth": 0,
      "compatibilityLevel": 4,
      "name": "Test Question Set",
      "navigationMode": "linear",
      "shuffle": "Yes",
      "status": "Draft"
    }
  }
}
```

{% endtab %}

{% tab title="404: Not Found QuestionSet Read Hierarchy operation failed !The possible reason for failure is that you may have provided wrong question id or the questionset is not published." %}

```javascript
{
  "id": "api.questionset.hierarchy.get",
  "ver": "3.0",
  "ts": "2021-02-03T13:56:54ZZ",
  "params": {
    "resmsgid": "db5bcf74-d151-46f5-85b1-8512053923cb",
    "msgid": null,
    "err": "RESOURCE_NOT_FOUND",
    "status": "failed",
    "errmsg": "rootId do_113208431570984960123 does not exist"
  },
  "responseCode": "RESOURCE_NOT_FOUND",
  "result": {}
}
```

{% endtab %}

{% tab title="500: Internal Server Error Looks like something went wrong! These errors are tracked automatically" %}

```javascript
{
  "result": {},
  "id": "string",
  "ver": "string",
  "ts": "string",
  "params": {
    "resmsgid": "string",
    "msgid": "string",
    "err": "string",
    "status": "string",
    "errmsg": "string"
  },
  "responseCode": "string"
}
```

{% endtab %}
{% endtabs %}

#### Success result schema

<table><thead><tr><th width="219">Attribute</th><th width="425.3333333333333">Description</th><th>Type</th></tr></thead><tbody><tr><td>identifier</td><td>Questionset Identifier</td><td>string</td></tr><tr><td>name</td><td>Questionset name</td><td>string</td></tr><tr><td>versionKey</td><td>Questionset versionKey</td><td>string</td></tr><tr><td>code</td><td>Questionset code</td><td>string</td></tr><tr><td>lastStatusChangedOn</td><td>Last status changed time</td><td>string</td></tr><tr><td>visibility</td><td>Questionset visibility (eg. Parent/Default)</td><td>string</td></tr><tr><td>mimeType</td><td>Questionset mimeType (eg. application/vnd.sunbird.questionset)</td><td>string</td></tr><tr><td>createdOn</td><td>Questionset createtion timestamp</td><td>string</td></tr><tr><td>objectType</td><td>Questionset objectType (eg. QuestionSet)</td><td>string</td></tr><tr><td>primaryCategory</td><td>Questionset primaryCategory (eg. Practice Question Set)</td><td>string</td></tr><tr><td>lastUpdatedOn</td><td>Questionset last updated timestamp</td><td>string</td></tr><tr><td>status</td><td>Questionset status (eg. Draft/Live)</td><td>string</td></tr><tr><td>children</td><td>Children of Questionset, mostly sections or questions</td><td>Object</td></tr><tr><td></td><td></td><td></td></tr></tbody></table>

#### cURL

```shell
curl --location -g --request GET '{{host}}/questionset/v1/hierarchy/read/{{questionSet_id}}' \
--header 'Authorization: Bearer {{api_key}}'
```


# Import QuestionSet

This API is used to import QuestionSet from one instance of sunbird to another instance of sunbird.

## This API is used to import QuestionSet from one instance of sunbird to another instance of sunbird.

<mark style="color:green;">`POST`</mark> `/questionset/v1/import`

• The endpoint for **Import QuestionSet** is <mark style="color:orange;">/questionset/v1/import</mark>\
• It points to inquiry-api-service (assessment service) - <mark style="color:orange;">/questionset/v4/import</mark> \
• All parameters marked with <mark style="color:red;">\*</mark> are mandatory. You must provide values for these parameters. \
• Mandatory fields cannot be null or empty.

#### Path Parameters

| Name                                            | Type   | Description                                                                                                                                                                                                                                                |
| ----------------------------------------------- | ------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Content-Type<mark style="color:red;">\*</mark>  | String | The Content-Type entity is the media type of the resource. The possible media types can be: <mark style="color:green;">Application/json</mark>                                                                                                             |
| Authorization<mark style="color:red;">\*</mark> | String | <p>You require authorization to make use of the API. Raise a request to the administrator for the use of the API. You will receive the authorization key. Specify the key received, here.<br>Set <mark style="color:green;">Bearer {{api\_key}}</mark></p> |
| x-channel-id                                    | String | Unique identification number associated with a root organization.                                                                                                                                                                                          |

#### Request Body

| Name                                      | Type   | Description                                                                        |
| ----------------------------------------- | ------ | ---------------------------------------------------------------------------------- |
| request<mark style="color:red;">\*</mark> | Object | The body is the representation of the resource object for importing a question set |

{% tabs %}
{% tab title="200: OK The Import QuestionSet operation was successful!" %}

```javascript
{
  "id": "api.questionset.import",
  "ver": "3.0",
  "ts": "2020-12-17T16:29:11ZZ",
  "params": {
    "resmsgid": "7cce8934-0a2f-46bf-a0ee-be5f49874cae",
    "msgid": null,
    "err": null,
    "status": "successful",
    "errmsg": null
  },
  "responseCode": "OK",
  "result": {
    "processId": "80a765c7-2202-4b3f-b473-448b5c2cd20e"
  }
}
```

{% endtab %}

{% tab title="400: Bad Request The Import QuestionSet operation failed. You may have missed providing input for a mandatory parameter.'" %}

```javascript
{
  "id": "api.questionset.import",
  "ver": "3.0",
  "ts": "2020-12-17T16:30:16ZZ",
  "params": {
    "resmsgid": "31f88a39-2514-4d86-b424-240166e315be"
  },
  "msgid": null,
  "err": "ERR_REQUIRED_PROPS_VALIDATION",
  "status": "failed",
  "errmsg": "Validation Failed! Mandatory Properties Are [name, code, mimeType, primaryCategory, framework]",
  "responseCode": "CLIENT_ERROR",
  "result": {
    "messages": null
  }
}
```

{% endtab %}

{% tab title="500: Internal Server Error We track these errors automatically and try to set it right at the earliest." %}

```javascript
{
  "id": "api.question.import",
  "ver": "1.0",
  "ts": "2020-12-10T08:51:51.647Z",
  "params": {
    "resmsgid": "f234a6f0-3ac4-11eb-b0a2-8d5c9f561887",
    "msgid": null,
    "status": "failed",
    "err": null,
    "errmsg": null
  },
  "responseCode": "SERVER_ERROR",
  "result": {}
}
```

{% endtab %}
{% endtabs %}

#### Sample Request

```json
{
  "request": {
    "questionset": [
      {
        "source": "https://dock.sunbirded.org/api/questionset/v1/read/do_1132613027022684161119",
        "metadata": {
          "framework": "ekstep_ncert_k-12",
          "channel": "01309282781705830427",
          "name": "QustionSet-1",
          "code": "9ae33d1e-a682-f30c-04b5-9bda236650ac",
          "lastPublishedBy": "5a587cc1-e018-4859-a0a8-e842650b9d64"
        },
        "collection": [
          {
            "identifier": "do_11324642736155033614",
            "unitId": "do_11324642761348710417"
          }
        ]
      }
    ]
  }
}
```

#### Request schema

<table><thead><tr><th width="139.33333333333331">Attribute</th><th width="486">Description</th><th>Type</th></tr></thead><tbody><tr><td>source</td><td>Represents the source of questionset object</td><td>string</td></tr><tr><td>metadata</td><td>Represents the additional metadata for the questionset object</td><td>Object</td></tr><tr><td>collection</td><td>Represents the collection with which Questionset can be linked.</td><td>Array of strings</td></tr></tbody></table>

#### Success result schema

| Attribute | Type   | Description       |
| --------- | ------ | ----------------- |
| processId | String | Unique process ID |

**cURL**

```
curl --location -g --request POST '{{host}}/questionset/v1/import' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer {{api_key}}' \
--header 'X-Channel-Id: {{channel_id}}' \
--data-raw '{
  "request": {
    "questionset": [
      {
        "source": "https://dock.sunbirded.org/api/questionset/v1/read/do_1132613027022684161119",
        "metadata": {
          "framework": "ekstep_ncert_k-12",
          "channel": "01309282781705830427",
          "name": "QustionSet-1",
          "code": "9ae33d1e-a682-f30c-04b5-9bda236650ac",
          "lastPublishedBy": "5a587cc1-e018-4859-a0a8-e842650b9d64"
        },
        "collection": [
          {
            "identifier": "do_11324642736155033614",
            "unitId": "do_11324642761348710417"
          }
        ]
      }
    ]
  }
}'
```


# Copy QuestionSet

This API is associated with copying questionset on the Sunbird Platform.

## This API is associated with copying questionset on the Sunbird Platform.

<mark style="color:green;">`POST`</mark> `/questionset/v1/copy/{QuestionSet_Id}`

• The endpoint for **Copy QuestionSet** is <mark style="color:orange;">/questionset/v1/copy</mark>\
• It points to inquiry-api-service (assessment service) - <mark style="color:orange;">/questionset/v4/copy</mark> \
• You need to provide a valid Question Set Id value in <mark style="color:orange;">{</mark>QuestionSet\_Id<mark style="color:orange;">}</mark> field of the API URL.\
• All parameters marked with <mark style="color:red;">\*</mark> are mandatory. You must provide values for these parameters. \
• Mandatory fields cannot be null or empty.

#### Path Parameters

| Name                                              | Type   | Description                                      |
| ------------------------------------------------- | ------ | ------------------------------------------------ |
| QuestionSet\_Id<mark style="color:red;">\*</mark> | String | Append a valid QuestionSet Id to the Request URL |

#### Headers

| Name                                            | Type   | Description                                                                                                                                                                                                                                                |
| ----------------------------------------------- | ------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Content-Type<mark style="color:red;">\*</mark>  | String | The Content-Type entity is the media type of the resource. The possible media types can be: <mark style="color:green;">Application/json</mark>                                                                                                             |
| Authorization<mark style="color:red;">\*</mark> | String | <p>You require authorization to make use of the API. Raise a request to the administrator for the use of the API. You will receive the authorization key. Specify the key received, here.<br>Set <mark style="color:green;">Bearer {{api\_key}}</mark></p> |
| x-channel-id                                    | String | Unique identification number associated with a root organisation.                                                                                                                                                                                          |

#### Request Body

| Name                                      | Type   | Description                                                                        |
| ----------------------------------------- | ------ | ---------------------------------------------------------------------------------- |
| request<mark style="color:red;">\*</mark> | Object | The body is the representation of the resource object for importing a question set |

{% tabs %}
{% tab title="200: OK The Copy QuestionSet operation was successful!" %}

```javascript
{
    "id": "api.questionset.copy",
    "ver": "3.0",
    "ts": "2023-06-23T06:41:31ZZ",
    "params": {
        "resmsgid": "8bba3dda-f81e-4659-8c05-55caed20d174",
        "msgid": null,
        "err": null,
        "status": "successful",
        "errmsg": null
    },
    "responseCode": "OK",
    "result": {
        "node_id": {
            "do_2138240203066900481600": "do_2138240204082216961601"
        },
        "versionKey": "1687502491400"
    }
}
```

{% endtab %}

{% tab title="400: Bad Request The Copy QuestionSet operation failed. You may have missed providing input for a mandatory parameter.'" %}

```javascript
{
    "id": "api.questionset.copy",
    "ver": "3.0",
    "ts": "2023-06-23T06:44:12ZZ",
    "params": {
        "resmsgid": "2ea62aa3-f2a9-4aeb-86f0-9d648591d1f2",
        "msgid": null,
        "err": "ERR_BAD_REQUEST",
        "status": "failed",
        "errmsg": "Hierarchy data is empty"
    },
    "responseCode": "CLIENT_ERROR",
    "result": {
        "messages": null
    }
}
```

{% endtab %}

{% tab title="500: Internal Server Error We track these errors automatically and try to set it right at the earliest." %}

```javascript
{
  "id": "api.questionset.copy",
  "ver": "3.0",
  "ts": "2020-12-10T08:51:51.647Z",
  "params": {
    "resmsgid": "f234a6f0-3ac4-11eb-b0a2-8d5c9f561887",
    "msgid": null,
    "status": "failed",
    "err": null,
    "errmsg": null
  },
  "responseCode": "SERVER_ERROR",
  "result": {}
}
```

{% endtab %}

{% tab title="404: Not Found The Copy QuestionSet operation failed. You may have requested a resource that is not existing in the server.'" %}

{% endtab %}
{% endtabs %}

#### Sample Request

```json
{
  "request": {
    "questionset": {
      "createdBy": "User001",
      "createdFor": [
        "Sunbird"
      ],
      "name": "Sunbird-QS"
    }
  }
}
```

#### Request schema

<table><thead><tr><th width="139.33333333333331">Attribute</th><th width="486">Description</th><th>Type</th></tr></thead><tbody><tr><td>createdBy</td><td>Represents the the user who triggered the copy operation</td><td>string</td></tr><tr><td>createdFor</td><td>Represents the organization on behalf the request was triggered</td><td>Object</td></tr><tr><td>name</td><td>Represents the collection with which Questionset can be copied.</td><td>string</td></tr></tbody></table>

#### Success result schema

| Attribute | Type            | Description               |
| --------- | --------------- | ------------------------- |
| node\_id  | Array of Object | Node Ids that were copied |

**cURL**

```
curl --location -g --request POST '{{host}}/questionset/v1/copy/{QuestionSet_Id}' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer {{api_key}}' \
--header 'X-Channel-Id: {{channel_id}}' \
--data-raw '{
  "request": {
    "questionset": {
      "createdBy": "User001",
      "createdFor": [
        "Sunbird"
      ],
      "name": "Sunbird-QS"
    }
  }
}'
```


# V2

Captures information about the v2 APIs

Question & QuestionSet Service has below API's to manage Question & QuestionSet type Asset.

### **Question Management API's**

{% content-ref url="/pages/VY1XJGepdA7wulu42ly6" %}
[Create Question](/learn/product-and-developer-guide/question-and-question-set-service/apis/v2/question-apis/create-question)
{% endcontent-ref %}

{% content-ref url="/pages/HW7HXXLV48DSH2iKJpWG" %}
[Read Question](/learn/product-and-developer-guide/question-and-question-set-service/apis/v2/question-apis/read-question)
{% endcontent-ref %}

{% content-ref url="/pages/qR6PFnmEvAnxwCQERczh" %}
[Read Private Question](/learn/product-and-developer-guide/question-and-question-set-service/apis/v2/question-apis/read-private-question)
{% endcontent-ref %}

{% content-ref url="/pages/xNVb7KLDywmChkNOQIjW" %}
[Update Question](/learn/product-and-developer-guide/question-and-question-set-service/apis/v2/question-apis/update-question)
{% endcontent-ref %}

{% content-ref url="/pages/QZuvpdSqBVYkQkzxICmZ" %}
[Submit for Review Question](/learn/product-and-developer-guide/question-and-question-set-service/apis/v2/question-apis/submit-for-review-question)
{% endcontent-ref %}

{% content-ref url="/pages/AoILKlorMeVUaBznMIHX" %}
[Reject Question](/learn/product-and-developer-guide/question-and-question-set-service/apis/v2/question-apis/reject-question)
{% endcontent-ref %}

{% content-ref url="/pages/o0NHLug6BmweVE0OoGjj" %}
[Publish Question](/learn/product-and-developer-guide/question-and-question-set-service/apis/v2/question-apis/publish-question)
{% endcontent-ref %}

{% content-ref url="/pages/Jdpw7x8NQ9aJ2tD4Uida" %}
[Copy Question](/learn/product-and-developer-guide/question-and-question-set-service/apis/v2/question-apis/copy-question)
{% endcontent-ref %}

{% content-ref url="/pages/QZQjrY9ie4JC45Ba3FG6" %}
[Import Question](/learn/product-and-developer-guide/question-and-question-set-service/apis/v2/question-apis/import-question)
{% endcontent-ref %}

{% content-ref url="/pages/ssEt2YZouwe0iJJyP6eE" %}
[Question List](/learn/product-and-developer-guide/question-and-question-set-service/apis/v2/question-apis/question-list)
{% endcontent-ref %}

{% content-ref url="/pages/3rVw0ixUrDumzntrBVK9" %}
[Retire Question](/learn/product-and-developer-guide/question-and-question-set-service/apis/v2/question-apis/retire-question)
{% endcontent-ref %}

### **QuestionSet Management API's**

{% content-ref url="/pages/q52TNyfeAIYJTp6UPhRv" %}
[Create QuestionSet](/learn/product-and-developer-guide/question-and-question-set-service/apis/v2/questionset-apis/create-questionset)
{% endcontent-ref %}

{% content-ref url="/pages/GqBDa1VpcxiEcDSffv4H" %}
[Read QuestionSet](/learn/product-and-developer-guide/question-and-question-set-service/apis/v2/questionset-apis/read-questionset)
{% endcontent-ref %}

{% content-ref url="/pages/2TDPbL1Ls1cnsrlxQdSj" %}
[Read Private QuestionSet](/learn/product-and-developer-guide/question-and-question-set-service/apis/v2/questionset-apis/read-private-questionset)
{% endcontent-ref %}

{% content-ref url="/pages/hDJ5lPJkIx5x0VB7yiZT" %}
[Update QuestionSet](/learn/product-and-developer-guide/question-and-question-set-service/apis/v2/questionset-apis/update-questionset)
{% endcontent-ref %}

{% content-ref url="/pages/3xfWoaR0Not6aslGJuJi" %}
[Review QuestionSet](/learn/product-and-developer-guide/question-and-question-set-service/apis/v2/questionset-apis/review-questionset)
{% endcontent-ref %}

{% content-ref url="/pages/nDfWgI8YluzgUg1Pc7X8" %}
[Reject QuestionSet](/learn/product-and-developer-guide/question-and-question-set-service/apis/v2/questionset-apis/reject-questionset)
{% endcontent-ref %}

{% content-ref url="/pages/aAAMw5EH6TCXOk9VXpDy" %}
[Publish QuestionSet](/learn/product-and-developer-guide/question-and-question-set-service/apis/v2/questionset-apis/publish-questionset)
{% endcontent-ref %}

{% content-ref url="/pages/egK3fxhWg8stT5r3WacZ" %}
[Update Hierarchy QuestionSet](/learn/product-and-developer-guide/question-and-question-set-service/apis/v2/questionset-apis/update-hierarchy-questionset)
{% endcontent-ref %}

{% content-ref url="/pages/e4bnkg34KHSINI782xsw" %}
[Read QuestionSet Hierarchy](/learn/product-and-developer-guide/question-and-question-set-service/apis/v2/questionset-apis/read-questionset-hierarchy)
{% endcontent-ref %}

{% content-ref url="/pages/6lrYD7cRJSs7voYjPJtG" %}
[Import QuestionSet](/learn/product-and-developer-guide/question-and-question-set-service/apis/v2/questionset-apis/import-questionset)
{% endcontent-ref %}

{% content-ref url="/pages/iDw8TVBZSmvgPJTDrxWa" %}
[Copy QuestionSet](/learn/product-and-developer-guide/question-and-question-set-service/apis/v2/questionset-apis/copy-questionset)
{% endcontent-ref %}

{% content-ref url="/pages/qUvzXRBiIQDXwvO1y6ap" %}
[Retire QuestionSet](/learn/product-and-developer-guide/question-and-question-set-service/apis/v2/questionset-apis/retire-questionset)
{% endcontent-ref %}


# Question API's

List of question related API's


# Create Question

This API is used to create Questions on the Sunbird-inQuiry Platform.

## This API is used to create Question on the Sunbird-inQuiry Platform.

<mark style="color:green;">`POST`</mark> `/question/v2/create`

• It points to inquiry-api-service (assessment service) - <mark style="color:orange;">/question/v5/create</mark>\
• It is mandatory to provide values for parameters marked with <mark style="color:red;">\*</mark>.\
• Mandatory fields cannot be null or empty.\
• The API supports QuML 1.1 version onwards. For Detailed Question schema, Please check [here](https://github.com/Sunbird-inQuiry/inquiry-api-service/tree/release-6.0.0/schemas/question/1.1) \
• Appropriate fields need to be passed to work questions functionally well.

#### Headers

| Name                                            | Type   | Description                                                                                                                                                                                                                                                |
| ----------------------------------------------- | ------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Content-Type<mark style="color:red;">\*</mark>  | String | The Content-Type entity is the media type of the resource. It should be<mark style="color:green;">`Application/json`</mark>                                                                                                                                |
| Authorization<mark style="color:red;">\*</mark> | String | <p>You require authorization to make use of the API. Raise a request to the administrator for the use of the API. You will receive the authorization key. Specify the key received, here.<br>Set <mark style="color:green;">Bearer {{api\_key}}</mark></p> |
| x-channel-id                                    | String | Unique identification number associated with a root organization.                                                                                                                                                                                          |

#### Request Body

| Name                                      | Type   | Description                                                                                                                                                                                          |
| ----------------------------------------- | ------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| request<mark style="color:red;">\*</mark> | object | <p><mark style="color:orange;"><code>request</code></mark> is the representation of the resource object for creating questions, which is an object of parameters that describes the question<br></p> |

{% tabs %}
{% tab title="200: OK The Create Question operation was successful!" %}
{% code overflow="wrap" %}

```javascript
{
    "id": "api.question.create",
    "ver": "5.0",
    "ts": "2023-06-29T03:20:53ZZ",
    "params": {
        "resmsgid": "5b4a288b-0875-4fc0-ab8d-b50a973f5ebd",
        "msgid": null,
        "err": null,
        "status": "successful",
        "errmsg": null
    },
    "responseCode": "OK",
    "result": {
        "identifier": "do_2138281685237841921513",
        "versionKey": "1688008853076"
    }
}
```

{% endcode %}
{% endtab %}

{% tab title="400: Bad Request The Create Question operation failed. You may have missed providing input for a mandatory parameter.'" %}

```javascript
{
    "id": "api.question.create",
    "ver": "5.0",
    "ts": "2023-06-29T03:37:12ZZ",
    "params": {
        "resmsgid": "b0e80224-9327-4e91-a565-c8ede7b27e1f",
        "msgid": null,
        "err": "CLIENT_ERROR",
        "status": "failed",
        "errmsg": "Validation Errors"
    },
    "responseCode": "CLIENT_ERROR",
    "result": {
        "messages": [
            "Metadata mimeType should be one of: [application/vnd.sunbird.question]"
        ]
    }
}
```

{% endtab %}

{% tab title="500: Internal Server Error We track these errors automatically and try to set it right at the earliest. Try refreshing the page." %}

```javascript
{
  "id": "api.question.create",
  "ver": "5.0",
  "ts": "2023-06-29T03:37:12ZZ",
  "params": {
    "resmsgid": "f234a6f0-3ac4-11eb-b0a2-8d5c9f561887",
    "msgid": null,
    "status": "failed",
    "err": null,
    "errmsg": null
  },
  "responseCode": "SERVER_ERROR",
  "result": {}
}
```

{% endtab %}
{% endtabs %}

#### Sample Request

```
{
    "request": {
        "question": {
            "name": "string",
            "code": "string",
            "mimeType": "string",
            "primaryCategory": "string"
        }
    }
```

#### Request Schema

<table><thead><tr><th width="182">Attribute</th><th width="104">Type</th><th width="249.33333333333331">Description</th><th>Required</th></tr></thead><tbody><tr><td>name</td><td>String</td><td>Represents the name of the question</td><td>Yes</td></tr><tr><td>code</td><td>String</td><td>Represents the unique code for the question</td><td>Yes</td></tr><tr><td>mimeType</td><td>String</td><td>Question mime type</td><td>Yes</td></tr><tr><td>primaryCategory</td><td>String</td><td>PrimaryCategory agains which question schema will be validated</td><td>Yes</td></tr></tbody></table>

#### Success Result Schema

<table><thead><tr><th width="156">Attribute</th><th width="112.33333333333331">Type</th><th width="345.6666666666667">Description</th></tr></thead><tbody><tr><td>identifier</td><td>String</td><td>Unique Question Identifier</td></tr><tr><td>versionKey</td><td>String</td><td>Unique version key of Question</td></tr></tbody></table>

#### cURL:

```json
curl --location -g --request POST '{{host}}/question/v2/create' \
--header 'Content-Type: application/json' \
--header 'X-Channel-Id: {{channel_id}}' \
--header 'Authorization: Bearer {{api_key}}' \
--data-raw '{
    "request": {
        "question": {
            "name": "Question 1",
            "code": "question.code",
            "mimeType": "application/vnd.sunbird.question",
            "primaryCategory": "Multiple Choice Question"
        }
    }
}'
```

#### Full Request Example

Following is the complete request example of creating **Multiple Choice Questions (MCQ).**&#x20;

This includes all the required fields to create a question object, as well as to work this question functionally some other fields were also added such as `editorState`, `responseDeclaration`, `qType` etc.

```json
{
  "question": {
    "copyright": "NIT123",
    "code": "ad6f06e4-1a36-47c2-964a-91c249191e4b",
    "subject": [
      "Math"
    ],
    "qumlVersion": 1.1,
    "channel": "01309282781705830427",
    "responseDeclaration": {
      "response1": {
        "cardinality": "single",
        "type": "integer",
        "correctResponse": {
          "value": 0
        },
        "mapping": [
          {
            "value": 0,
            "score": 1
          }
        ]
      }
    },
    "language": [
      "English"
    ],
    "medium": [
      "English"
    ],
    "mimeType": "application/vnd.sunbird.question",
    "showHints": false,
    "media": [],
    "body": "<div class='question-body' tabindex='-1'><div class='mcq-title' tabindex='0'><p>2+2=?</p></div><div data-choice-interaction='response1' class='mcq-vertical'></div></div>",
    "editorState": {
      "options": [
        {
          "answer": true,
          "value": {
            "body": "<p>4</p>",
            "value": 0
          }
        },
        {
          "answer": false,
          "value": {
            "body": "<p>8</p>",
            "value": 1
          }
        }
      ],
      "question": "<p>2+2=?</p>"
    },
    "templateId": "mcq-vertical",
    "createdOn": "2023-06-29T03:45:06.917+0000",
    "objectType": "Question",
    "interactions": {
      "response1": {
        "type": "choice",
        "options": [
          {
            "label": "<p>4</p>",
            "value": 0
          },
          {
            "label": "<p>8</p>",
            "value": 1
          }
        ],
        "validation": {
          "required": "Yes"
        }
      }
    },
    "gradeLevel": [
      "Class 1"
    ],
    "primaryCategory": "Multiple Choice Question",
    "contentDisposition": "inline",
    "lastUpdatedOn": "2023-06-29T03:45:07.002+0000",
    "contentEncoding": "gzip",
    "showSolutions": false,
    "allowAnonymousAccess": "Yes",
    "identifier": "do_2138281804342640641518",
    "lastStatusChangedOn": "2023-06-29T03:45:06.917+0000",
    "audience": [
      "Student"
    ],
    "schemaVersion": "1.1",
    "visibility": "Parent",
    "showTimer": false,
    "author": "Creator1",
    "solutions": {},
    "outcomeDeclaration": {
      "maxScore": {
        "cardinality": "single",
        "type": "integer",
        "defaultValue": 1
      }
    },
    "qType": "MCQ",
    "maxScore": 1,
    "languageCode": [
      "en"
    ],
    "versionKey": "1688010307002",
    "showFeedback": false,
    "license": "CC BY 4.0",
    "complexityLevel": [
      "evaluate"
    ],
    "interactionTypes": [
      "choice"
    ],
    "framework": "inquiry_k-12",
    "answer": "<div class='anwser-container'><div class='anwser-body'><p>4</p></div></div>",
    "createdBy": "5a587cc1-e018-4859-a0a8-e842650b9d64",
    "compatibilityLevel": 5,
    "name": "MCQ-1",
    "board": "CBSE",
    "status": "Draft"
  }
}
```


# Read Question

This API is used to read the question on the Sunbird-inQuiry Platform.

## This API is used to read the question on the Sunbird-inQuiry Platform.

<mark style="color:blue;">`GET`</mark> `/question/v2/read/{question_id}`

• It points to inquiry-api-service (assessment service)  - <mark style="color:orange;">`/question/v5/read`</mark>\
• You need to provide a valid Question Id value in <mark style="color:orange;">{question\_id}</mark> field of the API URL.\
• It is mandatory to provide values for parameters marked with <mark style="color:red;">\*</mark>.\
• Mandatory fields cannot be null or empty.

#### Path Parameters

| Name                                           | Type   | Description                                   |
| ---------------------------------------------- | ------ | --------------------------------------------- |
| question\_id<mark style="color:red;">\*</mark> | String | Append a valid Question ID To the Request URL |

#### Query Parameters

| Name                                  | Type   | Description                                                                                   |
| ------------------------------------- | ------ | --------------------------------------------------------------------------------------------- |
| mode=edit                             | String | To fetch the latest version of node from the database for edit purpose                        |
| fields=comma separated metadata names | String | To fetch the specific fields, this query parameter can be used eg. fields=name,body,answer... |

#### Headers

| Name                                            | Type   | Description                                                                                                                                                                                                                                                     |
| ----------------------------------------------- | ------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Content-Type                                    | String | The Content-Type entity is the media type of the resource. It should be <mark style="color:green;">Application/json</mark>                                                                                                                                      |
| Authorization<mark style="color:red;">\*</mark> | String | <p>To make use of the API, you require authorization. Raise a request to the administrator, for the use of the API. You will receive the authorization key. Specify the key received, here.</p><p>Set <mark style="color:green;">Bearer {{api\_key}}</mark></p> |
| x-channel-id                                    | String | Unique identification number associated with a root organization.                                                                                                                                                                                               |

{% tabs %}
{% tab title="200: OK Successful operation" %}
{% code overflow="wrap" %}

```javascript
{
    "id": "api.question.read",
    "ver": "5.0",
    "ts": "2023-06-29T03:49:09ZZ",
    "params": {
        "resmsgid": "8b56f8d3-4bba-4040-903d-1d8cbd01658a",
        "msgid": null,
        "err": null,
        "status": "successful",
        "errmsg": null
    },
    "responseCode": "OK",
    "result": {
        "question": {
            "copyright": "NIT123",
            "code": "ad6f06e4-1a36-47c2-964a-91c249191e4b",
            "subject": [
                "Math"
            ],
            "qumlVersion": 1.1,
            "channel": "01309282781705830427",
            "language": [
                "English"
            ],
            "medium": [
                "English"
            ],
            "mimeType": "application/vnd.sunbird.question",
            "showHints": false,
            "templateId": "mcq-vertical",
            "createdOn": "2023-06-29T03:45:06.917+0000",
            "objectType": "Question",
            "gradeLevel": [
                "Class 1"
            ],
            "primaryCategory": "Multiple Choice Question",
            "contentDisposition": "inline",
            "lastUpdatedOn": "2023-06-29T03:45:07.002+0000",
            "contentEncoding": "gzip",
            "showSolutions": false,
            "allowAnonymousAccess": "Yes",
            "identifier": "do_2138281804342640641518",
            "lastStatusChangedOn": "2023-06-29T03:45:06.917+0000",
            "audience": [
                "Student"
            ],
            "schemaVersion": "1.1",
            "visibility": "Parent",
            "showTimer": false,
            "author": "Creator1",
            "qType": "MCQ",
            "maxScore": 1,
            "languageCode": [
                "en"
            ],
            "versionKey": "1688010307002",
            "showFeedback": false,
            "license": "CC BY 4.0",
            "complexityLevel": [
                "evaluate"
            ],
            "interactionTypes": [
                "choice"
            ],
            "framework": "inquiry_k-12",
            "createdBy": "5a587cc1-e018-4859-a0a8-e842650b9d64",
            "compatibilityLevel": 5,
            "name": "MCQ-1",
            "board": "CBSE",
            "status": "Draft"
        }
    }
}
```

{% endcode %}
{% endtab %}

{% tab title="404: Not Found Resource not found" %}

```javascript
{
    "id": "api.question.read",
    "ver": "5.0",
    "ts": "2023-06-29T03:50:10ZZ",
    "params": {
        "resmsgid": "fd2271fc-6a7d-493d-a2ee-9cdcd20492e4",
        "msgid": null,
        "err": "NOT_FOUND",
        "status": "failed",
        "errmsg": "Error! Node(s) doesn't Exists. | [Invalid Node Id.]: do_213828180434264064151"
    },
    "responseCode": "RESOURCE_NOT_FOUND",
    "result": {
        "messages": null
    }
}
```

{% endtab %}

{% tab title="500: Internal Server Error Looks like something went wrong" %}

```javascript
{
  "id": "api.question.read",
  "ver": "5.0",
  "ts": "2023-06-29T03:50:10ZZ",
  "params": {
    "resmsgid": "f234a6f0-3ac4-11eb-b0a2-8d5c9f561887",
    "msgid": null,
    "status": "failed",
    "err": null,
    "errmsg": null
  },
  "responseCode": "SERVER_ERROR",
  "result": {}
}
```

{% endtab %}
{% endtabs %}

#### Success Result Schema

<table><thead><tr><th width="232">Attribute</th><th width="109.33333333333331">Type</th><th>Description</th></tr></thead><tbody><tr><td>identifier</td><td>string</td><td>Unique Question Identifier</td></tr><tr><td>name</td><td>string</td><td>Question name</td></tr><tr><td>versionKey</td><td>string</td><td>Question versionKey</td></tr><tr><td>code</td><td>string</td><td>Unique Question code</td></tr><tr><td>lastStatusChangedOn</td><td>string</td><td>Last status changed time</td></tr><tr><td>visibility</td><td>string</td><td>Question visibility eg. parent</td></tr><tr><td>mimeType</td><td>string</td><td>Question mimeType eg. application/vnd.sunbird.question</td></tr><tr><td>createdOn</td><td>string</td><td>Question createdOn Time</td></tr><tr><td>objectType</td><td>string</td><td>Question objectType</td></tr><tr><td>primaryCategory</td><td>string</td><td>Type of question (Multiple Choice Question or Subjective Question)</td></tr><tr><td>lastUpdatedOn</td><td>string</td><td>Question lastUpdatedOn</td></tr><tr><td>status</td><td>string</td><td>Question status Draft/Review/Live</td></tr></tbody></table>

#### cURL

**sample curl to read the metadata**

```shell
curl --location -g --request GET '{{host}}/question/v2/read/{{question_id}}' \
--header 'Authorization: Bearer {{api_key}}
```

**Sample curl to read specific metadata**

```
curl --location -g --request GET '{{host}}/question/v2/read/{{question_id}}?fields=name,body,responseDeclaration,outcomeDeclaration' \
--header 'Authorization: Bearer {{api_key}}
```


# Read Private Question

This API is used to read the private question on the Sunbird-inQuiry Platform.

## This API is used to read the private question on the Sunbird-inQuiry Platform.

<mark style="color:blue;">`GET`</mark> `/question/v2/private/read/{question_id}`

*Private Questions* are created within a specific channel. The user can fetch the question by providing that channel id in a request header.\
\
• It points to inquiry-api-service (assessment service)  - <mark style="color:orange;">/question/v5/private/read</mark>\
• You need to provide a valid Question Id value in <mark style="color:orange;">{question\_id}</mark> field of the API URL.\
• It is mandatory to provide values for parameters marked with <mark style="color:red;">\*</mark>.\
• Mandatory fields cannot be null or empty.

#### Path Parameters

| Name                                           | Type   | Description                                   |
| ---------------------------------------------- | ------ | --------------------------------------------- |
| question\_id<mark style="color:red;">\*</mark> | String | Append a valid Question ID To the Request URL |

#### Headers

| Name                                            | Type   | Description                                                                                                                                                                                                                                                     |
| ----------------------------------------------- | ------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Content-Type                                    | String | The Content-Type entity is the media type of the resource. It should be <mark style="color:green;">Application/json</mark>                                                                                                                                      |
| Authorization<mark style="color:red;">\*</mark> | String | <p>To make use of the API, you require authorization. Raise a request to the administrator, for the use of the API. You will receive the authorization key. Specify the key received, here.</p><p>Set <mark style="color:green;">Bearer {{api\_key}}</mark></p> |
| x-channel-id<mark style="color:red;">\*</mark>  | String | Unique identification number associated with a root organization.                                                                                                                                                                                               |

{% tabs %}
{% tab title="200: OK Successful Operation. The "Read Private Question" operation was successfully executed" %}
{% code overflow="wrap" %}

```json
{
    "id": "api.question.private.read",
    "ver": "5.0",
    "ts": "2023-06-29T04:01:25ZZ",
    "params": {
        "resmsgid": "ca95b536-5403-4dab-a019-47e8064cd4ce",
        "msgid": null,
        "err": null,
        "status": "successful",
        "errmsg": null
    },
    "responseCode": "OK",
    "result": {
        "question": {
            "code": "47f7fdfb-22c1-4d89-958d-f02e219246ec",
            "qumlVersion": 1.1,
            "channel": "test-001",
            "language": [
                "English"
            ],
            "mimeType": "application/vnd.sunbird.question",
            "showHints": false,
            "createdOn": "2023-06-29T04:01:05.631+0000",
            "objectType": "Question",
            "primaryCategory": "Multiple Choice Question",
            "contentDisposition": "inline",
            "lastUpdatedOn": "2023-06-29T04:01:05.631+0000",
            "contentEncoding": "gzip",
            "showSolutions": false,
            "allowAnonymousAccess": "Yes",
            "identifier": "do_2138281882873774081521",
            "lastStatusChangedOn": "2023-06-29T04:01:05.631+0000",
            "schemaVersion": "1.1",
            "visibility": "Private",
            "showTimer": false,
            "languageCode": [
                "en"
            ],
            "versionKey": "1688011265631",
            "showFeedback": false,
            "license": "CC BY 4.0",
            "compatibilityLevel": 5,
            "name": "FT_Q_1",
            "status": "Draft"
        }
    }
}
```

{% endcode %}
{% endtab %}

{% tab title="404: Not Found Question Private Read operation failed! The possible reason for failure is that you may have provided the wrong question ID." %}

```json
{
    "id": "api.question.private.read",
    "ver": "5.0",
    "ts": "2023-06-29T04:02:42ZZ",
    "params": {
        "resmsgid": "bb64e78b-55a0-40bc-b351-ce04237a0e1f",
        "msgid": null,
        "err": "NOT_FOUND",
        "status": "failed",
        "errmsg": "Error! Node(s) doesn't Exists. | [Invalid Node Id.]: do_213828188287377408152"
    },
    "responseCode": "RESOURCE_NOT_FOUND",
    "result": {
        "messages": null
    }
}
```

{% endtab %}

{% tab title="500: Internal Server Error Looks like something went wrong! These errors are tracked automatically." %}

```json
{
  "id": "api.question.private.read",
  "ver": "5.0",
  "ts": "2023-06-29T03:50:10ZZ",
  "params": {
    "resmsgid": "f234a6f0-3ac4-11eb-b0a2-8d5c9f561887",
    "msgid": null,
    "status": "failed",
    "err": null,
    "errmsg": null
  },
  "responseCode": "SERVER_ERROR",
  "result": {}
}
```

{% endtab %}
{% endtabs %}

#### Sample Response

```json
{
    "id": "api.question.private.read",
    "ver": "5.0",
    "ts": "2023-06-29T04:04:45ZZ",
    "params": {
        "resmsgid": "56b67c99-5beb-4bf5-a282-aee3193f24d9",
        "msgid": null,
        "err": null,
        "status": "successful",
        "errmsg": null
    },
    "responseCode": "OK",
    "result": {
        "question": {
            "code": "47f7fdfb-22c1-4d89-958d-f02e219246ec",
            "qumlVersion": 1.1,
            "channel": "test-001",
            "language": [
                "English"
            ],
            "mimeType": "application/vnd.sunbird.question",
            "showHints": false,
            "createdOn": "2023-06-29T04:01:05.631+0000",
            "objectType": "Question",
            "primaryCategory": "Multiple Choice Question",
            "contentDisposition": "inline",
            "lastUpdatedOn": "2023-06-29T04:01:05.631+0000",
            "contentEncoding": "gzip",
            "showSolutions": false,
            "allowAnonymousAccess": "Yes",
            "identifier": "do_2138281882873774081521",
            "lastStatusChangedOn": "2023-06-29T04:01:05.631+0000",
            "schemaVersion": "1.1",
            "visibility": "Private",
            "showTimer": false,
            "languageCode": [
                "en"
            ],
            "versionKey": "1688011265631",
            "showFeedback": false,
            "license": "CC BY 4.0",
            "compatibilityLevel": 5,
            "name": "FT_Q_{{randomeUUID}}",
            "status": "Draft"
        }
    }
}
```

#### Success Result Schema

<table><thead><tr><th width="230">Name</th><th width="133.33333333333331">Type</th><th>Description</th></tr></thead><tbody><tr><td>identifier</td><td>String</td><td>Unique Question Identifier</td></tr><tr><td>name</td><td>String</td><td>Name of the Question</td></tr><tr><td>versionKey</td><td>String</td><td>Unique version key of Question</td></tr><tr><td>code</td><td>String</td><td>Unique Code for Question</td></tr><tr><td>lastStatusChangedOn</td><td>String</td><td>Last status changed time</td></tr><tr><td>visibility</td><td>String</td><td>Question Visibility eg. parent</td></tr><tr><td>mimeType</td><td>String</td><td>Question mimeType eg. <code>application/vnd.sunbird.question</code></td></tr><tr><td>createdOn</td><td>String</td><td>Time of question creation</td></tr><tr><td>objectType</td><td>String</td><td>Question objectType</td></tr><tr><td>primaryCategory</td><td>String</td><td>Type of question - <code>Multiple Choice Question</code> or <code>Subjective Question</code></td></tr><tr><td>status</td><td>String</td><td>Question status <code>Draft/Review/Live</code></td></tr><tr><td>lastUpdatedOn</td><td>String</td><td>Last Updated time</td></tr></tbody></table>

#### &#x20;

#### cURL

```shell
curl --location -g --request GET '{{host}}/question/v2/read/{{question_id}}' \
--header 'X-Channel-ID: {{channel_id}}' \
--header 'Authorization: Bearer {{api_key}}'
```


# Update Question

This API is used to update the existing question on the Sunbird-inQuiry Platform.

## This API is used to update the existing question on the Sunbird-inQuiry Platform.

<mark style="color:purple;">`PATCH`</mark> `/question/v2/update/{question_id}`

• <mark style="color:orange;">/update</mark> endpoint executes the "Update Question" request based on parameters provided as metadata in the request body. Users can provide updated attributes and their values in a request.\
• It points to inquiry-api-service (assessment service) - <mark style="color:orange;">/question/v5/update</mark>\
• You need to provide a valid Question Id value in <mark style="color:orange;">{question\_id}</mark> field of the API URL.\
• It is mandatory to provide values for parameters marked with <mark style="color:red;">\*</mark>.\
• Mandatory fields cannot be null or empty.\
• The API supports QuML 1.1 version onwards. For Detailed Question schema, Please check [here](https://github.com/Sunbird-inQuiry/inquiry-api-service/tree/release-6.0.0/schemas/question/1.1)&#x20;

#### Path Parameters

| Name                                           | Type   | Description                                   |
| ---------------------------------------------- | ------ | --------------------------------------------- |
| question\_id<mark style="color:red;">\*</mark> | String | Append a valid Question ID To the Request URL |

#### Headers

| Name                                            | Type   | Description                                                                                                                                                                                                                                                     |
| ----------------------------------------------- | ------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Content-Type<mark style="color:red;">\*</mark>  | String | The Content-Type entity is the media type of the resource. It should be <mark style="color:green;">Application/json</mark>                                                                                                                                      |
| Authorization<mark style="color:red;">\*</mark> | String | <p>To make use of the API, you require authorization. Raise a request to the administrator, for the use of the API. You will receive the authorization key. Specify the key received, here.</p><p>Set <mark style="color:green;">Bearer {{api\_key}}</mark></p> |
| x-channel-id                                    | String | Unique identification number associated with a root organization.                                                                                                                                                                                               |

#### Request Body

| Name                                      | Type   | Description                                            |
| ----------------------------------------- | ------ | ------------------------------------------------------ |
| request<mark style="color:red;">\*</mark> | Object | It contains metadata about the question to be updated. |

{% tabs %}
{% tab title="200: OK Successful operation. The 'Update Question' operation was successfuly executed." %}

```javascript
{
  "id": "api.question.update",
  "ver": "5.0",
  "ts": "2023-06-29T04:01:05ZZ",
  "params": {
    "resmsgid": "9d9d4824-cc40-4ac7-a3d6-6da61c0240e9",
    "msgid": null,
    "err": null,
    "status": "successful",
    "errmsg": null
  },
  "responseCode": "OK",
  "result": {
    "identifier": "do_113207924037746688110",
    "versionKey": "1612295707004"
  }
}
```

{% endtab %}

{% tab title="400: Bad Request The 'Update Question' operation failed! The possible reason for failure is that you may have missed providing input for a mandatory parameter." %}

```javascript
{
  "id": "api.question.update",
  "ver": "5.0",
  "ts": "2023-06-29T04:01:05ZZ",
  "params": {
    "resmsgid": "fcfcf6d6-84f1-43f5-b573-c3b6cf69ef53",
    "msgid": null,
    "err": "CLIENT_ERROR",
    "status": "failed",
    "errmsg": "Invalid version Key"
  },
  "responseCode": "CLIENT_ERROR",
  "result": {
    "messages": null
  }
}
```

{% endtab %}

{% tab title="404: Not Found The Update Question operation failed! The possible reason for failure is that you may have provided wrong question ID." %}

```javascript
{
  "id": "api.question.update",
  "ver": "5.0",
  "ts": "2023-06-29T04:01:05ZZ",
  "params": {
    "resmsgid": "2b139ee9-f091-4cca-b466-32af45f49a65",
    "msgid": null,
    "err": "NOT_FOUND",
    "status": "failed",
    "errmsg": "Error! Node(s) doesn't Exists. | [Invalid Node Id.]: do_1132079240377466881101"
  },
  "responseCode": "RESOURCE_NOT_FOUND",
  "result": {
    "messages": null
  }
}
```

{% endtab %}

{% tab title="500: Internal Server Error Looks like something went wrong! These errors are tracked automatically." %}

```javascript
{
  "id": "api.question.update",
  "ver": "5.0",
  "ts": "2023-06-29T03:37:12ZZ",
  "params": {
    "resmsgid": "f234a6f0-3ac4-11eb-b0a2-8d5c9f561887",
    "msgid": null,
    "status": "failed",
    "err": null,
    "errmsg": null
  },
  "responseCode": "SERVER_ERROR",
  "result": {}
}
```

{% endtab %}
{% endtabs %}

#### Sample Request

```json
{
   "request": {
      "question":{
        "name": "Updated value",
        "versionKey": "{{versionKey}}"
      }
    }
}
```

#### Request Schema

<table><thead><tr><th width="146">Attribute</th><th width="92">Type</th><th width="401">Description</th><th>Required</th></tr></thead><tbody><tr><td>versionKey</td><td>string</td><td>Represents the transaction update version key of the Question</td><td>Yes</td></tr></tbody></table>

#### Success Result Schema

<table><thead><tr><th width="154.33333333333331">Attribute</th><th width="104">Type</th><th>Description</th></tr></thead><tbody><tr><td>identifier</td><td>String</td><td>Unique Question identifier</td></tr><tr><td>versionKey</td><td>String</td><td>Unique version key for question</td></tr></tbody></table>

#### cURL

```shell
curl --location -g --request PATCH '{{host}}/question/v2/update/{{question_id}}' \
--header 'Accept: application/json' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer {{api_key}}' \
--data-raw '{
   "request": {
      "question":{
        "name": "Updated value",
        "versionKey": "{{versionKey}}"
      }
    }
}'
```

#### Full Request Example

Following is the complete request example of updating an existing Question. This is a **Multiple Choice Questions (MCQ)** type of question.

```json
{
  "question": {
    "copyright": "NIT123",
    "subject": [
      "Math"
    ],
    "responseDeclaration": {
      "response1": {
        "cardinality": "single",
        "type": "integer",
        "correctResponse": {
          "value": 0
        },
        "mapping": [
          {
            "value": 0,
            "score": 1
          }
        ]
      }
    },
    "language": [
      "English"
    ],
    "medium": [
      "English"
    ],
    "showHints": false,
    "media": [],
    "body": "<div class='question-body' tabindex='-1'><div class='mcq-title' tabindex='0'><p>2+2=?</p></div><div data-choice-interaction='response1' class='mcq-vertical'></div></div>",
    "editorState": {
      "options": [
        {
          "answer": true,
          "value": {
            "body": "<p>4</p>",
            "value": 0
          }
        },
        {
          "answer": false,
          "value": {
            "body": "<p>8</p>",
            "value": 1
          }
        }
      ],
      "question": "<p>2+2=?</p>"
    },
    "templateId": "mcq-vertical",
    "interactions": {
      "response1": {
        "type": "choice",
        "options": [
          {
            "label": "<p>4</p>",
            "value": 0
          },
          {
            "label": "<p>8</p>",
            "value": 1
          }
        ],
        "validation": {
          "required": "Yes"
        }
      }
    },
    "gradeLevel": [
      "Class 1"
    ],
    "contentDisposition": "inline",
    "contentEncoding": "gzip",
    "showSolutions": false,
    "allowAnonymousAccess": "Yes",
    "audience": [
      "Student"
    ],
    "showTimer": false,
    "author": "Creator1",
    "outcomeDeclaration": {
      "maxScore": {
        "cardinality": "single",
        "type": "integer",
        "defaultValue": 1
      }
    },
    "qType": "MCQ",
    "maxScore": 1,
    "languageCode": [
      "en"
    ],
    "versionKey": "1688010307002",
    "showFeedback": false,
    "license": "CC BY 4.0",
    "complexityLevel": [
      "evaluate"
    ],
    "interactionTypes": [
      "choice"
    ],
    "framework": "inquiry_k-12",
    "answer": "<div class='anwser-container'><div class='anwser-body'><p>4</p></div></div>",
    "createdBy": "5a587cc1-e018-4859-a0a8-e842650b9d64",
    "name": "MCQ-1",
    "board": "CBSE"
  }
}
```


# Submit for Review Question

This API is used to submit question for review on the Sunbird-inQuiry Platform.

## This API is used to submit question for review on the Sunbird-inQuiry Platform.

<mark style="color:green;">`POST`</mark> `/question/v2/review/{question_id}`

• <mark style="color:orange;">/question/v2/review/{question\_id}</mark> endpoint executes the "Submit for Review" request based on parameters provided as metadata in the request body\
• It points to inquiry-api-service (assessment service) - <mark style="color:orange;">/question/v5/review</mark>\
• You need to provide a valid Question Id value in <mark style="color:orange;">{question\_id}</mark> field of the API URL.\
• It is mandatory to provide values for parameters marked with <mark style="color:red;">\*</mark>\
• Mandatory fields cannot be null or empty.

#### Path Parameters

| Name                                           | Type   | Description                                   |
| ---------------------------------------------- | ------ | --------------------------------------------- |
| question\_id<mark style="color:red;">\*</mark> | String | Append a valid Question ID To the Request URL |

#### Headers

| Name                                            | Type   | Description                                                                                                                                                                                                                                                     |
| ----------------------------------------------- | ------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Content-Type<mark style="color:red;">\*</mark>  | String | The Content-Type entity is the media type of the resource. It should be <mark style="color:green;">Application/json</mark>                                                                                                                                      |
| Authorization<mark style="color:red;">\*</mark> | String | <p>To make use of the API, you require authorization. Raise a request to the administrator, for the use of the API. You will receive the authorization key. Specify the key received, here.</p><p>Set <mark style="color:green;">Bearer {{api\_key}}</mark></p> |
| x-channel-id                                    | String | Unique identification number associated with a root organization.                                                                                                                                                                                               |

#### Request Body

| Name                                      | Type   | Description                                        |
| ----------------------------------------- | ------ | -------------------------------------------------- |
| request<mark style="color:red;">\*</mark> | Object | metadata about the question to be sent for review. |

{% tabs %}
{% tab title="200: OK Question sent for review operation successful!" %}

```javascript
{
  "id": "api.question.review",
  "ver": "5.0",
  "ts": "2023-06-29T04:01:05ZZ",
  "params": {
    "resmsgid": "6a00ef94-b63d-4fb6-818a-8dfc66680577",
    "msgid": null,
    "err": null,
    "status": "successful",
    "errmsg": null
  },
  "responseCode": "OK",
  "result": {
    "identifier": "do_113207931921555456111",
    "versionKey": "1612296382041"
  }
}
```

{% endtab %}

{% tab title="400: Bad Request The Review Question operation failed. The possible reason for failure is that you may have missed providing input for a mandatory parameter" %}

```javascript
{
  "id": "api.question.review",
  "ver": "5.0",
  "ts": "2023-06-29T04:01:05ZZ",
  "params": {
    "resmsgid": "db7fd0f9-4aa5-4f06-b43b-1b89bec45c50",
    "msgid": null,
    "err": "ERR_QUESTION_REVIEW",
    "status": "failed",
    "errmsg": "Question with status other than Draft can't be sent for review."
  },
  "responseCode": "CLIENT_ERROR",
  "result": {
    "messages": null
  }
}
```

{% endtab %}

{% tab title="404: Not Found The Review Question operation failed. The possible reason for failure is that you may have provided wrong question ID" %}

```javascript
{
  "id": "api.question.review",
  "ver": "5.0",
  "ts": "2023-06-29T04:01:05ZZ",
  "params": {
    "resmsgid": "852b878c-a607-4d72-9458-6239e36adb9e",
    "msgid": null,
    "err": "NOT_FOUND",
    "status": "failed",
    "errmsg": "Error! Node(s) does not Exist. | [Invalid Node Id.]: do_1132079319215554561111"
  },
  "responseCode": "RESOURCE_NOT_FOUND",
  "result": {
    "messages": null
  }
}
```

{% endtab %}

{% tab title="500: Internal Server Error Looks like something went wrong! These errors are tracked automatically." %}

```javascript
{
  "id": "api.question.review",
  "ver": "5.0",
  "ts": "2023-06-29T03:37:12ZZ",
  "params": {
    "resmsgid": "f234a6f0-3ac4-11eb-b0a2-8d5c9f561887",
    "msgid": null,
    "status": "failed",
    "err": null,
    "errmsg": null
  },
  "responseCode": "SERVER_ERROR",
  "result": {}
}
```

{% endtab %}
{% endtabs %}

#### Success result schema

<table><thead><tr><th width="178.33333333333331">Attribute</th><th width="104">Type</th><th>Description</th></tr></thead><tbody><tr><td>identifier</td><td>String</td><td>Unique Question identifier</td></tr><tr><td>versionKey</td><td>String</td><td>Unique version key for question</td></tr></tbody></table>

#### cURL

```shell
curl --location -g --request POST '{{host}}/question/v2/review/{{question_id}}' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer {{api_key}}' \
--header 'X-Channel-Id: {{channel_id}}' \
--data-raw '{
  "request": {
    "question": {}
  }
}'
```


# Reject Question

This API is used to reject the questions on the Sunbird-inQuiry Platform.

## This API is used to reject the questions on the Sunbird-inQuiry Platform.

<mark style="color:red;">`DELETE`</mark> `/question/v2/reject/{question_id}`

• *<mark style="color:orange;">/question/v2/reject/{</mark>*<mark style="color:orange;">question\_id</mark>*<mark style="color:orange;">}</mark>* endpoint executes the "Reject Question" request based on parameters provided as metadata in the request body\
• This API is used to send back the question to the creator by the reviewer. The API changes the question object status from review to draft.\
• It points to inquiry-api-service (assessment service) - <mark style="color:orange;">/question/v5/reject</mark>\
• It is mandatory to provide values for parameters marked with <mark style="color:red;">\*</mark>.\
• Mandatory fields cannot be null or empty.

#### Path Parameters

| Name                                           | Type   | Description                                   |
| ---------------------------------------------- | ------ | --------------------------------------------- |
| question\_id<mark style="color:red;">\*</mark> | String | Append a valid Question ID To the Request URL |

#### Headers

| Name                                            | Type   | Description                                                                                                                                                                                                                                                     |
| ----------------------------------------------- | ------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Authorization<mark style="color:red;">\*</mark> | String | <p>To make use of the API, you require authorization. Raise a request to the administrator, for the use of the API. You will receive the authorization key. Specify the key received, here.</p><p>Set <mark style="color:green;">Bearer {{api\_key}}</mark></p> |
| x-channel-id                                    | String | Unique identification number associated with a root organization.                                                                                                                                                                                               |

#### Request Body

| Name                                      | Type   | Description                                 |
| ----------------------------------------- | ------ | ------------------------------------------- |
| request<mark style="color:red;">\*</mark> | Object | Metadata about the question to be rejected. |

{% tabs %}
{% tab title="200: OK The Reject Question operation was successfully executed" %}

```json
{
  "id": "api.question.reject",
  "ver": "5.0",
  "ts": "2023-06-29T03:37:12ZZ",
  "params": {
    "resmsgid": "70dc4cef-b7d0-4794-ae78-e80cc85b4770",
    "msgid": null,
    "err": null,
    "status": "successful",
    "errmsg": null
  },
  "responseCode": "OK",
  "result": {
    "identifier": "do_11336893480941158415",
    "versionKey": "1634627965206"
  }
}
```

{% endtab %}

{% tab title="400: Bad Request The Reject Question operation was unsuccessful. You may have missed providing input for a mandatory parameter.'" %}

```javascript
{
  "id": "api.question.reject",
  "ver": "5.0",
  "ts": "2023-06-29T03:37:12ZZ",
  "params": {
    "resmsgid": "415e19d2-01e3-4690-b5c7-040316c56f5b",
    "msgid": null,
    "err": "ERR_QUESTION_REJECT",
    "status": "failed",
    "errmsg": "Question is not in Review state for identifier: do_11336893480941158415"
  },
  "responseCode": "CLIENT_ERROR",
  "result": {
    "messages": null
  }
}
```

{% endtab %}

{% tab title="404: Not Found The Reject Question operation failed. The possible reason for failure is that you may have provided wrong question ID" %}

```javascript
{
  "id": "api.question.reject",
  "ver": "5.0",
  "ts": "2023-06-29T03:37:12ZZ",
  "params": {
    "resmsgid": "da7af22e-bdce-48f0-8743-f50fa6c2cd21",
    "msgid": null,
    "err": "NOT_FOUND",
    "status": "failed",
    "errmsg": "Error! Node(s) does not Exist. | [Invalid Node Id.]: do_11336893480941158908"
  },
  "responseCode": "RESOURCE_NOT_FOUND",
  "result": {
    "messages": null
  }
}
```

{% endtab %}

{% tab title="500: Internal Server Error Looks like something went wrong! These errors are tracked automatically." %}

```javascript
{
  "id": "api.question.reject",
  "ver": "5.0",
  "ts": "2023-06-29T03:37:12ZZ",
  "params": {
    "resmsgid": "f234a6f0-3ac4-11eb-b0a2-8d5c9f561887",
    "msgid": null,
    "status": "failed",
    "err": null,
    "errmsg": null
  },
  "responseCode": "SERVER_ERROR",
  "result": {}
}
```

{% endtab %}
{% endtabs %}

#### Success result schema

<table><thead><tr><th width="189.33333333333331">Attribute</th><th width="142">Type</th><th>Description</th></tr></thead><tbody><tr><td>identifier</td><td>String</td><td>Unique Question identifier</td></tr><tr><td>versionKey</td><td>String</td><td>Unique version key for question</td></tr></tbody></table>

#### cURL

```shell
curl --location -g --request POST '{{host}}/question/v2/reject/{{question_id}}' \
--header 'Authorization: Bearer {{api_key}}' \
--header 'X-Channel-ID: {{channel_id}}' \
--header 'Content-Type: application/json' \
--data-raw '{
    "request": {
        "question": {
            "rejectComment":"Rejected for testing"
        }
    }
}'
```


# Publish Question

This API is used to publish the question on Sunbird platform.

## This API is used to publish the question on Sunbird-inQuiry platform.

<mark style="color:green;">`POST`</mark> `/question/v2/publish/{question_id}`

• <mark style="color:orange;">/publish</mark> endpoint executes the "Publish Question" request based on parameters provided       as metadata in the request body\
• It points to inquiry-api-service (assessment service)- <mark style="color:orange;">/question/v5/publish</mark>\
• You need to provide a valid Question Id value in <mark style="color:orange;">{question\_id}</mark> field of the API URL.\
• It is mandatory to provide values for parameters marked with <mark style="color:red;">\*</mark>.\
• Mandatory fields cannot be null or empty.\
• <mark style="color:orange;">Asynchronous flink job : async-questionset-publish will takes care of the publishing activity.</mark>

#### Path Parameters

| Name                                           | Type   | Description                                   |
| ---------------------------------------------- | ------ | --------------------------------------------- |
| question\_id<mark style="color:red;">\*</mark> | String | Append a valid Question ID To the Request URL |

#### Headers

| Name                                            | Type   | Description                                                                                                                                                                                                                                                     |
| ----------------------------------------------- | ------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Content-Type<mark style="color:red;">\*</mark>  | String | The Content-Type entity is the media type of the resource. It should be <mark style="color:green;">Application/json</mark>                                                                                                                                      |
| Authorization<mark style="color:red;">\*</mark> | String | <p>To make use of the API, you require authorization. Raise a request to the administrator, for the use of the API. You will receive the authorization key. Specify the key received, here.</p><p>Set <mark style="color:green;">Bearer {{api\_key}}</mark></p> |
| x-channel-id                                    | String | Unique identification number associated with a root organization.                                                                                                                                                                                               |

#### Request Body

| Name    | Type   | Description                                 |
| ------- | ------ | ------------------------------------------- |
| request | Object | metadata about the question to be published |

{% tabs %}
{% tab title="200: OK The Publish Question operation was successful!" %}

```javascript
{
  "id": "api.question.publish",
  "ver": "5.0",
  "ts": "2023-06-29T04:01:05ZZ",
  "params": {
    "resmsgid": "9c64cc9c-bed5-44c7-85bf-4918c3a42f58",
    "msgid": null,
    "err": null,
    "status": "successful",
    "errmsg": null
  },
  "responseCode": "OK",
  "result": {
    "message": "Question is successfully sent for Publish",
    "identifier": "do_2138282512518184961525"
  }
}
```

{% endtab %}

{% tab title="404: Not Found The Publish Question operation failed. The possible reason for failure is that you may have provided wrong question ID" %}

```javascript
{
  "id": "api.question.publish",
  "ver": "5.0",
  "ts": "2023-06-29T04:01:05ZZ",
  "params": {
    "resmsgid": "b084af8b-706b-4079-8ec2-0beb0753931c",
    "msgid": null,
    "err": "NOT_FOUND",
    "status": "failed",
    "errmsg": "Error! Node(s) doesn't Exists. | [Invalid Node Id.]: do_213828251251818496152"
  },
  "responseCode": "RESOURCE_NOT_FOUND",
  "result": {
    "messages": null
  }
}
```

{% endtab %}

{% tab title="500: Internal Server Error Looks like something went wrong! These errors are tracked automatically." %}

```javascript
{
  "id": "api.question.publish",
  "ver": "5.0",
  "ts": "2023-06-29T03:37:12ZZ",
  "params": {
    "resmsgid": "f234a6f0-3ac4-11eb-b0a2-8d5c9f561887",
    "msgid": null,
    "status": "failed",
    "err": null,
    "errmsg": null
  },
  "responseCode": "SERVER_ERROR",
  "result": {}
}
```

{% endtab %}

{% tab title="400: Bad Request The Publish Question operation failed." %}

```javascript
{
    "id": "api.question.publish",
    "ver": "5.0",
    "ts": "2023-06-29T06:09:24ZZ",
    "params": {
        "resmsgid": "a070ec5e-75c3-46b2-8cf8-e4feda03e042",
        "msgid": null,
        "err": "ERR_OBJECT_VALIDATION",
        "status": "failed",
        "errmsg": "Mandatory Fields [body, responseDeclaration, interactions, outcomeDeclaration] Missing for do_2138282512518184961525"
    },
    "responseCode": "CLIENT_ERROR",
    "result": {
        "messages": null
    }
}
```

{% endtab %}
{% endtabs %}

#### Success result schema

| Attribute  | Type   | Description                |
| ---------- | ------ | -------------------------- |
| identifier | String | Unique Question identifier |
| message    | String | Publish success message    |

#### cURL

```shell
curl --location -g --request POST '{{host}}/question/v2/publish/{{question_id}}' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer {{api_key}}' \
--header 'X-Channel-Id: {{channel_id}}' \
--data-raw '{
    "request": {}
}'
```


# Copy Question

This API is associated with copying question on the Sunbird Platform.

## This API is associated with copying question on the Sunbird Platform.

<mark style="color:green;">`POST`</mark> `/question/v2/copy/{question_id}`

• The endpoint for **Copy Question** is <mark style="color:orange;">/question/v2/copy</mark>\
• It points to inquiry-api-service (assessment service) - <mark style="color:orange;">/question/v5/copy</mark> \
• You need to provide a valid Question Id value in <mark style="color:orange;">{question\_id}</mark> field of the API URL.\
• All parameters marked with <mark style="color:red;">\*</mark> are mandatory. You must provide values for these parameters. \
• Mandatory fields cannot be null or empty.

#### Path Parameters

| Name                                           | Type   | Description                                   |
| ---------------------------------------------- | ------ | --------------------------------------------- |
| question\_id<mark style="color:red;">\*</mark> | String | Append a valid Question ID to the Request URL |

#### Headers

| Name                                            | Type   | Description                                                                                                                                                                                                                                                |
| ----------------------------------------------- | ------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Content-Type<mark style="color:red;">\*</mark>  | String | The Content-Type entity is the media type of the resource. The possible media types can be: <mark style="color:green;">Application/json</mark>                                                                                                             |
| Authorization<mark style="color:red;">\*</mark> | String | <p>You require authorization to make use of the API. Raise a request to the administrator for the use of the API. You will receive the authorization key. Specify the key received, here.<br>Set <mark style="color:green;">Bearer {{api\_key}}</mark></p> |
| x-channel-id                                    | String | Unique identification number associated with a root organisation.                                                                                                                                                                                          |

#### Request Body

| Name                                      | Type   | Description                                                                        |
| ----------------------------------------- | ------ | ---------------------------------------------------------------------------------- |
| request<mark style="color:red;">\*</mark> | Object | The body is the representation of the resource object for importing a question set |

{% tabs %}
{% tab title="200: OK The Copy Question operation was successful!" %}

```json
{
    "id": "api.question.copy",
    "ver": "5.0",
    "ts": "2023-06-29T03:37:12ZZ",
    "params": {
        "resmsgid": "8bba3dda-f81e-4659-8c05-55caed20d174",
        "msgid": null,
        "err": null,
        "status": "successful",
        "errmsg": null
    },
    "responseCode": "OK",
    "result": {
        "node_id": {
            "do_2138240203066900481600": "do_2138240204082216961601"
        },
        "versionKey": "1687502491400"
    }
}
```

{% endtab %}

{% tab title="400: Bad Request The Copy Question operation failed. You may have missed providing input for a mandatory parameter.'" %}

```javascript
{
    "id": "api.question.copy",
    "ver": "5.0",
    "ts": "2023-06-29T03:37:12ZZ",
    "params": {
        "resmsgid": "d078ab42-7650-4e5f-8c30-43f37d3ac244",
        "msgid": null,
        "err": "ERR_INVALID_REQUEST",
        "status": "failed",
        "errmsg": "Please provide valid value for [createdFor]"
    },
    "responseCode": "CLIENT_ERROR",
    "result": {
        "messages": null
    }
}
```

{% endtab %}

{% tab title="500: Internal Server Error We track these errors automatically and try to set it right at the earliest." %}

```javascript
{
  "id": "api.question.copy",
  "ver": "5.0",
  "ts": "2023-06-29T03:37:12ZZ",
  "params": {
    "resmsgid": "f234a6f0-3ac4-11eb-b0a2-8d5c9f561887",
    "msgid": null,
    "status": "failed",
    "err": null,
    "errmsg": null
  },
  "responseCode": "SERVER_ERROR",
  "result": {}
}
```

{% endtab %}

{% tab title="404: Not Found The Copy Question operation failed. You may have requested a resource that is not existing in the server.'" %}

```json
{
    "id": "api.questionset.copy",
    "ver": "5.0",
    "ts": "2023-06-29T07:51:03ZZ",
    "params": {
        "resmsgid": "16e68f93-51d0-48d2-82df-b79451e8bdcc",
        "msgid": null,
        "err": "NOT_FOUND",
        "status": "failed",
        "errmsg": "Error! Node(s) doesn't Exists. | [Invalid Node Id.]: do_213824021343412224160"
    },
    "responseCode": "RESOURCE_NOT_FOUND",
    "result": {
        "messages": null
    }
}
```

{% endtab %}
{% endtabs %}

#### Sample Request

```json
{
  "request": {
    "question": {
      "createdBy": "User001",
      "createdFor": [
        "Sunbird"
      ],
      "name": "Sunbird-Question"
    }
  }
}
```

#### Request schema

<table><thead><tr><th width="139.33333333333331">Attribute</th><th width="486">Description</th><th>Type</th></tr></thead><tbody><tr><td>createdBy</td><td>Represents the the user who triggered the copy operation</td><td>string</td></tr><tr><td>createdFor</td><td>Represents the organization on behalf the request was triggered</td><td>Object</td></tr><tr><td>name</td><td>Represents the name of the Question to be copied.</td><td>string</td></tr></tbody></table>

#### Success result schema

| Attribute | Type            | Description               |
| --------- | --------------- | ------------------------- |
| node\_id  | Array of Object | Node Ids that were copied |

**cURL**

```
curl --location -g --request POST '{{host}}/question/v2/copy/{question_id}' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer {{api_key}}' \
--header 'X-Channel-Id: {{channel_id}}' \
--data-raw '{
  "request": {
    "question": {
      "createdBy": "User001",
      "createdFor": [
        "Sunbird"
      ],
      "name": "Sunbird-Question"
    }
  }
}'
```


# Import Question

This API is used to import Question from one instance to another instance of sunbird

## This API is used to import Question from one instance to another instance of sunbird

<mark style="color:green;">`POST`</mark> `/question/v2/import`

• <mark style="color:orange;">/question/v2/import</mark> endpoint executes the "Import Question" request based on parameters provided as metadata in the request body\
• It points to inquiry-api-service (assessment service) - <mark style="color:orange;">/question/v5/import</mark>\
• It is mandatory to provide values for parameters marked with <mark style="color:red;">\*</mark>\
• Mandatory fields cannot be null or empty.

#### Headers

| Name                                            | Type   | Description                                                                                                                                                                                                                                                     |
| ----------------------------------------------- | ------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Content-Type<mark style="color:red;">\*</mark>  | String | The Content-Type entity is the media type of the resource. It should be <mark style="color:green;">Application/json</mark>                                                                                                                                      |
| Authorization<mark style="color:red;">\*</mark> | String | <p>To make use of the API, you require authorization. Raise a request to the administrator, for the use of the API. You will receive the authorization key. Specify the key received, here.</p><p>Set <mark style="color:green;">Bearer {{api\_key}}</mark></p> |
| x-channel-id                                    | String | Unique identification number associated with a root organization.                                                                                                                                                                                               |

#### Request Body

| Name                                      | Type   | Description                                 |
| ----------------------------------------- | ------ | ------------------------------------------- |
| request<mark style="color:red;">\*</mark> | Object | Metadata about the questions to be imported |

{% tabs %}
{% tab title="200: OK The Import Question operation was successful" %}

```javascript
{
  "id": "api.question.import",
  "ver": "5.0",
  "ts": "2023-06-29T03:37:12ZZ",
  "params": {
    "resmsgid": "7cce8934-0a2f-46bf-a0ee-be5f49874cae",
    "msgid": null,
    "err": null,
    "status": "successful",
    "errmsg": null
  },
  "responseCode": "OK",
  "result": {
    "processId": "80a765c7-2202-4b3f-b473-448b5c2cd20e"
  }
}
```

{% endtab %}

{% tab title="400: Bad Request The Import Question operation failed. You may have missed providing input for a mandatory parameter.'" %}

```javascript
{
  "id": "api.question.import",
  "ver": "5.0",
  "ts": "2023-06-29T03:37:12ZZ",
  "params": {
    "resmsgid": "31f88a39-2514-4d86-b424-240166e315be"
  },
  "msgid": null,
  "err": "ERR_REQUIRED_PROPS_VALIDATION",
  "status": "failed",
  "errmsg": "Validation Failed! Mandatory Properties Are [name, code, mimeType, primaryCategory, framework]",
  "responseCode": "CLIENT_ERROR",
  "result": {
    "messages": null
  }
}
```

{% endtab %}

{% tab title="500: Internal Server Error Looks like something went wrong! These errors are tracked automatically." %}

```javascript
{
  "id": "api.question.import",
  "ver": "5.0",
  "ts": "2023-06-29T03:37:12ZZ",
  "params": {
    "resmsgid": "f234a6f0-3ac4-11eb-b0a2-8d5c9f561887",
    "msgid": null,
    "status": "failed",
    "err": null,
    "errmsg": null
  },
  "responseCode": "SERVER_ERROR",
  "result": {}
}
```

{% endtab %}
{% endtabs %}

#### Sample Request

```javascript
{
  "request": {
    "question": [
      {
        "source": "https://dock.sunbirded.org/api/question/v2/read/do_1132390225275781121622",
        "metadata": {
          "framework": "ekstep_ncert_k-12",
          "channel": "01309282781705830427",
          "name": "Question 1",
          "code": "9ae33d1e-a682-f30c-04b5-9bda236650ac",
          "lastPublishedBy": "5a587cc1-e018-4859-a0a8-e842650b9d64"
        },
        "collection": [
          {
            "identifier": "do_11324642736155033614",
            "unitId": "do_11324642761348710417"
          }
        ],
        "stage": "Review"
      }
    ]
  }
}
```

#### Success result schema

| Attribute | Type   | Description                            |
| --------- | ------ | -------------------------------------- |
| processId | String | Unique ID assigned to import operation |

#### cURL

```shell
curl --location -g --request POST '{{host}}/question/v2/import' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer {{api_key}}' \
--header 'X-Channel-Id: {{channel_id}}' \
--data-raw '{
  "request": {
    "question": [
      {
        "source": "https://dock.sunbirded.org/api/question/v2/read/do_1132390225275781121622",
        "metadata": {
          "framework": "ekstep_ncert_k-12",
          "channel": "01309282781705830427",
          "name": "Question 1",
          "code": "9ae33d1e-a682-f30c-04b5-9bda236650ac",
          "lastPublishedBy": "5a587cc1-e018-4859-a0a8-e842650b9d64"
        },
        "collection": [
          {
            "identifier": "do_11324642736155033614",
            "unitId": "do_11324642761348710417"
          }
        ]
      }
    ]
  }
}'
```


# Question List

This API is used to get the list of Questions on the Sunbird-inQuiry Platform.

## This API is used to get the list of Questions on the Sunbird-inQuiry Platform.

<mark style="color:green;">`POST`</mark> `/question/v2/list`

• It gives all metadata of requested question identifiers\
• It points to inquiry-api-service (assessment service)- <mark style="color:orange;">/question/v5/list</mark>\
• You need to provide list of valid question identifiers in the request body\
• It is mandatory to provide values for parameters marked with <mark style="color:red;">\*</mark>\
• Mandatory fields cannot be null or empty.

#### Headers

| Name                                           | Type   | Description                                                                                                                |
| ---------------------------------------------- | ------ | -------------------------------------------------------------------------------------------------------------------------- |
| Content-Type<mark style="color:red;">\*</mark> | String | The Content-Type entity is the media type of the resource. It should be <mark style="color:green;">Application/json</mark> |
| x-channel-id                                   | String | Unique identification number associated with a root organization.                                                          |

#### Request Body

| Name                                      | Type   | Description                  |
| ----------------------------------------- | ------ | ---------------------------- |
| request<mark style="color:red;">\*</mark> | Object | List of question identifiers |

{% tabs %}
{% tab title="200: OK The Question List operation was successful" %}

```javascript
{
    "id": "api.questions.list",
    "ver": "5.0",
    "ts": "2023-06-29T06:51:54ZZ",
    "params": {
        "resmsgid": "7a23e026-3c51-4ec1-8cff-afa078a991f5",
        "msgid": null,
        "err": null,
        "status": "successful",
        "errmsg": null
    },
    "responseCode": "OK",
    "result": {
        "questions": [
            {
                "copyright": "NIT123",
                "code": "ad6f06e4-1a36-47c2-964a-91c249191e4b",
                "subject": [
                    "Math"
                ],
                "qumlVersion": 1.1,
                "channel": "01309282781705830427",
                "responseDeclaration": {
                    "response1": {
                        "cardinality": "single",
                        "type": "integer",
                        "correctResponse": {
                            "value": 0
                        },
                        "mapping": [
                            {
                                "value": 0,
                                "score": 1
                            }
                        ]
                    }
                },
                "language": [
                    "English"
                ],
                "medium": [
                    "English"
                ],
                "mimeType": "application/vnd.sunbird.question",
                "showHints": false,
                "media": [],
                "body": "<div class='question-body' tabindex='-1'><div class='mcq-title' tabindex='0'><p>2+2=?</p></div><div data-choice-interaction='response1' class='mcq-vertical'></div></div>",
                "editorState": {
                    "options": [
                        {
                            "answer": true,
                            "value": {
                                "body": "<p>4</p>",
                                "value": 0
                            }
                        },
                        {
                            "answer": false,
                            "value": {
                                "body": "<p>8</p>",
                                "value": 1
                            }
                        }
                    ],
                    "question": "<p>2+2=?</p>"
                },
                "templateId": "mcq-vertical",
                "createdOn": "2023-06-29T03:45:06.917+0000",
                "objectType": "Question",
                "interactions": {
                    "response1": {
                        "type": "choice",
                        "options": [
                            {
                                "label": "<p>4</p>",
                                "value": 0
                            },
                            {
                                "label": "<p>8</p>",
                                "value": 1
                            }
                        ],
                        "validation": {
                            "required": "Yes"
                        }
                    }
                },
                "gradeLevel": [
                    "Class 1"
                ],
                "primaryCategory": "Multiple Choice Question",
                "contentDisposition": "inline",
                "lastUpdatedOn": "2023-06-29T03:45:07.002+0000",
                "contentEncoding": "gzip",
                "showSolutions": false,
                "allowAnonymousAccess": "Yes",
                "identifier": "do_2138281804342640641518",
                "lastStatusChangedOn": "2023-06-29T03:45:06.917+0000",
                "audience": [
                    "Student"
                ],
                "schemaVersion": "1.1",
                "visibility": "Parent",
                "showTimer": false,
                "author": "Creator1",
                "solutions": {},
                "outcomeDeclaration": {
                    "maxScore": {
                        "cardinality": "single",
                        "type": "integer",
                        "defaultValue": 1
                    }
                },
                "qType": "MCQ",
                "maxScore": 1,
                "languageCode": [
                    "en"
                ],
                "versionKey": "1688010307002",
                "showFeedback": false,
                "license": "CC BY 4.0",
                "complexityLevel": [
                    "evaluate"
                ],
                "interactionTypes": [
                    "choice"
                ],
                "framework": "inquiry_k-12",
                "answer": "<div class='anwser-container'><div class='anwser-body'><p>4</p></div></div>",
                "createdBy": "5a587cc1-e018-4859-a0a8-e842650b9d64",
                "compatibilityLevel": 5,
                "name": "MCQ-1",
                "board": "CBSE",
                "status": "Draft"
            }
        ],
        "count": 1
    }
}
```

{% endtab %}

{% tab title="400: Bad Request The Question List  operation failed. You may have missed providing input for a mandatory parameter.'" %}

```javascript
{
  "id": "api.question.list",
  "ver": "5.0",
  "ts": "2023-06-29T03:37:12ZZ",
  "params": {
    "resmsgid": "86481a2f-513e-4fd4-a1dd-46a7ebcb1e65",
    "msgid": null,
    "err": "CLIENT_ERROR",
    "status": "failed",
    "errmsg": "Either identifier is missing or it is not list type"
  },
  "responseCode": "CLIENT_ERROR",
  "result": {}
}
```

{% endtab %}

{% tab title="500: Internal Server Error Looks like something went wrong! These errors are tracked automatically." %}

```javascript
{
  "id": "api.question.list",
  "ver": "5.0",
  "ts": "2023-06-29T03:37:12ZZ",
  "params": {
    "resmsgid": "f234a6f0-3ac4-11eb-b0a2-8d5c9f561887",
    "msgid": null,
    "status": "failed",
    "err": null,
    "errmsg": null
  },
  "responseCode": "SERVER_ERROR",
  "result": {}
}
```

{% endtab %}
{% endtabs %}

#### Sample Request&#x20;

```json
{
  "request": {
    "search": {
      "identifier": [
        "do_1131687689003827201864",
        "do_0987632323234356522345"
      ]
    }
  }
}
```

#### Success result schema

Below is the list of possible fields which will occur in the question list API

<table><thead><tr><th width="219">Attribute</th><th width="149.33333333333331">Type</th><th>Description</th></tr></thead><tbody><tr><td>mimeType</td><td>string</td><td>MimeType of Question eg. application/vnd.sunbird.question</td></tr><tr><td>audience</td><td>Array of strings</td><td>List of Audience eg. Student/Teacher/Administrator</td></tr><tr><td>lastStatusChangedOn</td><td>string</td><td>Timestamp of last status change</td></tr><tr><td>createdBy</td><td>string</td><td>UserId of creator</td></tr><tr><td>compatibilityLevel</td><td>integer</td><td>compatibility Level</td></tr><tr><td>language</td><td>Array of string</td><td>Language of Question</td></tr><tr><td>lastUpdatedOn</td><td>string</td><td>Timestamp of last question update</td></tr><tr><td>name</td><td>string</td><td>Name of question</td></tr><tr><td>version</td><td>integer</td><td>Version number</td></tr><tr><td>license</td><td>string</td><td>License under it is created</td></tr><tr><td>framework</td><td>string</td><td>Framework in which questiton created</td></tr><tr><td>code</td><td>string</td><td>Unique code for question</td></tr><tr><td>objectType</td><td>string</td><td>Typeof object eg. Question</td></tr><tr><td>identifier</td><td>string</td><td>Unique identifier of Question</td></tr><tr><td>languageCode</td><td>Array of strings</td><td>List of language codes</td></tr><tr><td>channel</td><td>string</td><td>Channel ID from which question is belongs to</td></tr><tr><td>visibility</td><td>string</td><td>visibility of question eg. Parent/Default</td></tr><tr><td>versionKey</td><td>string</td><td>Uniuque version key of  question for specific version</td></tr><tr><td>status</td><td>string</td><td>Staus or state of the question eg. Draft/Review/Live</td></tr><tr><td>createdOn</td><td>string</td><td>Timestamp of creation of question</td></tr><tr><td>primaryCategory</td><td>string</td><td>Main category of question eg. Multiple Choice Question/ Subjective Questions</td></tr></tbody></table>

#### cURL

```shell
curl --location -g --request POST '{{host}}/question/v2/list' \
  -H 'Content-Type: application/json' \
  --data-raw '{"request":{"search":{"identifier":["question_id_1","question_id_2"]}}}' \
  --compressed
```


# Retire Question

This API is used to retiring a questions on the Sunbird-inQuiry Platform.

## This API is used to retiring a questions on the Sunbird-inQuiry Platform.

<mark style="color:red;">`DELETE`</mark> `/question/v2/retire/{question_id}`

• It points to inquiry-api-service (assessment service)- <mark style="color:orange;">/question/v5/retire</mark>\
• You need to provide a valid Question Id value in <mark style="color:orange;">{question\_id}</mark> field of the API URL.\
• It is mandatory to provide values for parameters marked with <mark style="color:red;">\*</mark>\
• Mandatory fields cannot be null or empty.

#### Path Parameters

| Name                                           | Type   | Description                                   |
| ---------------------------------------------- | ------ | --------------------------------------------- |
| question\_id<mark style="color:red;">\*</mark> | String | Append a valid Question ID To the Request URL |

#### Headers

| Name                                            | Type   | Description                                                                                                                                                                                                                                                     |
| ----------------------------------------------- | ------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Authorization<mark style="color:red;">\*</mark> | String | <p>To make use of the API, you require authorization. Raise a request to the administrator, for the use of the API. You will receive the authorization key. Specify the key received, here.</p><p>Set <mark style="color:green;">Bearer {{api\_key}}</mark></p> |
| x-channel-id                                    | String | Unique identification number associated with a root organization.                                                                                                                                                                                               |

{% tabs %}
{% tab title="200: OK The Retire Question operation was successful!" %}

<pre class="language-javascript"><code class="lang-javascript">{
  "id": "api.question.retire",
<strong>  "ver": "5.0",
</strong>  "ts": "2023-06-29T03:37:12ZZ",
  "params": {
    "resmsgid": "98c9f97d-f9d6-4da9-be88-2852294c2aaa",
    "msgid": null,
    "err": null,
    "status": "successful",
    "errmsg": null
  },
  "responseCode": "OK",
  "result": {
    "identifier": "do_113207939069968384112",
    "versionKey": "1612297249754"
  }
}
</code></pre>

{% endtab %}

{% tab title="400: Bad Request Question is already retired" %}

```javascript
{
  "id": "api.question.retire",
  "ver": "5.0",
  "ts": "2023-06-29T03:37:12ZZ",
  "params": {
    "resmsgid": "0608b59d-dfb9-4c0e-807f-1a19c9a163fe",
    "msgid": null,
    "err": "ERR_QUESTION_RETIRE",
    "status": "failed",
    "errmsg": "Question with identifier : do_113207939069968384112 is already Retired."
  },
  "responseCode": "CLIENT_ERROR",
  "result": {
    "messages": null
  }
}
```

{% endtab %}

{% tab title="404: Not Found The Retire Question operation failed. The possible reason for failure is that you may have provided wrong question ID" %}

```javascript
{
  "id": "api.question.retire",
  "ver": "5.0",
  "ts": "2023-06-29T03:37:12ZZ",
  "params": {
    "resmsgid": "da7af22e-bdce-48f0-8743-f50fa6c2cd21",
    "msgid": null,
    "err": "NOT_FOUND",
    "status": "failed",
    "errmsg": "Error! Node(s) does not Exist. | [Invalid Node Id.]: do_1132079390699683841121"
  },
  "responseCode": "RESOURCE_NOT_FOUND",
  "result": {
    "messages": null
  }
}
```

{% endtab %}

{% tab title="500: Internal Server Error Looks like something went wrong! These errors are tracked automatically." %}

```javascript
{
  "id": "api.question.retire",
  "ver": "5.0",
  "ts": "2023-06-29T03:37:12ZZ",
  "params": {
    "resmsgid": "f234a6f0-3ac4-11eb-b0a2-8d5c9f561887",
    "msgid": null,
    "status": "failed",
    "err": null,
    "errmsg": null
  },
  "responseCode": "SERVER_ERROR",
  "result": {}
}
```

{% endtab %}
{% endtabs %}

#### Success result Schema

<table><thead><tr><th width="172.33333333333331">Attribute</th><th width="152">Type</th><th>Description</th></tr></thead><tbody><tr><td>identifier</td><td>String</td><td>Unique Question identifier</td></tr><tr><td>versionKey</td><td>String</td><td>Unique version key for question</td></tr></tbody></table>

#### cURL

```
curl --location -g --request DELETE '{{host}}/question/v2/retire/{question_id}' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer {{api_key}}' \
--header 'X-Channel-Id: {{channel_id}}' \
```


# QuestionSet API's

List questionset related API's


# Create QuestionSet

This API is used to create a question set on the Sunbird-inQuiry Platform.

## This API is used to create a question set on the Sunbird-inQuiry Platform.

<mark style="color:green;">`POST`</mark> `/questionset/v2/create`

• The endpoint for Create QuestionSet is <mark style="color:orange;">/questionset/v2/create</mark>\
• It points to inquiry-api-service (assessment service) - <mark style="color:orange;">/questionset/v5/create</mark>\
• It is mandatory to provide values for parameters marked with <mark style="color:red;">\*</mark>\
• Mandatory fields cannot be null or empty.

#### Headers

| Name                                            | Type   | Description                                                                                                                                                                                                                                                 |
| ----------------------------------------------- | ------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Content-Type<mark style="color:red;">\*</mark>  | String | The Content-Type entity is the media type of the resource. The possible media types can be:- <mark style="color:green;">Application/json</mark>                                                                                                             |
| Authorization<mark style="color:red;">\*</mark> | String | <p>To make use of the API, you require authorization. Raise a request to the administrator for the use of the API. You will receive the authorization key. Specify the key received, here.<br>Set <mark style="color:green;">Bearer {{api\_key}}</mark></p> |
| x-channel-id                                    | String | Unique identification number associated with a root organization.                                                                                                                                                                                           |

#### Request Body

| Name                                      | Type   | Description                                                                    |
| ----------------------------------------- | ------ | ------------------------------------------------------------------------------ |
| request<mark style="color:red;">\*</mark> | Object | The body is the representation of the resource object for creating questionset |

{% tabs %}
{% tab title="200: OK The Create Questionset operation was successful!" %}

```javascript
{
  "id": "api.questionset.create",
  "ver": "5.0",
  "ts": "2023-06-29T07:51:03ZZ",
  "params": {
    "resmsgid": "4c45a5e2-c3b4-47c1-95a2-3a31f7e7c1ca",
    "msgid": null,
    "err": null,
    "status": "successful",
    "errmsg": null
  },
  "responseCode": "OK",
  "result": {
    "identifier": "do_113208291312132096114",
    "versionKey": "1612340248069"
  }
}
```

{% endtab %}

{% tab title="400: Bad Request The Create Questionset operation was failed! You may have missed input for the mandatory field" %}

```javascript
{
  "id": "api.questionset.create",
  "ver": "5.0",
  "ts": "2023-06-29T07:51:03ZZ",
  "params": {
    "resmsgid": "6cc7bb1c-330e-4da5-9075-1ac69cddf225",
    "msgid": null,
    "err": "CLIENT_ERROR",
    "status": "failed",
    "errmsg": "Validation Errors"
  },
  "responseCode": "CLIENT_ERROR",
  "result": {
    "messages": [
      "Metadata mimeType should be one of: [application/vnd.sunbird.questionset]"
    ]
  }
}
```

{% endtab %}

{% tab title="500: Internal Server Error We track these errors automatically and try to set it right at the earliest. Try refreshing the page." %}

```javascript
{
  "id": "api.questionset.create",
  "ver": "5.0",
  "ts": "2023-06-29T07:51:03ZZ",
  "params": {
    "resmsgid": "f234a6f0-3ac4-11eb-b0a2-8d5c9f561887",
    "msgid": null,
    "status": "failed",
    "err": null,
    "errmsg": null
  },
  "responseCode": "SERVER_ERROR",
  "result": {}
}
```

{% endtab %}
{% endtabs %}

#### Sample Request

```json
{
  "request": {
    "questionset": {
      "code": "asa1212",
      "mimeType": "application/vnd.sunbird.questionset",
      "primaryCategory": "Practice Question Set",
      "name": "Test Question Set"
    }
  }
}
```

#### Request Schema

<table><thead><tr><th width="180">Attribute</th><th width="99">Type</th><th>Description</th><th width="102">Required</th></tr></thead><tbody><tr><td>name</td><td>String</td><td>Represents the name of the questionset</td><td>Yes</td></tr><tr><td>code</td><td>String</td><td>Represents the unique code for the questionset</td><td>Yes</td></tr><tr><td>mimeType</td><td>String</td><td>questionset mime type</td><td>Yes</td></tr><tr><td>primaryCategory</td><td>String</td><td>PrimaryCategory agains which questionset schema will be validated</td><td>Yes</td></tr></tbody></table>

#### Success result schema

<table><thead><tr><th width="184">Attribute</th><th width="158.33333333333331">Type</th><th>Description</th></tr></thead><tbody><tr><td>identifier</td><td>String</td><td>Unique Question identifier</td></tr><tr><td>versionKey</td><td>String</td><td>Unique version key for question</td></tr></tbody></table>

#### cURL

```shell
curl --location -g --request POST '{{host}}/questionset/v2/create' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer {{api_key}}' \
--header 'X-Channel-Id: {{channel_id}}' \
--data-raw '{
    "request": {
        "questionset": {
            "code": "questionset.1",
            "mimeType": "application/vnd.sunbird.questionset",
            "primaryCategory": "Practice Question Set",
            "name": "Test Question Set"
        }
    }
}'
```

#### Complete example

The following request is to create a question set object with basic information. To add additional metadata, and questions, please use the question-set update hierarchy API.

```json
{
  "request": {
    "questionset": {
      "name": "My QuestionSet",
      "mimeType": "application/vnd.sunbird.questionset",
      "primaryCategory": "Practice Question Set",
      "createdBy": "5a587cc1-e018-4859-a0a8-e842650b9d64",
      "createdFor": [
        "01309282781705830427"
      ],
      "framework": "inquiry_k-12",
      "code": "7d5aaa70-ffb8-d062-ba10-1db445a11dbc"
    }
  }
}
```


# Read QuestionSet

This API is used to read an existing question set on the Sunbird-inQuiry Platform.

## This API is used to read an existing question set on the Sunbird-inQuiry Platform.

<mark style="color:blue;">`GET`</mark> `/questionset/v2/read/{questionSet_id}`

• The <mark style="color:orange;">/questionset/v2/read/{</mark>questionSet\_id<mark style="color:orange;">}</mark> endpoint executes a request for fetching the question to read.\
• This API returns only the metadata of the question set not the hierarchical structure. To read  hierarchical structure please use **read** **questionset hierarchy** API\
• The endpoint for reading QuestionSet is <mark style="color:orange;">`/questionset/v2/read`</mark>\
• It points to inquiry-api-service (assessment service)  - <mark style="color:orange;">/questionset/v5/read</mark>\
• You need to provide a valid QuestionSet Id value in <mark style="color:orange;">{questionSet\_id}</mark> field of the API URL. \
• It is mandatory to provide values for parameters marked with <mark style="color:red;">\*</mark>\
• Mandatory fields cannot be null or empty.

#### Path Parameters

| Name                                              | Type   | Description                                       |
| ------------------------------------------------- | ------ | ------------------------------------------------- |
| questionSet\_id<mark style="color:red;">\*</mark> | String | Append a valid Question Set Id To the Request URL |

#### Query Parameters

| Name                                  | Type   | Description                                                                                                     |
| ------------------------------------- | ------ | --------------------------------------------------------------------------------------------------------------- |
| mode=edit                             | String | To fetch the latest version of node from the database for edit purpose                                          |
| fields=comma separated metadata names | String | To fetch the specific fields, this query parameter can be used eg. fields=name,description,outcomDeclaration... |

#### Headers

| Name          | Type   | Description                                                                                                                                                                                                                                                 |
| ------------- | ------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Content-Type  | String | The Content-Type entity is the media type of the resource. Possible media types can be: <mark style="color:green;">Application/json</mark>                                                                                                                  |
| Authorization | String | <p>To make use of the API, you require authorization. Raise a request to the administrator for the use of the API. You will receive the authorization key. Specify the key received, here.<br>Set <mark style="color:green;">Bearer {{api\_key}}</mark></p> |
| x-channel-id  | String | Unique identification number associated with a root organization.                                                                                                                                                                                           |

{% tabs %}
{% tab title="200: OK The "Read Question Set" operation was successfully executed" %}

```javascript
{
    "id": "api.questionset.read",
    "ver": "5.0",
    "ts": "2023-06-29T11:15:59ZZ",
    "params": {
        "resmsgid": "813ea426-92f2-4e5b-b9bf-c19bbd8e2b23",
        "msgid": null,
        "err": null,
        "status": "successful",
        "errmsg": null
    },
    "responseCode": "OK",
    "result": {
        "questionset": {
            "code": "sunbird.qs.1",
            "allowSkip": "Yes",
            "containsUserData": "No",
            "qumlVersion": 1.1,
            "language": [
                "English"
            ],
            "mimeType": "application/vnd.sunbird.questionset",
            "showHints": false,
            "createdOn": "2023-06-29T11:15:31.610+0000",
            "objectType": "QuestionSet",
            "scoreCutoffType": "AssessmentLevel",
            "primaryCategory": "Practice Question Set",
            "contentDisposition": "inline",
            "lastUpdatedOn": "2023-06-29T11:15:31.610+0000",
            "contentEncoding": "gzip",
            "generateDIALCodes": "No",
            "showSolutions": false,
            "trackable": {
                "enabled": "No",
                "autoBatch": "No"
            },
            "allowAnonymousAccess": "Yes",
            "identifier": "do_2138284018199265281540",
            "lastStatusChangedOn": "2023-06-29T11:15:31.610+0000",
            "schemaVersion": "1.1",
            "requiresSubmit": "No",
            "visibility": "Default",
            "showTimer": true,
            "consumerId": "6968004d-c67e-434a-a350-773aa1e068a3",
            "setType": "materialised",
            "languageCode": [
                "en"
            ],
            "versionKey": "1688037331610",
            "showFeedback": false,
            "license": "CC BY 4.0",
            "createdBy": "sunbird-user-1",
            "compatibilityLevel": 6,
            "name": "QuestionSet-FT-1",
            "navigationMode": "non-linear",
            "allowBranching": "No",
            "shuffle": true,
            "status": "Draft"
        }
    }
}
```

{% endtab %}

{% tab title="404: Not Found The Read Question Set operation failed! The possible reason for failure is that you may have provided wrong question set ID." %}

```javascript
{
  "id": "api.questionset.read",
  "ver": "5.0",
  "ts": "2023-06-29T11:15:59ZZ",
  "params": {
    "resmsgid": "815b341a-7984-45a1-b1f9-4335da18985e",
    "msgid": null,
    "err": "NOT_FOUND",
    "status": "failed",
    "errmsg": "Error! Node(s) does not exist. | [Invalid Node Id.]: do_1132083238015549441201"
  },
  "responseCode": "RESOURCE_NOT_FOUND",
  "result": {
    "messages": null
  }
}
```

{% endtab %}

{% tab title="500: Internal Server Error Looks like something went wrong! These errors are tracked automatically" %}

```javascript
{
  "id": "api.questionset.read",
  "ver": "5.0",
  "ts": "2023-06-29T07:51:03ZZ",
  "params": {
    "resmsgid": "f234a6f0-3ac4-11eb-b0a2-8d5c9f561887",
    "msgid": null,
    "status": "failed",
    "err": null,
    "errmsg": null
  },
  "responseCode": "SERVER_ERROR",
  "result": {}
}
```

{% endtab %}
{% endtabs %}

#### Success response schema

<table><thead><tr><th width="223">Attribute</th><th width="121.33333333333331">Type</th><th>Description</th></tr></thead><tbody><tr><td>identifier</td><td>String</td><td>Unique Question set Identifier</td></tr><tr><td>name</td><td>String</td><td>Name of the Question set</td></tr><tr><td>versionKey</td><td>String</td><td>Unique version key of Question set</td></tr><tr><td>code</td><td>String</td><td>Unique Code for Question set</td></tr><tr><td>lastStatusChangedOn</td><td>String</td><td>Last status changed time</td></tr><tr><td>visibility</td><td>String</td><td>Question set Visibility eg. parent or default</td></tr><tr><td>mimeType</td><td>String</td><td>Question mimeType eg. application/vnd.sunbird.questionset</td></tr><tr><td>createdOn</td><td>String</td><td>Time of question set creation</td></tr><tr><td>objectType</td><td>String</td><td>QuestionSet objectType</td></tr><tr><td>primaryCategory</td><td>String</td><td>Eg - <code>Practice Question set</code> or <code>Exam Question set</code></td></tr><tr><td>status</td><td>String</td><td>Question status <code>Draft/Review/Live</code></td></tr><tr><td>lastUpdatedOn</td><td>String</td><td>Last updated time</td></tr></tbody></table>

#### cURL

**Sample CURL to read all metadata**

```shell
curl --location -g --request GET '{{host}}/questionset/v2/read/{{questionSet_id}}' \
--header 'Authorization: Bearer {{api_key}}'
```

**Sample CURL to read all metadata**

```
curl --location -g --request GET '{{host}}/questionset/v2/read/{{questionSet_id}}?fields=name,description' \
--header 'Authorization: Bearer {{api_key}}'
```


# Read Private QuestionSet

This API is used to read an existing private question set on the Sunbird-inQuiry Platform.

## This API is used to read an existing private question set on the Sunbird-inQuiry Platform.

<mark style="color:blue;">`GET`</mark> `/questionset/v2/private/read/{questionSet_id}`

• The <mark style="color:orange;">/questionset/v2/private/read/{QuestionSet\_Id}</mark> endpoint executes a request for fetching the private and public question sets to be viewed and read. \
• The endpoint for reading Private QuestionSet is <mark style="color:orange;">/questionset/v2/private/read</mark>\
• It points to inquiry-api-service (assessment service) - <mark style="color:orange;">/questionset/v5/private/read</mark> \
• You need to provide a valid QuestionSet Id value in <mark style="color:orange;">{questionSet\_id}</mark> field of the API URL.\
• It is mandatory to provide values for parameters marked with <mark style="color:red;">\*</mark>\
• Mandatory fields cannot be null or empty.

#### Path Parameters

| Name                                              | Type   | Description                                       |
| ------------------------------------------------- | ------ | ------------------------------------------------- |
| questionSet\_id<mark style="color:red;">\*</mark> | String | Append a valid Question Set Id To the Request URL |

#### Headers

| Name                                            | Type   | Description                                                                                                                                                                                                                                                 |
| ----------------------------------------------- | ------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Content-Type                                    | String | The Content-Type entity is the media type of the resource. Possible media types can be: <mark style="color:green;">Application/json</mark>                                                                                                                  |
| Authorization<mark style="color:red;">\*</mark> | String | <p>To make use of the API, you require authorization. Raise a request to the administrator for the use of the API. You will receive the authorization key. Specify the key received, here.<br>Set <mark style="color:green;">Bearer {{api\_key}}</mark></p> |
| x-channel-id<mark style="color:red;">\*</mark>  | String | Unique identification number associated with a root organization.                                                                                                                                                                                           |

{% tabs %}
{% tab title="200: OK The "Read Private Question Set" operation was successfully executed" %}

```javascript
{
    "id": "api.questionset.private.read",
    "ver": "5.0",
    "ts": "2023-06-29T11:23:27ZZ",
    "params": {
        "resmsgid": "c14dcc78-4387-4a7d-acb5-2e071dbc3117",
        "msgid": null,
        "err": null,
        "status": "successful",
        "errmsg": null
    },
    "responseCode": "OK",
    "result": {
        "questionset": {
            "code": "sunbird.qs.1",
            "allowSkip": "Yes",
            "containsUserData": "No",
            "qumlVersion": 1.1,
            "channel": "test-0001",
            "language": [
                "English"
            ],
            "mimeType": "application/vnd.sunbird.questionset",
            "showHints": false,
            "createdOn": "2023-06-29T11:22:49.141+0000",
            "objectType": "QuestionSet",
            "scoreCutoffType": "AssessmentLevel",
            "primaryCategory": "Practice Question Set",
            "contentDisposition": "inline",
            "lastUpdatedOn": "2023-06-29T11:22:49.141+0000",
            "contentEncoding": "gzip",
            "generateDIALCodes": "No",
            "showSolutions": false,
            "trackable": {
                "enabled": "No",
                "autoBatch": "No"
            },
            "allowAnonymousAccess": "Yes",
            "identifier": "do_2138284054041886721542",
            "lastStatusChangedOn": "2023-06-29T11:22:49.141+0000",
            "schemaVersion": "1.1",
            "requiresSubmit": "No",
            "visibility": "Private",
            "showTimer": true,
            "consumerId": "6968004d-c67e-434a-a350-773aa1e068a3",
            "setType": "materialised",
            "languageCode": [
                "en"
            ],
            "versionKey": "1688037769141",
            "showFeedback": false,
            "license": "CC BY 4.0",
            "createdBy": "sunbird-user-1",
            "compatibilityLevel": 6,
            "name": "QuestionSet-FT-1",
            "navigationMode": "non-linear",
            "allowBranching": "No",
            "shuffle": true,
            "status": "Draft"
        }
    }
}
```

{% endtab %}

{% tab title="404: Not Found The Read Private Question Set operation failed! The possible reason for failure is that you may have provided wrong question set ID." %}

```javascript
{
  "id": "api.questionset.private.read",
  "ver": "5.0",
  "ts": "2023-06-29T07:51:03ZZ",
  "params": {
    "resmsgid": "50bd44a0-ccc8-48fd-9361-3a2990f44e16",
    "msgid": null,
    "err": "NOT_FOUND",
    "status": "failed",
    "errmsg": "Error! Node(s) doesn't Exists. | [Invalid Node Id.]: do_11336896348850585612"
  },
  "responseCode": "RESOURCE_NOT_FOUND",
  "result": {
    "messages": null
  }
}
```

{% endtab %}

{% tab title="500: Internal Server Error Looks like something went wrong! These errors are tracked automatically" %}

```javascript
{
  "id": "api.questionset.private.read",
  "ver": "5.0",
  "ts": "2023-06-29T07:51:03ZZ",
  "params": {
    "resmsgid": "f234a6f0-3ac4-11eb-b0a2-8d5c9f561887",
    "msgid": null,
    "status": "failed",
    "err": null,
    "errmsg": null
  },
  "responseCode": "SERVER_ERROR",
  "result": {}
}
```

{% endtab %}
{% endtabs %}

#### cURL

```shell
curl --location -g --request GET '{{host}}/questionset/v2/private/read/{{questionSet_id}}' \
--header 'Authorization: Bearer {{api_key}}' \
--header 'X-Channel-ID: {{channel_id}}'
```


# Update QuestionSet

This API is used to update an existing question set on the Sunbird-inQuiry Platform.

## This API is used to update an existing question set on the Sunbird-inQuiry Platform.

<mark style="color:purple;">`PATCH`</mark> `/questionset/v2/update/{questionSet_id}`

• <mark style="color:orange;">/Update/</mark> endpoint executes the "Update QuestionSet" request based on parameters provided as metadata in the request body.\
• It points to inquiry-api-service (assessment service) - <mark style="color:orange;">/questionset/v5/update</mark>\
• It is mandatory to provide values for parameters marked with <mark style="color:red;">\*</mark>. \
• Mandatory fields cannot be null or empty.

#### Path Parameters

| Name                                              | Type   | Description                                        |
| ------------------------------------------------- | ------ | -------------------------------------------------- |
| questionSet\_id<mark style="color:red;">\*</mark> | String | Append a valid QuestionSet ID to the requested URL |

#### Headers

| Name                                            | Type   | Description                                                                                                                                                                                                                     |
| ----------------------------------------------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Content-Type<mark style="color:red;">\*</mark>  | String | The Content-Type entity is the media type of the resource. Possible media types can be:-<mark style="color:green;">Application/json</mark>                                                                                      |
| Authorization<mark style="color:red;">\*</mark> | String | <p>All question APIs require authorization for use. Specify the authorization key received from the administrator when placing the request for use of the API.<br>Set <mark style="color:green;">Bearer {{api\_key}}</mark></p> |
| x-channel-id                                    | String | Unique identification number associated with a root organization.                                                                                                                                                               |

#### Request Body

| Name                                      | Type   | Description                                               |
| ----------------------------------------- | ------ | --------------------------------------------------------- |
| request<mark style="color:red;">\*</mark> | Object | It contains metadata about the questionset to be updated. |

{% tabs %}
{% tab title="200: OK The Update Question Set operation was successfuly executed." %}

```javascript
{
  "id": "api.questionset.update",
  "ver": "5.0",
  "ts": "2023-06-29T07:51:03ZZ",
  "params": {
    "resmsgid": "9d9d4824-cc40-4ac7-a3d6-6da61c0240e9",
    "msgid": null,
    "err": null,
    "status": "successful",
    "errmsg": null
  },
  "responseCode": "OK",
  "result": {
    "identifier": "do_113207924037746688110",
    "versionKey": "1612295707004"
  }
}
```

{% endtab %}

{% tab title="400: Bad Request The 'Update QuestionSet' operation failed ! The possible reason for failure is that you may have missed providing input for a mandatory parameter." %}

```javascript
{
  "id": "api.questionset.update",
  "ver": "5.0",
  "ts": "2023-06-29T07:51:03ZZ",
  "params": {
    "resmsgid": "fcfcf6d6-84f1-43f5-b573-c3b6cf69ef53",
    "msgid": null,
    "err": "CLIENT_ERROR",
    "status": "failed",
    "errmsg": "Invalid version Key"
  },
  "responseCode": "CLIENT_ERROR",
  "result": {
    "messages": null
  }
}
```

{% endtab %}

{% tab title="404: Not Found The Update Question Set operation failed !The possible reason for failure is that you may have provided wrong question ID." %}

```javascript
{
  "id": "api.questionset.update",
  "ver": "5.0",
  "ts": "2023-06-29T07:51:03ZZ",
  "params": {
    "resmsgid": "2b139ee9-f091-4cca-b466-32af45f49a65",
    "msgid": null,
    "err": "NOT_FOUND",
    "status": "failed",
    "errmsg": "Error! Node(s) does not exist. | [Invalid Node Id.]: do_1132079240377466881101"
  },
  "responseCode": "RESOURCE_NOT_FOUND",
  "result": {
    "messages": null
  }
}
```

{% endtab %}

{% tab title="500: Internal Server Error Looks like something went wrong! These errors are tracked automatically" %}

```javascript
{
  "id": "api.questionset.update",
  "ver": "5.0",
  "ts": "2023-06-29T07:51:03ZZ",
  "params": {
    "resmsgid": "f234a6f0-3ac4-11eb-b0a2-8d5c9f561887",
    "msgid": null,
    "status": "failed",
    "err": null,
    "errmsg": null
  },
  "responseCode": "SERVER_ERROR",
  "result": {}
}
```

{% endtab %}
{% endtabs %}

#### Sample Request

```json
{
  "request": {
    "questionset": {
      "description": "Updated description",
      "versionKey": "1612295414767"
    }
  }
}
```

#### Request schema

<table><thead><tr><th width="168">Attribute</th><th width="111">Type</th><th width="353">Description</th><th>Required</th></tr></thead><tbody><tr><td>versionKey</td><td>String</td><td>Represents the transaction update version key of the Questionset</td><td>Yes</td></tr><tr><td>description</td><td>String</td><td>Represents the description of the Questionset</td><td>No</td></tr></tbody></table>

#### Success result schema

| Attribute  | Type   | Description                     |
| ---------- | ------ | ------------------------------- |
| identifier | String | Unique Question identifier      |
| versionKey | String | Unique version key for question |

####

#### cURL

```shell
curl --location -g --request PATCH '{{host}}/questionset/v2/update/{{questionSet_id}}' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer {{api_key}}' \
--data-raw '{
  "request": {
      "questionset":{
        "versionKey": {{versionKey}},
        "description": "Updated description"
      }
  }
}'
```


# Review QuestionSet

This API is used to send question set for review on the Sunbird-inQuiry Platform.

## This API is used to send question set for review on the Sunbird-inQuiry Platform.

<mark style="color:green;">`POST`</mark> `/questionset/v2/review/{questionSet_Id}`

• The <mark style="color:orange;">/questionset/v2/review/{questionSet\_Id}</mark> endpoint executes the "***Submit for Review***" request based on parameters provided as metadata in the request body. \
• It points to inquiry-api-service (assessment service) - <mark style="color:orange;">/questionset/v5/review</mark>\
• You need to provide a valid QuestionSet Id value in <mark style="color:orange;">{questionSet\_Id}</mark> field of the API URL. \
• It is mandatory to provide values for parameters marked with <mark style="color:red;">\*</mark>\
• Mandatory fields cannot be null or empty.

#### Path Parameters

| Name                                              | Type   | Description                                       |
| ------------------------------------------------- | ------ | ------------------------------------------------- |
| questionSet\_Id<mark style="color:red;">\*</mark> | String | Append a valid Question Set Id To the Request URL |

#### Headers

| Name                                            | Type   | Description                                                                                                                                                                                                                                                    |
| ----------------------------------------------- | ------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Content-Type<mark style="color:red;">\*</mark>  | String | The Content-Type entity is the media type of the resource. Possible media types can be: <mark style="color:green;">Application/json</mark>                                                                                                                     |
| Authorization<mark style="color:red;">\*</mark> | String | <p>To make use of the API, you require authorization. Raise a request to the administrator for the use of the API. You will receive the authorization key. Specify the key received, here.</p><p>Set <mark style="color:green;">Bearer {{api\_key}}</mark></p> |
| x-channel-id                                    | String | Unique identification number associated with a root organization.                                                                                                                                                                                              |

#### Request Body

| Name    | Type   | Description                                               |
| ------- | ------ | --------------------------------------------------------- |
| request | Object | It contains metadata about the questionset to be updated. |

{% tabs %}
{% tab title="200: OK  The 'Review Question Set' operation failed ! The possible reason for failure is that you may have missed providing input for a mandatory parameter." %}

```javascript
{
  "id": "api.questionset.review",
  "ver": "5.0",
  "ts": "2023-06-29T07:51:03ZZ",
  "params": {
    "resmsgid": "679a458f-cd12-4dee-a6b4-5aea11fbe426",
    "msgid": null,
    "err": null,
    "status": "successful",
    "errmsg": null
  },
  "responseCode": "OK",
  "result": {
    "identifier": "do_113208323801554944120",
    "versionKey": "1612344214060"
  }
}
```

{% endtab %}

{% tab title="400: Bad Request The 'Review Question Set' operation failed ! The possible reason for failure is that you may have missed providing input for a mandatory parameter." %}

```javascript
{
  "id": "api.questionset.review",
  "ver": "5.0",
  "ts": "2023-06-29T07:51:03ZZ",
  "params": {
    "resmsgid": "95670d2a-764c-489f-bf27-b4acedc4b465",
    "msgid": null,
    "err": "ERR_QUESTION_SET_REVIEW",
    "status": "failed",
    "errmsg": "A question set with status other than Draft can't be sent for review."
  },
  "responseCode": "CLIENT_ERROR",
  "result": {
    "messages": null
  }
}
```

{% endtab %}

{% tab title="404: Not Found The Send Question Set for Review operation failed! The possible reason for failure is that you may have provided wrong question set ID." %}

```javascript
{
  "id": "api.questionset.review",
  "ver": "5.0",
  "ts": "2023-06-29T07:51:03ZZ",
  "params": {
    "resmsgid": "852b878c-a607-4d72-9458-6239e36adb9e",
    "msgid": null,
    "err": "NOT_FOUND",
    "status": "failed",
    "errmsg": "Error! Node(s) does not exist. | [Invalid Node Id.]: do_1132079319215554561111"
  },
  "responseCode": "RESOURCE_NOT_FOUND",
  "result": {
    "messages": null
  }
}
```

{% endtab %}

{% tab title="500: Internal Server Error Looks like something went wrong! We track these errors automatically" %}

```javascript
{
  "id": "api.questionset.review",
  "ver": "5.0",
  "ts": "2023-06-29T07:51:03ZZ",
  "params": {
    "resmsgid": "f234a6f0-3ac4-11eb-b0a2-8d5c9f561887",
    "msgid": null,
    "status": "failed",
    "err": null,
    "errmsg": null
  },
  "responseCode": "SERVER_ERROR",
  "result": {}
}
```

{% endtab %}
{% endtabs %}

#### Success result schema

<table><thead><tr><th width="154.33333333333331">Attribute</th><th width="257">Type</th><th>Description</th></tr></thead><tbody><tr><td>identifier</td><td>String</td><td>Unique Question identifier</td></tr><tr><td>versionKey</td><td>String</td><td>Unique version key for question</td></tr></tbody></table>

#### cURL

```shell
curl --location -g --request POST '{{host}}/questionset/v2/review/{{questionSet_id}}' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer {{api_key}}' \
--header 'X-Channel-Id: {{channel_id}}' \
--data-raw '{
  "request": {
    "questionset": {}
  }
}'
```


# Reject QuestionSet

This API is used to reject the question set, which is sent for review on the Sunbird-inQuiry Platform.

## This API is used to reject the question set, which is sent for review on the Sunbird-inQuiry Platform.

<mark style="color:green;">`POST`</mark> `/questionset/v2/reject/{questionSet_Id}}`

• The  <mark style="color:orange;">/questionset/v2/reject/{questionSet\_Id}</mark> endpoint executes the "Rejecting QuestionSet" request based on parameters provided as metadata in the request body.\
• It points to inquiry-api-service (assessment service) - <mark style="color:orange;">/questionset/v5/reject/{questionSet\_Id}</mark>\
• You need to provide a valid QuestionSet Id value in the <mark style="color:orange;">{questionSet\_Id}</mark> field of the API URL. \
• It is mandatory to provide values for parameters marked with <mark style="color:red;">\*</mark>\
• Mandatory fields cannot be null or empty.

#### Path Parameters

| Name                                              | Type   | Description                                       |
| ------------------------------------------------- | ------ | ------------------------------------------------- |
| questionSet\_Id<mark style="color:red;">\*</mark> | String | Append a valid Question Set Id To the Request URL |

#### Headers

| Name                                            | Type   | Description                                                                                                                                                                                                                    |
| ----------------------------------------------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| Content-Type<mark style="color:red;">\*</mark>  | String | The Content-Type entity is the media type of the resource. Possible media types can be: <mark style="color:green;">Application/json</mark>                                                                                     |
| Authorization<mark style="color:red;">\*</mark> | String | <p>All content APIs require authorization for use. Specify the authorization key received from the administrator when placing the request for use of the API.<br>Set <mark style="color:green;">Bearer {{api\_key}}</mark></p> |
| x-channel-id                                    | String | Unique identification number associated with a root organization.                                                                                                                                                              |

#### Request Body

| Name    | Type   | Description                                       |
| ------- | ------ | ------------------------------------------------- |
| request | Object | The metadata about the questionset to be rejected |

{% tabs %}
{% tab title="200: OK  Reject QuestionSet review operation was successfully executed." %}

```javascript
{
  "id": "api.questionset.reject",
  "ver": "5.0",
  "ts": "2023-06-29T07:51:03ZZ",
  "params": {
    "resmsgid": "a505a723-616f-4e3f-9a52-2f0d9924f732",
    "msgid": null,
    "err": null,
    "status": "successful",
    "errmsg": null
  },
  "responseCode": "OK",
  "result": {
    "identifier": "do_113208406116417536122",
    "versionKey": "1612354279918"
  }
}
```

{% endtab %}

{% tab title="400: Bad Request The 'Review Reject QuestionSet' operation failed ! The possible reason for failure is that you may have missed providing input for a mandatory parameter." %}

```javascript
{
  "id": "api.questionset.reject",
  "ver": "5.0",
  "ts": "2023-06-29T07:51:03ZZ",
  "params": {
    "resmsgid": "cbcaa290-e132-47e6-b4d9-94212037195d",
    "msgid": null,
    "err": "ERR_QUESTION_SET_REJECT",
    "status": "failed",
    "errmsg": "QuestionSet is not in 'Review' state for identifier: do_113208406116417536122"
  },
  "responseCode": "CLIENT_ERROR",
  "result": {
    "messages": null
  }
}
```

{% endtab %}

{% tab title="404: Not Found The 'Review Reject QuestionSet' operation failed ! The possible reason for failure is that you may have missed providing input for a mandatory parameter." %}

```javascript
{
  "id": "api.questionset.reject",
  "ver": "5.0",
  "ts": "2023-06-29T07:51:03ZZ",
  "params": {
    "resmsgid": "6fc0bd55-e99e-4ae1-80e2-7275458258ab",
    "msgid": null,
    "err": "NOT_FOUND",
    "status": "failed",
    "errmsg": "Error! Node(s) doesn't Exists. | [Invalid Node Id.]: do_1132084061164175361221"
  },
  "responseCode": "RESOURCE_NOT_FOUND",
  "result": {
    "messages": null
  }
}
```

{% endtab %}

{% tab title="500: Internal Server Error Looks like something went wrong! We track these errors automatically, but if the problem persists feel free to contact us. In the meantime, try refreshing." %}

```javascript
{
  "id": "api.questionset.reject",
  "ver": "5.0",
  "ts": "2023-06-29T07:51:03ZZ",
  "params": {
    "resmsgid": "f234a6f0-3ac4-11eb-b0a2-8d5c9f561887",
    "msgid": null,
    "status": "failed",
    "err": null,
    "errmsg": null
  },
  "responseCode": "SERVER_ERROR",
  "result": {}
}
```

{% endtab %}
{% endtabs %}

#### Request Sample

```json
{
  "request": {
    "questionset": {
      "rejectComment": "Rejected for testing"
    }
  }
}
```

#### Request Schema

<table><thead><tr><th>Attribute</th><th width="122">Type</th><th>Description</th><th>Required</th></tr></thead><tbody><tr><td>rejectComment</td><td>String</td><td>Question set rejection comment/reason</td><td>Yes</td></tr></tbody></table>

#### Success result schema

<table><thead><tr><th width="189">Attribute</th><th width="120.33333333333331">Type</th><th>Description</th></tr></thead><tbody><tr><td>identifier</td><td>String</td><td>Unique Question identifier</td></tr><tr><td>versionKey</td><td>String</td><td>Unique version key for question</td></tr></tbody></table>

#### cURL

```shell
curl --location -g --request POST '{{host}}/questionset/v2/reject/{{questionSet_id}}' \
  -H 'Authorization: Bearer {{api_key}}' \
  -H 'Content-Type: application/json' \
  --data-raw '{"request":{"questionset":{"rejectComment":"Not aligned"}}}' \
  --compressed
```


# Publish QuestionSet

This API is used to publish the question set on the Sunbird-inQuiry Platform.

## This API is used to publish the question set on the Sunbird-inQuiry Platform.

<mark style="color:green;">`POST`</mark> `/questionset/v2/publish/{questionSet_id}`

• <mark style="color:orange;">/questionset/v2/publish/{questionSet\_id}</mark> endpoint executes the "Publish QuestionSet" request based on parameters provided as metadata in the request body. \
• It points to inquiry-api-service (assessment service) - <mark style="color:orange;">/questionset/v5/publish/{questionSet\_id}</mark>\
• It is mandatory to provide values for parameters marked with <mark style="color:red;">\*</mark>\
• Mandatory fields cannot be null or empty.\
• <mark style="color:orange;">Asynchronous flink job : async-questionset-publish will takes care of the publishing activity.</mark>

#### Path Parameters

| Name            | Type   | Description                                       |
| --------------- | ------ | ------------------------------------------------- |
| questionSet\_id | String | Append a valid Question Set Id To the Request URL |

#### Headers

| Name                                            | Type   | Description                                                                                                                                                                                                                    |
| ----------------------------------------------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| Content-Type<mark style="color:red;">\*</mark>  | String | The Content-Type entity is the media type of the resource. Possible media types can be: <mark style="color:green;">Application/json</mark>                                                                                     |
| Authorization<mark style="color:red;">\*</mark> | String | <p>All content APIs require authorization for use. Specify the authorization key received from the administrator when placing the request for use of the API.<br>Set <mark style="color:green;">Bearer {{api\_key}}</mark></p> |
| x-channel-id                                    | String | Unique identification number associated with a root organization.                                                                                                                                                              |

#### Request Body

| Name    | Type   | Description                                                                       |
| ------- | ------ | --------------------------------------------------------------------------------- |
| request | Object | The body is the representation of the resource object for publishing question set |

{% tabs %}
{% tab title="200: OK QuestionSet publish operation was successfully executed." %}

```javascript
{
  "id": "api.questionset.publish",
  "ver": "5.0",
  "ts": "2023-06-29T07:51:03ZZ",
  "params": {
    "resmsgid": "62f7e310-39e1-4287-bc9f-f8e6ac5f5bd3",
    "msgid": null,
    "err": null,
    "status": "successful",
    "errmsg": null
  },
  "responseCode": "OK",
  "result": {
    "message": "QuestionSet is successfully sent for Publish",
    "identifier": "do_113208323801554944120"
  }
}
```

{% endtab %}

{% tab title="404: Not Found QuestionSet Send for publish operation failed !The possible reason for failure is that you may have provided wrong questionset id." %}

```javascript
{
  "id": "api.questionset.publish",
  "ver": "5.0",
  "ts": "2023-06-29T07:51:03ZZ",
  "params": {
    "resmsgid": "6fc0bd55-e99e-4ae1-80e2-7275458258ab",
    "msgid": null,
    "err": "NOT_FOUND",
    "status": "failed",
    "errmsg": "Error! Node(s) doesn't Exists. | [Invalid Node Id.]: do_1132084061164175361221"
  },
  "responseCode": "RESOURCE_NOT_FOUND",
  "result": {
    "messages": null
  }
}
```

{% endtab %}

{% tab title="500: Internal Server Error Looks like something went wrong! We track these errors automatically" %}

```javascript
{
  "id": "api.questionset.publish",
  "ver": "5.0",
  "ts": "2023-06-29T07:51:03ZZ",
  "params": {
    "resmsgid": "f234a6f0-3ac4-11eb-b0a2-8d5c9f561887",
    "msgid": null,
    "status": "failed",
    "err": null,
    "errmsg": null
  },
  "responseCode": "SERVER_ERROR",
  "result": {}
}
```

{% endtab %}

{% tab title="400: Bad Request Publish operation failed because of some error in QuestionSet data" %}

```json
{
    "id": "api.questionset.publish",
    "ver": "5.0",
    "ts": "2023-06-29T11:36:09ZZ",
    "params": {
        "resmsgid": "93f72a36-e5ca-4154-86a3-de662a20ecf4",
        "msgid": null,
        "err": "ERR_OBJECT_VALIDATION",
        "status": "failed",
        "errmsg": "No children's found for identifier:do_2138284054041886721542"
    },
    "responseCode": "CLIENT_ERROR",
    "result": {
        "messages": null
    }
}
```

{% endtab %}
{% endtabs %}

#### Request Sample

```json
{
  "request": {
    "questionset": {
      "lastPublishedBy": "ae94b68c-a535-4dce-8e7a-fb9662b0ad68"
    }
  }
}
```

#### Success result schema

<table><thead><tr><th width="183">Attribute</th><th width="141.33333333333331">Type</th><th>Description</th></tr></thead><tbody><tr><td>identifier</td><td>String</td><td>Unique Question identifier</td></tr><tr><td>message</td><td>String</td><td>Publish success message</td></tr></tbody></table>

#### cURL

```shell
curl --location -g --request POST '{{host}}/questionset/v2/publish/{{questionSet_id}}' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer {{api_key}}' \
--header 'X-Channel-Id: {{channel_id}}' \
--data-raw '{
  "request": {
    "questionset": {}
  }
}'
```


# Update Hierarchy QuestionSet

This API is used to update the existing question set on the Sunbird-inQuiry Platform.

## This API is used to update the existing question set on the Sunbird-inQuiry Platform.

<mark style="color:purple;">`PATCH`</mark> `/questionset/v2/hierarchy/update`

• <mark style="color:orange;">/questionset/v2/hierarchy/update/</mark> endpoint executes the "Update Hierarchy QuestionSet" request based on parameters provided as metadata in the request body.\
•This API is used to add new children and update the existing children or update a hierarchical structure of the question set.\
• It points to inquiry-api-service (assessment service) - <mark style="color:orange;">/questionset/v5/hierarchy/update</mark> \
• It is mandatory to provide values for parameters marked with <mark style="color:red;">\*</mark>\
• Mandatory fields cannot be null or empty.

#### Headers

| Name                                            | Type   | Description                                                                                                                                                                                                                     |
| ----------------------------------------------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Content-Type<mark style="color:red;">\*</mark>  | String | The Content Type entity is the media type of the resource.Possible media types can be: <mark style="color:green;">Application/json</mark>                                                                                       |
| Authorization<mark style="color:red;">\*</mark> | String | <p>All question APIs require authorization for use. Specify the authorization key received from the administrator when placing the request for use of the API.<br>Set <mark style="color:green;">Bearer {{api\_key}}</mark></p> |
| x-channel-id                                    | String | Unique identification number associated with a root organization.                                                                                                                                                               |

#### Request Body

| Name                                      | Type   | Description                                                             |
| ----------------------------------------- | ------ | ----------------------------------------------------------------------- |
| request<mark style="color:red;">\*</mark> | Object | It contains metadata and a hierarchy of the question set to be updated. |

{% tabs %}
{% tab title="200: OK QuestionSet update hierarchy operation was successfuly executed." %}

```javascript
{
  "id": "api.questionset.hierarchy.update",
  "ver": "5.0",
  "ts": "2023-06-29T07:51:03ZZ",
  "params": {
    "resmsgid": "221f9cdb-c220-4d3f-a579-4e7b82facf89",
    "msgid": null,
    "err": null,
    "status": "successful",
    "errmsg": null
  },
  "responseCode": "OK",
  "result": {
    "identifier": "do_113208431570984960123",
    "identifiers": {
      "section-1": "do_113208433229889536126",
      "question-1": "do_113208433229873152124"
    }
  }
}
```

{% endtab %}

{% tab title="400: Bad Request The 'Update Hierarchy QuestionSet' operation failed ! The possible reason for failure is that you may have missed providing input for a mandatory parameter." %}

```javascript
{
  "id": "api.questionset.hierarchy.update",
  "ver": "5.0",
  "ts": "2023-06-29T07:51:03ZZ",
  "params": {
    "resmsgid": "04e218fc-76bc-4fd3-b98d-5ed947a30b8b",
    "msgid": null,
    "err": "ERR_QS_UPDATE_HIERARCHY",
    "status": "failed",
    "errmsg": "Question cannot have children in hierarchy"
  },
  "responseCode": "CLIENT_ERROR",
  "result": {
    "messages": null
  }
}
```

{% endtab %}

{% tab title="404: Not Found QuestionSet Update Hierarchy operation failed !The possible reason for failure is that you may have provided wrong questionset id." %}

```javascript
{
  "id": "api.questionset.hierarchy.update",
  "ver": "5.0",
  "ts": "2023-06-29T07:51:03ZZ",
  "params": {
    "resmsgid": "0fbe77de-a612-4406-bcd2-a63de5b29b6d",
    "msgid": null,
    "err": "NOT_FOUND",
    "status": "failed",
    "errmsg": "Error! Node(s) doesn't Exists. | [Invalid Node Id.]: do_1132084315709849601231"
  },
  "responseCode": "RESOURCE_NOT_FOUND",
  "result": {
    "messages": null
  }
}
```

{% endtab %}

{% tab title="500: Internal Server Error Looks like something went wrong! These errors are tracked automatically" %}

```javascript
{
  "id": "api.questionset.hierarchy.update",
  "ver": "5.0",
  "ts": "2023-06-29T07:51:03ZZ",
  "params": {
    "resmsgid": "f234a6f0-3ac4-11eb-b0a2-8d5c9f561887",
    "msgid": null,
    "status": "failed",
    "err": null,
    "errmsg": null
  },
  "responseCode": "SERVER_ERROR",
  "result": {}
}
```

{% endtab %}
{% endtabs %}

#### Request Sample

```json
{
  "request": {
    "data": {
      "nodesModified": {
        "ad6f06e4-1a36-47c2-964a-91c249191e4b": {
          "metadata": {
            "mimeType": "application/vnd.sunbird.question",
            "media": [],
            "editorState": {
              "options": [
                {
                  "answer": true,
                  "value": {
                    "body": "<p>4</p>",
                    "value": 0
                  }
                },
                {
                  "answer": false,
                  "value": {
                    "body": "<p>8</p>",
                    "value": 1
                  }
                }
              ],
              "question": "<p>2+2=?</p>"
            },
            "templateId": "mcq-vertical",
            "answer": "<div class='anwser-container'><div class='anwser-body'><p>4</p></div></div>",
            "complexityLevel": [
              "evaluate"
            ],
            "maxScore": 1,
            "name": "MCQ-1",
            "responseDeclaration": {
              "response1": {
                "cardinality": "single",
                "type": "integer",
                "correctResponse": {
                  "value": 0
                },
                "mapping": [
                  {
                    "value": 0,
                    "score": 1
                  }
                ]
              }
            },
            "outcomeDeclaration": {
              "maxScore": {
                "cardinality": "single",
                "type": "integer",
                "defaultValue": 1
              }
            },
            "interactionTypes": [
              "choice"
            ],
            "interactions": {
              "response1": {
                "type": "choice",
                "options": [
                  {
                    "label": "<p>4</p>",
                    "value": 0
                  },
                  {
                    "label": "<p>8</p>",
                    "value": 1
                  }
                ],
                "validation": {
                  "required": "Yes"
                }
              }
            },
            "qType": "MCQ",
            "primaryCategory": "Multiple Choice Question",
            "body": "<div class='question-body' tabindex='-1'><div class='mcq-title' tabindex='0'><p>2+2=?</p></div><div data-choice-interaction='response1' class='mcq-vertical'></div></div>",
            "solutions": {},
            "createdBy": "5a587cc1-e018-4859-a0a8-e842650b9d64",
            "board": "CBSE",
            "medium": [
              "English"
            ],
            "gradeLevel": [
              "Class 1"
            ],
            "subject": [
              "Math"
            ],
            "author": "Creator1",
            "channel": "01309282781705830427",
            "framework": "inquiry_k-12",
            "copyright": "NIT123",
            "audience": [
              "Student"
            ],
            "license": "CC BY 4.0"
          },
          "objectType": "Question",
          "root": false,
          "isNew": true
        }
      },
      "hierarchy": {
        "do_2138281786908098561515": {
          "name": "G-QS-1",
          "children": [
            "do_2138281798916177921516"
          ],
          "root": true
        },
        "do_2138281798916177921516": {
          "name": "Simple Calculation",
          "children": [
            "ad6f06e4-1a36-47c2-964a-91c249191e4b"
          ],
          "root": false
        }
      }
    }
  }
}
```

#### Request Shema

<table><thead><tr><th width="169">Attribute</th><th width="87">Type</th><th width="344">Description</th><th>Required</th></tr></thead><tbody><tr><td>nodesModified</td><td>Object</td><td>objects details to be created or updated</td><td>Yes</td></tr><tr><td>hierarchy</td><td>Object</td><td>objects hierarchy details</td><td>Yes</td></tr></tbody></table>

#### Success result schema

<table><thead><tr><th width="164">Attribute</th><th width="136.33333333333331">Type</th><th>Description</th></tr></thead><tbody><tr><td>identidier</td><td>String</td><td>Unique Question identifier</td></tr><tr><td>identifiers</td><td>String</td><td>Object mapping i.e. created or updated</td></tr></tbody></table>

#### cURL

```shell
curl --location -g --request PATCH '{{host}}/questionset/v2/hierarchy/update' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer {{api_key}}' \
--data-raw '{"request":{"data":{"nodesModified":{"ad6f06e4-1a36-47c2-964a-91c249191e4b":{"metadata":{"mimeType":"application/vnd.sunbird.question","media":[],"editorState":{"options":[{"answer":true,"value":{"body":"<p>4</p>","value":0}},{"answer":false,"value":{"body":"<p>8</p>","value":1}}],"question":"<p>2+2=?</p>"},"templateId":"mcq-vertical","answer":"<div class=\'anwser-container\'><div class=\'anwser-body\'><p>4</p></div></div>","complexityLevel":["evaluate"],"maxScore":1,"name":"MCQ-1","responseDeclaration":{"response1":{"cardinality":"single","type":"integer","correctResponse":{"value":0},"mapping":[{"value":0,"score":1}]}},"outcomeDeclaration":{"maxScore":{"cardinality":"single","type":"integer","defaultValue":1}},"interactionTypes":["choice"],"interactions":{"response1":{"type":"choice","options":[{"label":"<p>4</p>","value":0},{"label":"<p>8</p>","value":1}],"validation":{"required":"Yes"}}},"qType":"MCQ","primaryCategory":"Multiple Choice Question","body":"<div class=\'question-body\' tabindex=\'-1\'><div class=\'mcq-title\' tabindex=\'0\'><p>2+2=?</p></div><div data-choice-interaction=\'response1\' class=\'mcq-vertical\'></div></div>","solutions":{},"createdBy":"5a587cc1-e018-4859-a0a8-e842650b9d64","board":"CBSE","medium":["English"],"gradeLevel":["Class 1"],"subject":["Math"],"author":"Creator1","channel":"01309282781705830427","framework":"inquiry_k-12","copyright":"NIT123","audience":["Student"],"license":"CC BY 4.0"},"objectType":"Question","root":false,"isNew":true}},"hierarchy":{"do_2138281786908098561515":{"name":"G-QS-1","children":["do_2138281798916177921516"],"root":true},"do_2138281798916177921516":{"name":"Simple Calculation","children":["ad6f06e4-1a36-47c2-964a-91c249191e4b"],"root":false}}}}}' \
--compressed
```

**Complete example**

The following request is for updating the existing question set. Here, a new question (MCQ) is added to one of the sections of the question set.

```json
{
  "request": {
    "data": {
      "nodesModified": {
        "ad6f06e4-1a36-47c2-964a-91c249191e4b": {
          "metadata": {
            "mimeType": "application/vnd.sunbird.question",
            "media": [],
            "editorState": {
              "options": [
                {
                  "answer": true,
                  "value": {
                    "body": "<p>4</p>",
                    "value": 0
                  }
                },
                {
                  "answer": false,
                  "value": {
                    "body": "<p>8</p>",
                    "value": 1
                  }
                }
              ],
              "question": "<p>2+2=?</p>"
            },
            "templateId": "mcq-vertical",
            "answer": "<div class='anwser-container'><div class='anwser-body'><p>4</p></div></div>",
            "complexityLevel": [
              "evaluate"
            ],
            "maxScore": 1,
            "name": "MCQ-1",
            "responseDeclaration": {
              "response1": {
                "cardinality": "single",
                "type": "integer",
                "correctResponse": {
                  "value": 0
                },
                "mapping": [
                  {
                    "value": 0,
                    "score": 1
                  }
                ]
              }
            },
            "outcomeDeclaration": {
              "maxScore": {
                "cardinality": "single",
                "type": "integer",
                "defaultValue": 1
              }
            },
            "interactionTypes": [
              "choice"
            ],
            "interactions": {
              "response1": {
                "type": "choice",
                "options": [
                  {
                    "label": "<p>4</p>",
                    "value": 0
                  },
                  {
                    "label": "<p>8</p>",
                    "value": 1
                  }
                ],
                "validation": {
                  "required": "Yes"
                }
              }
            },
            "qType": "MCQ",
            "primaryCategory": "Multiple Choice Question",
            "body": "<div class='question-body' tabindex='-1'><div class='mcq-title' tabindex='0'><p>2+2=?</p></div><div data-choice-interaction='response1' class='mcq-vertical'></div></div>",
            "solutions": {},
            "createdBy": "5a587cc1-e018-4859-a0a8-e842650b9d64",
            "board": "CBSE",
            "medium": [
              "English"
            ],
            "gradeLevel": [
              "Class 1"
            ],
            "subject": [
              "Math"
            ],
            "author": "Creator1",
            "channel": "01309282781705830427",
            "framework": "inquiry_k-12",
            "copyright": "NIT123",
            "audience": [
              "Student"
            ],
            "license": "CC BY 4.0"
          },
          "objectType": "Question",
          "root": false,
          "isNew": true
        }
      },
      "hierarchy": {
        "do_2138281786908098561515": {
          "name": "G-QS-1",
          "children": [
            "do_2138281798916177921516"
          ],
          "root": true
        },
        "do_2138281798916177921516": {
          "name": "Simple Calculation",
          "children": [
            "ad6f06e4-1a36-47c2-964a-91c249191e4b"
          ],
          "root": false
        }
      }
    }
  }
}
```

<br>


# Read QuestionSet Hierarchy

This API is used to read the question set on the Sunbird-inQuiry Platform.

## This API is used to read the question set on the Sunbird-inQuiry Platform.

<mark style="color:blue;">`GET`</mark> `/questionset/v2/hierarchy/{questionSet_id}`

• The <mark style="color:orange;">/questionset/v2/hierarchy/{questionSet\_id}</mark> endpoint executes a request for fetching the question set hierarchical structure. \
• By default, this API tries to fetch a question set with live status. If you need to fetch the hierarchy of qustion set having any other status please use mode=edit query parameter.\
• The endpoint for reading QuestionSet Hierarchy is <mark style="color:orange;">/questionset/v2/hierarchy</mark> \
• It points to inquiry-api-service (assessment service) - <mark style="color:orange;">/questionset/v5/hierarchy</mark> \
• You need to provide a valid QuestionSet Id value in {questionSet\_id<mark style="color:orange;">}</mark> field of the API URL. \
• It is mandatory to provide values for parameters marked with <mark style="color:red;">\*</mark>\
• Mandatory fields cannot be null or empty.

#### Path Parameters

| Name                                              | Type   | Description                                             |
| ------------------------------------------------- | ------ | ------------------------------------------------------- |
| questionSet\_id<mark style="color:red;">\*</mark> | String | Please append a valid QuestionSet Id to the Request URL |

#### Query Parameters

| Name      | Type   | Description                                                                                |
| --------- | ------ | ------------------------------------------------------------------------------------------ |
| mode=edit | String | To fetch the latest version of a questionSet hierarchy from the Database for edit purposes |

#### Headers

| Name                                            | Type   | Description                                                                                                                                                                                                                                                    |
| ----------------------------------------------- | ------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Content-Type                                    | String | The Content-Type entity is the media type of the resource. Possible media types can be: <mark style="color:green;">Application/json</mark>                                                                                                                     |
| Authorization<mark style="color:red;">\*</mark> | String | <p>To make use of the API, you require authorization. Raise a request to the administrator for the use of the API. You will receive the authorization key. Specify the key received, here.</p><p>Set <mark style="color:green;">Bearer {{api\_key}}</mark></p> |
| x-channel-id                                    | String | Unique identification number associated with a root organization.                                                                                                                                                                                              |

{% tabs %}
{% tab title="200: OK "Read QuestionSet Hierarchy" operation was successfully executed" %}

```json
{
    "id": "api.questionset.hierarchy.get",
    "ver": "5.0",
    "ts": "2023-06-29T12:03:38ZZ",
    "params": {
        "resmsgid": "a8368ba1-3246-4f69-8ba6-f37ef0605885",
        "msgid": null,
        "err": null,
        "status": "successful",
        "errmsg": null
    },
    "responseCode": "OK",
    "result": {
        "questionset": {
            "copyright": "NIT123",
            "subject": [
                "Math"
            ],
            "channel": "01309282781705830427",
            "language": [
                "English"
            ],
            "mimeType": "application/vnd.sunbird.questionset",
            "showHints": false,
            "objectType": "QuestionSet",
            "gradeLevel": [
                "Class 1"
            ],
            "appIcon": "",
            "primaryCategory": "Practice Question Set",
            "children": [
                {
                    "parent": "do_2138281786908098561515",
                    "instructions": "<p>Sample Instruction</p>",
                    "code": "802700d6-c6bd-4c5d-97e9-6010b4530e13",
                    "allowSkip": "Yes",
                    "containsUserData": "No",
                    "qumlVersion": 1.1,
                    "channel": "01309282781705830427",
                    "description": "Simple Calculation",
                    "language": [
                        "English"
                    ],
                    "mimeType": "application/vnd.sunbird.questionset",
                    "showHints": false,
                    "createdOn": "2023-06-29T03:44:00.676+0000",
                    "objectType": "QuestionSet",
                    "scoreCutoffType": "AssessmentLevel",
                    "primaryCategory": "Practice Question Set",
                    "children": [
                        {
                            "parent": "do_2138281798916177921516",
                            "copyright": "NIT123",
                            "code": "ad6f06e4-1a36-47c2-964a-91c249191e4b",
                            "subject": [
                                "Math"
                            ],
                            "qumlVersion": 1.1,
                            "channel": "01309282781705830427",
                            "language": [
                                "English"
                            ],
                            "medium": [
                                "English"
                            ],
                            "mimeType": "application/vnd.sunbird.question",
                            "showHints": false,
                            "templateId": "mcq-vertical",
                            "createdOn": "2023-06-29T03:45:06.917+0000",
                            "objectType": "Question",
                            "gradeLevel": [
                                "Class 1"
                            ],
                            "primaryCategory": "Multiple Choice Question",
                            "contentDisposition": "inline",
                            "lastUpdatedOn": "2023-06-29T03:45:06.917+0000",
                            "contentEncoding": "gzip",
                            "showSolutions": false,
                            "allowAnonymousAccess": "Yes",
                            "identifier": "do_2138281804342640641518",
                            "lastStatusChangedOn": "2023-06-29T03:45:06.917+0000",
                            "audience": [
                                "Student"
                            ],
                            "schemaVersion": "1.1",
                            "visibility": "Parent",
                            "showTimer": false,
                            "author": "Creator1",
                            "index": 1,
                            "qType": "MCQ",
                            "maxScore": 1,
                            "languageCode": [
                                "en"
                            ],
                            "versionKey": "1688010307002",
                            "showFeedback": false,
                            "license": "CC BY 4.0",
                            "complexityLevel": [
                                "evaluate"
                            ],
                            "interactionTypes": [
                                "choice"
                            ],
                            "framework": "inquiry_k-12",
                            "depth": 2,
                            "createdBy": "5a587cc1-e018-4859-a0a8-e842650b9d64",
                            "compatibilityLevel": 5,
                            "name": "MCQ-1",
                            "board": "CBSE",
                            "status": "Draft"
                        }
                    ],
                    "contentDisposition": "inline",
                    "lastUpdatedOn": "2023-06-29T03:44:00.676+0000",
                    "contentEncoding": "gzip",
                    "generateDIALCodes": "No",
                    "showSolutions": true,
                    "trackable": {
                        "enabled": "No",
                        "autoBatch": "No"
                    },
                    "allowAnonymousAccess": "Yes",
                    "identifier": "do_2138281798916177921516",
                    "lastStatusChangedOn": "2023-06-29T03:44:00.676+0000",
                    "schemaVersion": "1.1",
                    "requiresSubmit": "No",
                    "visibility": "Parent",
                    "showTimer": false,
                    "index": 1,
                    "setType": "materialised",
                    "languageCode": [
                        "en"
                    ],
                    "versionKey": "1688010240676",
                    "showFeedback": true,
                    "license": "CC BY 4.0",
                    "depth": 1,
                    "compatibilityLevel": 6,
                    "name": "Simple Calculation",
                    "navigationMode": "non-linear",
                    "allowBranching": "No",
                    "timeLimits": {
                        "questionSet": {
                            "max": 0,
                            "min": 0
                        }
                    },
                    "shuffle": true,
                    "attributions": [],
                    "status": "Draft"
                }
            ],
            "contentEncoding": "gzip",
            "generateDIALCodes": "No",
            "showSolutions": false,
            "trackable": {
                "enabled": "No",
                "autoBatch": "No"
            },
            "identifier": "do_2138281786908098561515",
            "audience": [
                "Student"
            ],
            "visibility": "Default",
            "showTimer": true,
            "author": "Creator1",
            "consumerId": "6968004d-c67e-434a-a350-773aa1e068a3",
            "childNodes": [
                "do_2138281804342640641518",
                "do_2138281798916177921516"
            ],
            "languageCode": [
                "en"
            ],
            "license": "CC BY 4.0",
            "name": "G-QS-1",
            "allowBranching": "No",
            "status": "Draft",
            "code": "7d5aaa70-ffb8-d062-ba10-1db445a11dbc",
            "allowSkip": "Yes",
            "containsUserData": "No",
            "qumlVersion": 1.1,
            "description": "Sample QuestionSet",
            "medium": [
                "English"
            ],
            "createdOn": "2023-06-29T03:41:34.176+0000",
            "scoreCutoffType": "AssessmentLevel",
            "contentDisposition": "inline",
            "lastUpdatedOn": "2023-06-29T03:45:07.108+0000",
            "allowAnonymousAccess": "Yes",
            "lastStatusChangedOn": "2023-06-29T03:41:34.176+0000",
            "createdFor": [
                "01309282781705830427"
            ],
            "schemaVersion": "1.1",
            "requiresSubmit": "No",
            "setType": "materialised",
            "versionKey": "1688010307108",
            "showFeedback": false,
            "framework": "inquiry_k-12",
            "depth": 0,
            "createdBy": "5a587cc1-e018-4859-a0a8-e842650b9d64",
            "compatibilityLevel": 6,
            "navigationMode": "non-linear",
            "timeLimits": {
                "questionSet": {
                    "max": 900,
                    "min": 0
                }
            },
            "shuffle": true,
            "board": "CBSE"
        }
    }
}
```

{% endtab %}

{% tab title="404: Not Found QuestionSet Read Hierarchy operation failed !The possible reason for failure is that you may have provided wrong question id or the questionset is not published." %}

```javascript
{
  "id": "api.questionset.hierarchy.get",
  "ver": "5.0",
  "ts": "2023-06-29T07:51:03ZZ",
  "params": {
    "resmsgid": "db5bcf74-d151-46f5-85b1-8512053923cb",
    "msgid": null,
    "err": "RESOURCE_NOT_FOUND",
    "status": "failed",
    "errmsg": "rootId do_113208431570984960123 does not exist"
  },
  "responseCode": "RESOURCE_NOT_FOUND",
  "result": {}
}
```

{% endtab %}

{% tab title="500: Internal Server Error Looks like something went wrong! These errors are tracked automatically" %}

```javascript
{
  "id": "api.questionset.hierarchy.read",
  "ver": "5.0",
  "ts": "2023-06-29T07:51:03ZZ",
  "params": {
    "resmsgid": "f234a6f0-3ac4-11eb-b0a2-8d5c9f561887",
    "msgid": null,
    "status": "failed",
    "err": null,
    "errmsg": null
  },
  "responseCode": "SERVER_ERROR",
  "result": {}
}
```

{% endtab %}
{% endtabs %}

#### Success result schema

<table><thead><tr><th width="219">Attribute</th><th width="425.3333333333333">Description</th><th>Type</th></tr></thead><tbody><tr><td>identifier</td><td>Questionset Identifier</td><td>string</td></tr><tr><td>name</td><td>Questionset name</td><td>string</td></tr><tr><td>versionKey</td><td>Questionset versionKey</td><td>string</td></tr><tr><td>code</td><td>Questionset code</td><td>string</td></tr><tr><td>lastStatusChangedOn</td><td>Last status changed time</td><td>string</td></tr><tr><td>visibility</td><td>Questionset visibility (eg. Parent/Default)</td><td>string</td></tr><tr><td>mimeType</td><td>Questionset mimeType (eg. application/vnd.sunbird.questionset)</td><td>string</td></tr><tr><td>createdOn</td><td>Questionset createtion timestamp</td><td>string</td></tr><tr><td>objectType</td><td>Questionset objectType (eg. QuestionSet)</td><td>string</td></tr><tr><td>primaryCategory</td><td>Questionset primaryCategory (eg. Practice Question Set)</td><td>string</td></tr><tr><td>lastUpdatedOn</td><td>Questionset last updated timestamp</td><td>string</td></tr><tr><td>status</td><td>Questionset status (eg. Draft/Live)</td><td>string</td></tr><tr><td>children</td><td>Children of Questionset, mostly sections or questions</td><td>Object</td></tr><tr><td></td><td></td><td></td></tr></tbody></table>

#### cURL

```shell
curl --location -g --request GET '{{host}}/questionset/v2/hierarchy/{{questionSet_id}}' \
--header 'Authorization: Bearer {{api_key}}'
```


# Import QuestionSet

This API is used to import QuestionSet from one instance of sunbird to another instance of sunbird.

## This API is used to import QuestionSet from one instance of sunbird to another instance of sunbird.

<mark style="color:green;">`POST`</mark> `/questionset/v2/import`

• The endpoint for **Import QuestionSet** is <mark style="color:orange;">/questionset/v2/import</mark>\
• It points to inquiry-api-service (assessment service) - <mark style="color:orange;">/questionset/v5/import</mark> \
• All parameters marked with <mark style="color:red;">\*</mark> are mandatory. You must provide values for these parameters. \
• Mandatory fields cannot be null or empty.

#### Path Parameters

| Name                                            | Type   | Description                                                                                                                                                                                                                                                |
| ----------------------------------------------- | ------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Content-Type<mark style="color:red;">\*</mark>  | String | The Content-Type entity is the media type of the resource. The possible media types can be: <mark style="color:green;">Application/json</mark>                                                                                                             |
| Authorization<mark style="color:red;">\*</mark> | String | <p>You require authorization to make use of the API. Raise a request to the administrator for the use of the API. You will receive the authorization key. Specify the key received, here.<br>Set <mark style="color:green;">Bearer {{api\_key}}</mark></p> |
| x-channel-id                                    | String | Unique identification number associated with a root organization.                                                                                                                                                                                          |

#### Request Body

| Name                                      | Type   | Description                                                                        |
| ----------------------------------------- | ------ | ---------------------------------------------------------------------------------- |
| request<mark style="color:red;">\*</mark> | Object | The body is the representation of the resource object for importing a question set |

{% tabs %}
{% tab title="200: OK The Import QuestionSet operation was successful!" %}

```javascript
{
  "id": "api.questionset.import",
  "ver": "5.0",
  "ts": "2023-06-29T07:51:03ZZ",
  "params": {
    "resmsgid": "7cce8934-0a2f-46bf-a0ee-be5f49874cae",
    "msgid": null,
    "err": null,
    "status": "successful"2
    "errmsg": null
  },
  "responseCode": "OK",
  "result": {
    "processId": "80a765c7-2202-4b3f-b473-448b5c2cd20e"
  }
}
```

{% endtab %}

{% tab title="400: Bad Request The Import QuestionSet operation failed. You may have missed providing input for a mandatory parameter.'" %}

```javascript
{
  "id": "api.questionset.import",
  "ver": "5.0",
  "ts": "2023-06-29T07:51:03ZZ",
  "params": {
    "resmsgid": "31f88a39-2514-4d86-b424-240166e315be"
  },
  "msgid": null,
  "err": "ERR_REQUIRED_PROPS_VALIDATION",
  "status": "failed",
  "errmsg": "Validation Failed! Mandatory Properties Are [name, code, mimeType, primaryCategory, framework]",
  "responseCode": "CLIENT_ERROR",
  "result": {
    "messages": null
  }
}
```

{% endtab %}

{% tab title="500: Internal Server Error We track these errors automatically and try to set it right at the earliest." %}

```javascript
{
  "id": "api.question.import",
  "ver": "5.0",
  "ts": "2023-06-29T07:51:03ZZ",
  "params": {
    "resmsgid": "f234a6f0-3ac4-11eb-b0a2-8d5c9f561887",
    "msgid": null,
    "status": "failed",
    "err": null,
    "errmsg": null
  },
  "responseCode": "SERVER_ERROR",
  "result": {}
}
```

{% endtab %}
{% endtabs %}

#### Sample Request

```json
{
  "request": {
    "questionset": [
      {
        "source": "https://dock.sunbirded.org/api/questionset/v2/read/do_1132613027022684161119",
        "metadata": {
          "framework": "ekstep_ncert_k-12",
          "channel": "01309282781705830427",
          "name": "QustionSet-1",
          "code": "9ae33d1e-a682-f30c-04b5-9bda236650ac",
          "lastPublishedBy": "5a587cc1-e018-4859-a0a8-e842650b9d64"
        },
        "collection": [
          {
            "identifier": "do_11324642736155033614",
            "unitId": "do_11324642761348710417"
          }
        ]
      }
    ]
  }
}
```

#### Request schema

<table><thead><tr><th width="139.33333333333331">Attribute</th><th width="486">Description</th><th>Type</th></tr></thead><tbody><tr><td>source</td><td>Represents the source of questionset object</td><td>string</td></tr><tr><td>metadata</td><td>Represents the additional metadata for the questionset object</td><td>Object</td></tr><tr><td>collection</td><td>Represents the collection with which Questionset can be linked.</td><td>Array of strings</td></tr></tbody></table>

#### Success result schema

| Attribute | Type   | Description       |
| --------- | ------ | ----------------- |
| processId | String | Unique process ID |

**cURL**

```
curl --location -g --request POST '{{host}}/questionset/v2/import' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer {{api_key}}' \
--header 'X-Channel-Id: {{channel_id}}' \
--data-raw '{
  "request": {
    "questionset": [
      {
        "source": "https://dock.sunbirded.org/api/questionset/v2/read/do_1132613027022684161119",
        "metadata": {
          "framework": "ekstep_ncert_k-12",
          "channel": "01309282781705830427",
          "name": "QustionSet-1",
          "code": "9ae33d1e-a682-f30c-04b5-9bda236650ac",
          "lastPublishedBy": "5a587cc1-e018-4859-a0a8-e842650b9d64"
        },
        "collection": [
          {
            "identifier": "do_11324642736155033614",
            "unitId": "do_11324642761348710417"
          }
        ]
      }
    ]
  }
}'
```


# Copy QuestionSet

This API is associated with copying questionset on the Sunbird Platform.

## This API is associated with copying questionset on the Sunbird Platform.

<mark style="color:green;">`POST`</mark> `/questionset/v2/copy/{questionSet_id}`

• The endpoint for **Copy QuestionSet** is <mark style="color:orange;">/questionset/v2/copy</mark>\
• It points to inquiry-api-service (assessment service) - <mark style="color:orange;">/questionset/v5/copy</mark> \
• You need to provide a valid Question Set Id value in <mark style="color:orange;">{questionSet\_id}</mark> field of the API URL.\
• All parameters marked with <mark style="color:red;">\*</mark> are mandatory. You must provide values for these parameters. \
• Mandatory fields cannot be null or empty.

#### Path Parameters

| Name                                              | Type   | Description                                      |
| ------------------------------------------------- | ------ | ------------------------------------------------ |
| questionSet\_id<mark style="color:red;">\*</mark> | String | Append a valid QuestionSet Id to the Request URL |

#### Headers

| Name                                            | Type   | Description                                                                                                                                                                                                                                                |
| ----------------------------------------------- | ------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Content-Type<mark style="color:red;">\*</mark>  | String | The Content-Type entity is the media type of the resource. The possible media types can be: <mark style="color:green;">Application/json</mark>                                                                                                             |
| Authorization<mark style="color:red;">\*</mark> | String | <p>You require authorization to make use of the API. Raise a request to the administrator for the use of the API. You will receive the authorization key. Specify the key received, here.<br>Set <mark style="color:green;">Bearer {{api\_key}}</mark></p> |
| x-channel-id                                    | String | Unique identification number associated with a root organisation.                                                                                                                                                                                          |

#### Request Body

| Name                                      | Type   | Description                                                                        |
| ----------------------------------------- | ------ | ---------------------------------------------------------------------------------- |
| request<mark style="color:red;">\*</mark> | Object | The body is the representation of the resource object for importing a question set |

{% tabs %}
{% tab title="200: OK The Copy QuestionSet operation was successful!" %}

```javascript
{
    "id": "api.questionset.copy",
    "ver": "5.0",
    "ts": "2023-06-29T07:51:03ZZ",
    "params": {
        "resmsgid": "8bba3dda-f81e-4659-8c05-55caed20d174",
        "msgid": null,
        "err": null,
        "status": "successful",
        "errmsg": null
    },
    "responseCode": "OK",
    "result": {
        "node_id": {
            "do_2138240203066900481600": "do_2138240204082216961601"
        },
        "versionKey": "1687502491400"
    }
}
```

{% endtab %}

{% tab title="400: Bad Request The Copy QuestionSet operation failed. You may have missed providing input for a mandatory parameter.'" %}

```javascript
{
    "id": "api.questionset.copy",
    "ver": "5.0",
    "ts": "2023-06-29T07:51:03ZZ",
    "params": {
        "resmsgid": "2ea62aa3-f2a9-4aeb-86f0-9d648591d1f2",
        "msgid": null,
        "err": "ERR_BAD_REQUEST",
        "status": "failed",
        "errmsg": "Hierarchy data is empty"
    },
    "responseCode": "CLIENT_ERROR",
    "result": {
        "messages": null
    }
}
```

{% endtab %}

{% tab title="500: Internal Server Error We track these errors automatically and try to set it right at the earliest." %}

```javascript
{
  "id": "api.questionset.copy",
  "ver": "5.0",
  "ts": "2023-06-29T07:51:03ZZ",
  "params": {
    "resmsgid": "f234a6f0-3ac4-11eb-b0a2-8d5c9f561887",
    "msgid": null,
    "status": "failed",
    "err": null,
    "errmsg": null
  },
  "responseCode": "SERVER_ERROR",
  "result": {}
}
```

{% endtab %}

{% tab title="404: Not Found The Copy QuestionSet operation failed. You may have requested a resource that is not existing in the server.'" %}

```json
{
  "id": "api.questionset.copyjs",
  "ver": "5.0",
  "ts": "2023-06-29T07:51:03ZZ",
  "params": {
    "resmsgid": "6fc0bd55-e99e-4ae1-80e2-7275458258ab",
    "msgid": null,
    "err": "NOT_FOUND",
    "status": "failed",
    "errmsg": "Error! Node(s) doesn't Exists. | [Invalid Node Id.]: do_1132084061164175361221"
  },
  "responseCode": "RESOURCE_NOT_FOUND",
  "result": {
    "messages": null
  }
}
```

{% endtab %}
{% endtabs %}

#### Sample Request

```json
{
  "request": {
    "questionset": {
      "createdBy": "User001",
      "createdFor": [
        "Sunbird"
      ],
      "name": "Sunbird-QS"
    }
  }
}
```

#### Request schema

<table><thead><tr><th width="139.33333333333331">Attribute</th><th width="486">Description</th><th>Type</th></tr></thead><tbody><tr><td>createdBy</td><td>Represents the the user who triggered the copy operation</td><td>string</td></tr><tr><td>createdFor</td><td>Represents the organization on behalf the request was triggered</td><td>Object</td></tr><tr><td>name</td><td>Represents the collection with which Questionset can be copied.</td><td>string</td></tr></tbody></table>

#### Success result schema

| Attribute | Type            | Description               |
| --------- | --------------- | ------------------------- |
| node\_id  | Array of Object | Node Ids that were copied |

**cURL**

```
curl --location -g --request POST '{{host}}/questionset/v2/copy/{questionSet_id}' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer {{api_key}}' \
--header 'X-Channel-Id: {{channel_id}}' \
--data-raw '{
  "request": {
    "questionset": {
      "createdBy": "User001",
      "createdFor": [
        "Sunbird"
      ],
      "name": "Sunbird-QS"
    }
  }
}'
```


# Retire QuestionSet

This API is used to retire the question set on the Sunbird-inQuiry Platform.

## This API is used to retire the question set on the Sunbird-inQuiry Platform.

<mark style="color:red;">`DELETE`</mark> `/questionset/v2/retire/{questionSet_id}`

• The <mark style="color:orange;">/questionset/v2/retire/{questionSet\_id}</mark> endpoint executes a "Retire QuestionSet" request based on <mark style="color:orange;">QuestionSet\_Id</mark> to delete the specific Question set.\
•  It points to inquiry-api-service (assessment service) - <mark style="color:orange;">/questionset/v5/retire/{questionSet\_id}</mark>\
• It is mandatory to provide values for parameters. \
• Mandatory fields cannot be null or empty.

#### Path Parameters

| Name                                              | Type   | Description                                             |
| ------------------------------------------------- | ------ | ------------------------------------------------------- |
| questionSet\_id<mark style="color:red;">\*</mark> | String | Please append a valid QuestionSet Id to the Request URL |

#### Headers

| Name                                            | Type   | Description                                                                                                                                                                                                                        |
| ----------------------------------------------- | ------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Authorization<mark style="color:red;">\*</mark> | String | <p>All questionset APIs require authorization for use. Specify the authorization key received from the administrator when placing the request for use of the API.<br>Set <mark style="color:green;">Bearer {{api\_key}}</mark></p> |
| x-channel-id                                    | String | Unique identification number associated with a root organization.                                                                                                                                                                  |

#### Request Body

| Name    | Type   | Description                                                                       |
| ------- | ------ | --------------------------------------------------------------------------------- |
| request | Object | The body is the representation of the resource object for retiring a question set |

{% tabs %}
{% tab title="200: OK QuestionSet deletion operation was successfully executed." %}

```javascript
{
  "id": "api.questionset.retire",
  "ver": "5.0",
  "ts": "2023-06-29T07:51:03ZZ",
  "params": {
    "resmsgid": "98c9f97d-f9d6-4da9-be88-2852294c2aaa",
    "msgid": null,
    "err": null,
    "status": "successful",
    "errmsg": null
  },
  "responseCode": "OK",
  "result": {
    "identifier": "do_113207939069968384112",
    "versionKey": "1612297249754"
  }
}
```

{% endtab %}

{% tab title="400: Bad Request QuestionSet is already retired." %}

```javascript
{
  "id": "api.questionset.retire",
  "ver": "5.0",
  "ts": "2023-06-29T07:51:03ZZ",
  "params": {
    "resmsgid": "0608b59d-dfb9-4c0e-807f-1a19c9a163fe",
    "msgid": null,
    "err": "ERR_QUESTION_RETIRE",
    "status": "failed",
    "errmsg": "QuestionSet with identifier : do_113207939069968384112 is already Retired."
  },
  "responseCode": "CLIENT_ERROR",
  "result": {
    "messages": null
  }
}
```

{% endtab %}

{% tab title="404: Not Found QuestionSet Send for Retire operation failed! The possible reason for failure is that you may have provided wrong questionset id." %}

```javascript
{
  "id": "api.questionset.retire",
  "ver": "5.0",
  "ts": "2023-06-29T07:51:03ZZ",
  "params": {
    "resmsgid": "da7af22e-bdce-48f0-8743-f50fa6c2cd21",
    "msgid": null,
    "err": "NOT_FOUND",
    "status": "failed",
    "errmsg": "Error! Node(s) doesn't Exists. | [Invalid Node Id.]: do_1132079390699683841121"
  },
  "responseCode": "RESOURCE_NOT_FOUND",
  "result": {
    "messages": null
  }
}
```

{% endtab %}

{% tab title="500: Internal Server Error Looks like something went wrong! These errors are tracked automatically" %}

```javascript
{
  "id": "api.questionset.retire",
  "ver": "5.0",
  "ts": "2023-06-29T07:51:03ZZ",
  "params": {
    "resmsgid": "f234a6f0-3ac4-11eb-b0a2-8d5c9f561887",
    "msgid": null,
    "status": "failed",
    "err": null,
    "errmsg": null
  },
  "responseCode": "SERVER_ERROR",
  "result": {}
}
```

{% endtab %}
{% endtabs %}

#### Success result schema

<table><thead><tr><th width="188">Attribute</th><th width="159.33333333333331">Type</th><th>Description</th></tr></thead><tbody><tr><td>identifier</td><td>String</td><td>Unique Question identifier</td></tr><tr><td>versionKey</td><td>String</td><td>Unique version key for question</td></tr></tbody></table>

#### cURL

```shell
curl --location -g --request DELETE '{{host}}/questionset/v2/retire/{{questionSet_id}}' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer {{api_key}}' \
--header 'X-Channel-Id: {{channel_id}}' \
--data-raw '{
  "request": {
    "questionset": {
    }
  }
}'
```


# Configuration

This page provides configuration details of Question & QuestionSet service

For quick overview of QuestionSet Service Configuration, Please checkout below video

{% embed url="<https://youtu.be/_xa6nrMa7jw>" %}

For Question & QuestionSet Service Configuration details and default values, Please refer [here](/use/developer-installation/question-and-question-set-service/configuration).

Micro-service Configuration is available [here](https://github.com/project-sunbird/sunbird-devops/blob/release-5.2.0-inquiry/ansible/roles/stack-sunbird/templates/assessment-service_application.conf)

Flink Job Configurations are available [here](https://github.com/Sunbird-inQuiry/data-pipeline/blob/release-5.2.0/kubernetes/helm_charts/datapipeline_jobs/values.j2)<br>


# Source Code

Here is the link to the source code. Currently, inQuiry leverages source code from [Sunbird Knowlg](https://knowlg.sunbird.org/learn/readme) for core component (ontology-engine). For Branch and Tag, Please checkout release notes.

\
\
**Question & QuestionSet Service Source Code:**&#x20;

{% embed url="<https://github.com/Sunbird-inQuiry/inquiry-api-service.git>" %}

{% embed url="<https://youtu.be/yoHBowTh4OQ?si=OddNJ_r67qgGSyWV&t=37>" %}

**Core Component (knowlg-core) Source Code:**&#x20;

{% embed url="<https://github.com/Sunbird-Knowlg/knowledge-platform.git>" %}

For Question & QuestionSet Service, Please use [**assessment-api** ](https://github.com/Sunbird-inQuiry/inquiry-api-service/tree/master/assessment-api)folder in above repo.&#x20;

**Asynchronous Flink Job Source Code:**

{% embed url="<https://github.com/Sunbird-inQuiry/data-pipeline.git>" %}

Question & QuestionSet Service uses below async jobs (written using Apache Flink)&#x20;

1. [async-questionset-publish](https://github.com/Sunbird-inQuiry/data-pipeline/tree/master/publish-pipeline/async-questionset-publish) : used for publish operation of Question & QuestionSet Asset.

{% embed url="<https://youtu.be/yoHBowTh4OQ?si=il_JPSlJU_FGB4DD&t=1433>" %}


# FAQs

### 1. What is the recommended way to make a deep copy of a request?

In order to make a deep copy of Sunbird Request, you can serialize it and then deserialize back as a Request class object. For serialization and deserialization, you can use exiting files like JsonUtils or ScalaJsonUtils. Click [here](https://github.com/Sunbird-inQuiry/Community/discussions/6) for more details.


# Question Set Player

Question set player (QuML player) is responsible for rendering questions & question sets created as per the QuML spec. The question set player is embeddable in any angular web app. It is an npm package that can be installed and configured with ease.&#x20;

### Key Features:

#### **Inclusivity:**

Question set player is built as per WCAG AA guidelines such as:

* Text alternatives for all non-text content
* Enables consumption of the assessment using a keyboard
* Maintenance of proper focus order to enable a meaningful consumption experience for users using assistive technologies
* Compatible with assistive technologies such as screen readers
* Screen readers can be used in both mobile app and browser.

#### **Embeddable:**

Can be easily embedded in any hybrid mobile app or angular based web applications

#### **Supports offline consumption**

Question set player is build to support offline consumption

#### **Creates engaging learning by allowing users to:**&#x20;

* Navigate to any question within the question set&#x20;
* View their progress
* View hints, solutions, and prompt feedback if allowed
* Keep track of their time
* Review and submit their answers to assessments
* Keep track of the skipped question
* Retry the question if allowed
* Share the question set

![](https://lh5.googleusercontent.com/THbamHiOn9Gi8eDwCZeSHJrbX3GOSsNFcDry0J74HJvVmSADN8amjPKukiDFy1RE6_G6UH6kPRl7MrrDdyRJhXrVhZ1DOwYeE59cJe9jo554QANSSXUc63uj6PFsBRl6n7fCHaXwFR0)

![](https://3506001968-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FWu4HIWGkb7dD4y0Kup4W%2Fuploads%2FFRLpnEOSSBEeP8cWhY4e%2FScreen%20Shot%202022-03-21%20at%201.32.23%20PM.png?alt=media\&token=d31e8c9b-c4fb-47ee-8a91-0e097ac8ca3a)

![](https://lh5.googleusercontent.com/zSTG6dcYlL8WFZhkg2aezFHXQw38cug2RGPUHqZJIP1f5NBC8BL7nnx7xN0D_j2ZnBXBWD1pU4lQBqxS3VvCVhRKb6TBuOVkvF5fS_RZcHM10NhtpEo8RjgYZatpvQ11Wz1zH3Xe2zg)


# Architecture

The Following diagram dictates the architecture of the QuML player

![Arhitectural diagram of QuML player](https://3506001968-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FWu4HIWGkb7dD4y0Kup4W%2Fuploads%2FTGTNR9d4Nayj9eg13Gp9%2FContent%20%20player%20Achitecture-PDF%20player-PDF%20player-Video%20player.png?alt=media\&token=3d4dac86-3405-47df-b3c1-ef56bfc43013)

## **Sunbird Player SDK**

SDK contains common components used by all the V2 players to make it consistent and reusable across players. It contains Start, End Page components along with Navigation and Side menu components. These components accept the config and expose an event on the action performed on it.

## **Common Service Library**

TelemetryModule is getting used from this common-service-library to generate the telemetry events from the player.

## **Katex**

The question and answer can contain this mathematical notation. KaTeX is a cross-browser JavaScript library that displays mathematical notation in web browsers. It puts special emphasis on being fast and easy to use.&#x20;

## **ngx-bootstrap**

**`CarouselModule`** is getting used from the `ngx-bootstrap` to show the carousel (slides) in the player.


# Configuration

The QuML player is an angular library built with Angular version 12, and it exports some modules and components. It has a component that accepts input from the user. The followings are the list of all the configurations on which the QuML player works.

## :notebook\_with\_decorative\_cover:**Component:** *quml-main-player*&#x20;

\
&#x20; This is the main player Component that accepts some configurations (here `playerConfig`) based on it will render the player.  \
&#x20; While rendering the player it also emits some events such as `playerEvent` and `telemetryEvent`

Let's deep dive into the player input configuration:

```typescript
  export interface QumlPlayerConfig = {
    config: Config;
    context?: Context;
    metadata: Metadata;
  }
```

## :clipboard:Input Config

### **1. Config** - Required

This Required property from the `playerConfig` provides the configuration for the player to enable/disable some functionalities.  \
Along with this it also provides the state of the content, if available.

```typescript
  export interface Config {
    traceId?: string;
    sideMenu?: {
        enable?: boolean;
        showShare?: boolean;
        showDownload?: boolean;
        showReplay?: boolean;
        showExit?: boolean;
    };
    progressBar?: any[];
    questions?: any[];
    lastQuestionId?: string;
    duration?: number;
    nextContent?: {
        name: string;
        identifer?: string;
    },
    showWarningTimer: boolean,
    warningTime: number
}
```

Description of the properties for the config

| Property              | Default Value | Required | Description                                                                                                                                                                                               |
| --------------------- | ------------- | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| sideMenu.enable       | true          | false    | To show/hide the sidebar menu / hamburger menu                                                                                                                                                            |
| sideMenu.showShare    | true          | false    | To enable the share functionality in a sidebar menu                                                                                                                                                       |
| sideMenu.showDownload | true          | false    | To enable the Download functionality in a sidebar menu                                                                                                                                                    |
| sideMenu.showExit     | true          | false    | To enable the exit functionality in a sidebar menu (Mostly used in mobile application to exit the player)                                                                                                 |
| progressBar           | \[ ]          | false    | Previous saved state for progressBar. It is state object containing question and there associate answer status.                                                                                           |
| questions             | \[ ]          | false    | Previously saved state for questions. Array of saved questions                                                                                                                                            |
| lastQuestionId        | null          | false    | Question Identifier of last played content                                                                                                                                                                |
| nextContent           | null          | false    | Data of the next content to be play like name and identifier                                                                                                                                              |
| duration              | 0             | false    | Last player duration in miliseconds.                                                                                                                                                                      |
| traceId               | null          | false    | To trace the error                                                                                                                                                                                        |
| showWarningTimer      | true          | false    | This will decide if the `WarningTimer` has to be displayed or not                                                                                                                                         |
| warningTime           | 75            | false    | <p>Warning timer will start showing once the user finishes 75% (default) of the max time</p><p><strong>For eg,</strong> max time is 100 seconds, warning timer will start showing from the 75 seconds</p> |

### **2. Context** - (Optional)

This Required property from the `playerConfig` provides the context to the player mostly in terms of the telemetry.

Along with this it also provides the state of the content, if available.

```typescript
 export interface Context {
    mode: string;
    threshold?: number;
    authToken?: string;
    sid: string;
    did: string;
    uid: string;
    channel: string;
    pdata: Pdata;
    contextRollup: ContextRollup;
    tags: string[];
    cdata?: Cdata[];
    timeDiff?: number;
    objectRollup?: ObjectRollup;
    host?: string;
    endpoint?: string;
    userData?: {
        firstName: string;
        lastName: string;
    };
  }
```

Description of the properties for the config

| **Property**       | **Required** | **Description**                                                                                                |
| ------------------ | ------------ | -------------------------------------------------------------------------------------------------------------- |
| mode               | true         | It is `string` to identify preview used by the user to play/edit/preview. Default value is `play`              |
| sid                | true         | It is `string` and User sessionid on portal or mobile                                                          |
| did                | true         | It is `string` and Unique id to identify the device or browser                                                 |
| channel            | true         | It is `string` which defines channel identifier to know which channel is currently using. for ex. `in.sunbird` |
| pdata              | true         | It is an `object` which defines the producer information it should have identifier and version                 |
| contextRollup      | true         | context Rollups upto level 4                                                                                   |
| tags               | true         | Encrypted dimension tags passed by respective channels                                                         |
| authToken          | false        | It is `string` and Auth key to make api calls                                                                  |
| threshold          | false        | Its a Threshold number to fetch the number of questions with question API                                      |
| cdata              | false        | Correlation data                                                                                               |
| timeDiff           | false        | Last content playing duration                                                                                  |
| objectRollup       | false        | Object Rollup up to level 4                                                                                    |
| host               | false        | It is `string` which defines the from which domain content should be load                                      |
| endpoint           | false        | Telemetry API endpoint                                                                                         |
| userData.firstName | false        | User's first name                                                                                              |
| userData.lastName  | false        | User's last name                                                                                               |

### **3. Metadata:** Required

Following is the interface for the metadata:

```typescript
  export interface Metadata {
    instructions: Object; // May Contain default instructions
    showStartPage: boolean;
    timeLimits: Object; // Contains maxTime and warningTime in number of seconds
    navigationMode: string;
    maxScore: number;
    showTimer: string,
    name: string;
    description: string;
    allowSkip: string;
    primaryCategory: string;
    mimeType: string;
    objectType: string;
    maxAttempts: number;
    showHints: string;
    showFeedback: string;
    requiresSubmit: string;
    showSolutions: string;
    shuffle: boolean;
    [propName: string]: any;
  }
```

The followings are some of the properties related to the question set response, it will have other properties of content as well.

| **Property**    | **Description**                                                                                                                                                                                                                                                                  |
| --------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| instructions    | These are instructions that will be placed on the first page of the question set or the section. It has HTML code that can be directly painted on DOM                                                                                                                            |
| showStartPage   | This config is used to show or hide the start page in the question set                                                                                                                                                                                                           |
| timeLimits      | This config used to show the maximum time to attempt the test with the warning time                                                                                                                                                                                              |
| navigationMode  | Navigation of the questionset such as Linear, non-linear                                                                                                                                                                                                                         |
| maxScore        | Total maxscore of the questionset                                                                                                                                                                                                                                                |
| showTimer       | To show the timer in descending order                                                                                                                                                                                                                                            |
| name            | Name of the Questionset                                                                                                                                                                                                                                                          |
| description     | Description of the questionset                                                                                                                                                                                                                                                   |
| allowSkip       | Config to tell the player if skipping the questions are allowed. If allowed then user can directly jump to any question, if cannot skip the question.                                                                                                                            |
| primaryCategory | Primary Category of the questionset e.g. Practice Question Set                                                                                                                                                                                                                   |
| mimeType        | MimeType of the questionset which is `application/vnd.sunbird.questionset`                                                                                                                                                                                                       |
| maxAttempts     | A maximum number of attempts one can take. It will be shown on the player. Once all the attempts are exhausted user cannot attempt questionset anymore                                                                                                                           |
| showHints       | Config to show/hide the hint button. By clicking on this button it will show solution page.                                                                                                                                                                                      |
| showFeedback    | <p>Config to show/hide feedback page. If enabled it will show a feedback popup for correct and wrong answers. For a wrong answer, user can attempt the question again by clicking on ‘Try Again’ button<br>This config uses different color coding for the question-set list</p> |
| requiresSubmit  | Config to show/hide the submit button. This is to show submit page where all the questions are listed and user can navigate to skipped or attempted questions directly from this page before submitting the answers.                                                             |
| showSolutions   | Config to show/hide the solution button                                                                                                                                                                                                                                          |
| shuffle         | Config to enable/disable the shuffle in questions                                                                                                                                                                                                                                |

## :arrow\_forward:Screenshots:

* Refer to the following screenshots for more understanding:

![First page configurations](https://3506001968-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FWu4HIWGkb7dD4y0Kup4W%2Fuploads%2FqCacWKPK5iWCwxDqQv5l%2Fparent-config.png?alt=media\&token=afc34e50-e40a-44e8-a922-51bfc69164df)

![Sidebar menu configurations](https://3506001968-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FWu4HIWGkb7dD4y0Kup4W%2Fuploads%2FONvzzXDs37378niXyEOk%2Fsidemenu.png?alt=media\&token=6c9912a4-928b-4bd7-b8c4-512a13b24c2d)

![Feedback popup configurations](https://3506001968-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FWu4HIWGkb7dD4y0Kup4W%2Fuploads%2FEQlAxrX03D1zBMeC7p9S%2Ffeedback-popup.png?alt=media\&token=0506df73-8f4a-4907-9743-b8abe9594278)


# Source Code

Here is the link to the source code of the QuML player:

{% embed url="<https://github.com/Sunbird-inQuiry/player>" %}


# APIs

Below are the list of APIs that is invoked from Player

## InQuiry - QuestionSet APIs

Below are the set of QuestionSet APIs from inQuiry Service that QuML Player is dependent on.

* QuestionSet Read
* QuestionSet Hierarchy Read

Details of the APIs can be found [here](https://inquiry.sunbird.org/learn/product-and-developer-guide/question-and-question-set-service/apis/questionset-apis)

## InQuiry - Question APIs

Below are the set of Question APIs from inQuiry Service that QuML Player is dependent on.

* Question List

Details of the APIs can be found [here](https://inquiry.sunbird.org/learn/product-and-developer-guide/question-and-question-set-service/apis/question-apis)


# FAQ's

Frequently Asked questions

### Which type of questions QuML Player supports?

As of now, the QuML player supports two types of questions viz. MCQ i.e. Multiple Choice Questions and SA i.e. Subjective Answer

### How to hide the sidebar?

By default the sidebar is visible. To hide or disable it, the user needs to pass the following config to the player :point\_down:

```typescript
"config": {
        "sideMenu": {
            "enable": true
        }
    }
```

### How to add a new menu item in the menubar?

As of now, there are 3 options are available such as share, download, and exit.\
\
Share is to share the content as a link, the download will download the content on the device and exit will close the player(prefer to use in the mobile app)\
\
To show these options in the menubar add the following config in the input of the player :point\_down:

```typescript
"config": {
      "sideMenu": {
            "enable": true,
            "showShare": true,
            "showDownload": true,
            "showExit": true,
        }
}
```

### How to enable maximum attempts allowed?

The QuML player expects two config properties in metadata to enable the maximum attempts allowed viz. <mark style="color:red;">maxAttempt</mark> and <mark style="color:red;">currentAttempt</mark><br>

maxAttempt is total maximum attempt allowed\
currentAttempt is a count of the current attempt number.

\
Users can pass the config like below :point\_down:

```typescript
"metadata": {
  "maxAttempt": 3,
  "currentAttempt": 1,
}
```

### **How to enable the maximum timer and warning timer for the question set player?**

The maximum timer is the total time given to complete the assessment whereas the warning time is the time which will start blinking so that the user can get to know that the maximum time is about to be over.&#x20;

The QuML player accepts 2 config options to enable these timers. All are in milliseconds.<br>

```typescript
"metadata": {
  "showTimer": "No",
  "timeLimits": '{"maxTime":"1800","warningTime":"600"}',
}
```

### What is feedback and how to enable it?

Feedback is a way to tell a user that an attempted question is correct or wrong. It will show a popup for each correct and wrong answer. It even allows trying again the same question if the answer is wrong. Feedback will also update the colors in the progress bar as well.&#x20;

To enable this feature, the player accepts the following configs :point\_down:

```typescript
"metadata": {
  "showFeedback": "Yescode"
}
```

<div align="center"><img src="https://3506001968-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FWu4HIWGkb7dD4y0Kup4W%2Fuploads%2FTv99aJn86bXrIX5tFkR6%2Ffeedback-popup.png?alt=media&amp;token=d9e4f06f-6754-4880-87e6-2da2ed6aec38" alt="Feedback popup"></div>

### How to show solutions?

The QuML player has a feature to show solutions. Once the user attempted any question, the answer button will be shown.&#x20;

To enable the show solution, the player accepts the following configs :point\_down:

```typescript
"metadata": {
  "showSolutions": "Yes"
}
```

### How to enable the question shuffle?

Shuffling questions are works on section level. To enable the shuffle player accepts the following configs :point\_down:

```typescript
"metadata": {
  "shuffle": true,
}
```

### How to restrict the user to skip the question?

The QuML player has a provision to disallow a user from skipping the question. The player accepts the following config to disallow question skip :point\_down:

```typescript
"metadata": {
  "allowSkip": "Yes",
}
```

###

### What is submit page and how to enable it?

*<mark style="color:red;">Submit page</mark>* provides an option to users to review their attempt details and submit the assessment. To enable the submit page one needs to pass the following config in the metadata :point\_down:

```typescript
"metadata": {
    "requiresSubmit": "Yes"
}
```

<div align="left"><img src="https://3506001968-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FWu4HIWGkb7dD4y0Kup4W%2Fuploads%2FjvYai7eLKj4HZGwCKvmQ%2Fsubmit-page.png?alt=media&amp;token=f8ba2517-1cdd-418d-a90e-90685109aa95" alt="Submit page with feedback enabled"></div>

### How to handle telemetry events?

The QuML library exports the <mark style="color:red;">telemetryEvent.</mark> It will provide all the generated telemetry events within the player. The user needs to listen for this event and sync with the server.

### Does the QuML player store the state of the question set?

The QuML player does not store the state of the question set, but instead, it exports the state values so that the client application can save and send it to the player for subsequent usage.

### Does the user need to be logged in to access the question set?

If the question set is part of a trackable collection or course then the user needs to log in to access the course, but a user can always access the question set without logging into the web app.

### Can users change the look and styles of the player?

As of now, the QuML player does not support any themes or custom styles. But still, users can override the existing classes and change the styles.&#x20;

**Note:** Player supports the dark and light theme, based on sb-themes

### Does the QuML player support multiple Languages?

As of now, the player works in English language. It can be extended and made multi-lingual.


# Analytics

### Telemetry Events for QuML Player

Following is the list of telemetry events that are used to analyze the question sets to generate reports of the assessments and to calculate the attempts.

#### **START**

This will initialize the Player with content and user details

```json
{
  "eid": "START",
  "ets": 1647849981050,
  "ver": "3.0",
  "mid": "START:23dd18d1b3cb4f4f9649c4bed4da8c5c",
  "actor": {
    "id": "561c348e631fd225b46a5571cbd42ad1",
    "type": "User"
  },
  "context": {
    "channel": "01268904781886259221",
    "pdata": {
      "id": "preprod.diksha.portal",
      "ver": "3.3.0",
      "pid": "sunbird-portal.contentplayer"
    },
    "env": "contentplayer",
    "sid": "913b3c6c-2874-26dd-ed0c-c23ddc00b718",
    "did": "561c348e631fd225b46a5571cbd42ad1",
    "cdata": [
      {
        "id": "c0c9384a82a75f219468d363e1891963",
        "type": "ContentSession"
      },
      {
        "id": "a12f45a1d7078901adb27b48be4b428d",
        "type": "PlaySession"
      },
      {
        "id": "8XJCqu3HxZchf039369fHiGtAHFXvCch",
        "type": "ContentSession"
      },
      {
        "id": "dqYZxK1hUunrgJ9GcRKCHq1S2wc8GSnl",
        "type": "PlaySession"
      },
      {
        "id": "2.0",
        "type": "PlayerVersion"
      },
      {
        "id": "do_21348431528472576011",
        "type": "SectionId"
      }
    ],
    "uid": ""
  },
  "object": {
    "id": "do_213484313936035840138",
    "type": "Content"
  },
  "tags": [],
  "edata": {
    "type": "content",
    "mode": "play",
    "pageid": "",
    "duration": 0.01
  }
}
```

#### **INTERACT**

This method is used to capture user interactions on a page. For example, the next button click, option select, or keyboard actions such as enter key, move and resize

```json
{
  "eid": "INTERACT",
  "ets": 1647886019289,
  "ver": "3.0",
  "mid": "INTERACT:4dfa680648714137401a1104512d4526",
  "actor": {
    "id": "561c348e631fd225b46a5571cbd42ad1",
    "type": "User"
  },
  "context": {
    "channel": "01268904781886259221",
    "pdata": {
      "id": "preprod.diksha.portal",
      "ver": "3.3.0",
      "pid": "sunbird-portal.contentplayer"
    },
    "env": "contentplayer",
    "sid": "913b3c6c-2874-26dd-ed0c-c23ddc00b718",
    "did": "561c348e631fd225b46a5571cbd42ad1",
    "cdata": [
      {
        "id": "c0c9384a82a75f219468d363e1891963",
        "type": "ContentSession"
      },
      {
        "id": "a12f45a1d7078901adb27b48be4b428d",
        "type": "PlaySession"
      },
      {
        "id": "0A4fMmfb7WYZzAzYMTnc5kT5sqFM0XEk",
        "type": "ContentSession"
      },
      {
        "id": "MNNxc334B8GRey3tAXi8TAIYQwHxYU5K",
        "type": "PlaySession"
      },
      {
        "id": "2.0",
        "type": "PlayerVersion"
      },
      {
        "id": "do_21348431528472576011",
        "type": "SectionId"
      }
    ],
    "uid": ""
  },
  "object": {
    "id": "do_213484313936035840138",
    "type": "Content",
    "ver": ""
  },
  "tags": [],
  "edata": {
    "type": "TOUCH",
    "subtype": "",
    "id": "option_clicked",
    "pageid": "1"
  }
}
```

#### **IMPRESSION**

This method is used to capture telemetry for user visits to a specific page. In the case of QuML it gets generated when the user changes the question by clicking on the next or previous button, when a user visits the end page, or when a user visits the scoreboard.

```json
{
  "eid": "IMPRESSION",
  "ets": 1647886137586,
  "ver": "3.0",
  "mid": "IMPRESSION:653c50e4887b8db4bb397e0e4aaed242",
  "actor": {
    "id": "561c348e631fd225b46a5571cbd42ad1",
    "type": "User"
  },
  "context": {
    "channel": "01268904781886259221",
    "pdata": {
      "id": "preprod.diksha.portal",
      "ver": "3.3.0",
      "pid": "sunbird-portal.contentplayer"
    },
    "env": "contentplayer",
    "sid": "913b3c6c-2874-26dd-ed0c-c23ddc00b718",
    "did": "561c348e631fd225b46a5571cbd42ad1",
    "cdata": [
      {
        "id": "c0c9384a82a75f219468d363e1891963",
        "type": "ContentSession"
      },
      {
        "id": "a12f45a1d7078901adb27b48be4b428d",
        "type": "PlaySession"
      },
      {
        "id": "0A4fMmfb7WYZzAzYMTnc5kT5sqFM0XEk",
        "type": "ContentSession"
      },
      {
        "id": "MNNxc334B8GRey3tAXi8TAIYQwHxYU5K",
        "type": "PlaySession"
      },
      {
        "id": "2.0",
        "type": "PlayerVersion"
      },
      {
        "id": "do_21348431528472576011",
        "type": "SectionId"
      }
    ],
    "uid": ""
  },
  "object": {
    "id": "do_213484313936035840138",
    "type": "Content",
    "ver": ""
  },
  "tags": [],
  "edata": {
    "type": "workflow",
    "subtype": "",
    "pageid": "2",
    "uri": ""
  }
}
```

#### **ERROR**

This method is used to capture the errors with stacktrace, for example when content fails to load when the internet is not available, or when corrupted ECAR opened.

```json
{
  "eid": "ERROR",
  "ets": 1647886200908,
  "ver": "3.0",
  "mid": "ERROR:93bce8052268b09ab9e41024d371de8a",
  "actor": {
    "id": "561c348e631fd225b46a5571cbd42ad1",
    "type": "User"
  },
  "context": {
    "channel": "01268904781886259221",
    "pdata": {
      "id": "preprod.diksha.portal",
      "ver": "3.3.0",
      "pid": "sunbird-portal.contentplayer"
    },
    "env": "contentplayer",
    "sid": "913b3c6c-2874-26dd-ed0c-c23ddc00b718",
    "did": "561c348e631fd225b46a5571cbd42ad1",
    "cdata": [
      {
        "id": "c0c9384a82a75f219468d363e1891963",
        "type": "ContentSession"
      },
      {
        "id": "a12f45a1d7078901adb27b48be4b428d",
        "type": "PlaySession"
      },
      {
        "id": "j7qS353smUdovr8o9OrmMfOTKDycZobW",
        "type": "ContentSession"
      },
      {
        "id": "lcThEjeBDEGuQsDAus7jxgQXlWgZtdxo",
        "type": "PlaySession"
      },
      {
        "id": "2.0",
        "type": "PlayerVersion"
      },
      {
        "id": "do_21348431657166438417",
        "type": "SectionId"
      }
    ],
    "uid": ""
  },
  "object": {
    "id": "do_213484313936035840138",
    "type": "Content",
    "ver": ""
  },
  "tags": [],
  "edata": {
    "err": "LOAD",
    "errtype": "content",
    "stacktrace": "Error: content failed to load , No Internet Available"
  }
}
```

#### **ASSESS**

This method is used to capture user assessments that happen while playing content. Which includes the options with correct answer value and selected option. This event is used to calculate the score.

```json
{
  "eid": "ASSESS",
  "ets": 1647850263832,
  "ver": "3.0",
  "mid": "ASSESS:8e936a7fc0f51f75217d559b0b6eb308",
  "actor": {
    "id": "561c348e631fd225b46a5571cbd42ad1",
    "type": "User"
  },
  "context": {
    "channel": "01268904781886259221",
    "pdata": {
      "id": "preprod.diksha.portal",
      "ver": "3.3.0",
      "pid": "sunbird-portal.contentplayer"
    },
    "env": "contentplayer",
    "sid": "913b3c6c-2874-26dd-ed0c-c23ddc00b718",
    "did": "561c348e631fd225b46a5571cbd42ad1",
    "cdata": [
      {
        "id": "c0c9384a82a75f219468d363e1891963",
        "type": "ContentSession"
      },
      {
        "id": "a12f45a1d7078901adb27b48be4b428d",
        "type": "PlaySession"
      },
      {
        "id": "TWyTb82FPy9W79ayWaFhmitEfecaPUb9",
        "type": "ContentSession"
      },
      {
        "id": "Peu3ndqo4ILAFaJj1M2oIBvdyvzNXGp8",
        "type": "PlaySession"
      },
      {
        "id": "2.0",
        "type": "PlayerVersion"
      },
      {
        "id": "do_21348431528472576011",
        "type": "SectionId"
      }
    ],
    "rollup": {
      "l1": "string",
      "l2": "string",
      "l3": "string",
      "l4": "string"
    },
    "uid": ""
  },
  "object": {
    "id": "do_213484313936035840138",
    "type": "Content",
    "ver": "",
    "rollup": {
      "l1": "string",
      "l2": "string",
      "l3": "string",
      "l4": "string"
    }
  },
  "tags": [],
  "edata": {
    "item": {
      "id": "do_21348431640099225615",
      "title": "q2",
      "type": "mcq",
      "maxscore": 1,
      "params": [
        {
          "answer": true,
          "value": {
            "body": "<p>Jeff Bezos</p>",
            "value": 0
          }
        },
        {
          "answer": false,
          "value": {
            "body": "<p><span style=\"background-color:rgb(255,255,255);color:rgb(32,33,36);\">Bill Gates</span></p>",
            "value": 1
          }
        }
      ],
      "sectionId": "do_21348431528472576011"
    },
    "index": 2,
    "pass": "Yes",
    "score": 1,
    "resvalues": [
      {
        "label": "<p>Jeff Bezos</p>",
        "value": 0,
        "selected": true
      }
    ],
    "duration": 3
  }
}JSO
```

#### RESPONSE

This method is used to capture user responses. For example; response to a question.

```json
{
  "eid": "RESPONSE",
  "ets": 1647850364447,
  "ver": "3.0",
  "mid": "RESPONSE:369882d4d4db9a4eb972d1f0de61ca02",
  "actor": {
    "id": "561c348e631fd225b46a5571cbd42ad1",
    "type": "User"
  },
  "context": {
    "channel": "01268904781886259221",
    "pdata": {
      "id": "preprod.diksha.portal",
      "ver": "3.3.0",
      "pid": "sunbird-portal.contentplayer"
    },
    "env": "contentplayer",
    "sid": "913b3c6c-2874-26dd-ed0c-c23ddc00b718",
    "did": "561c348e631fd225b46a5571cbd42ad1",
    "cdata": [
      {
        "id": "c0c9384a82a75f219468d363e1891963",
        "type": "ContentSession"
      },
      {
        "id": "a12f45a1d7078901adb27b48be4b428d",
        "type": "PlaySession"
      },
      {
        "id": "TWyTb82FPy9W79ayWaFhmitEfecaPUb9",
        "type": "ContentSession"
      },
      {
        "id": "Peu3ndqo4ILAFaJj1M2oIBvdyvzNXGp8",
        "type": "PlaySession"
      },
      {
        "id": "2.0",
        "type": "PlayerVersion"
      },
      {
        "id": "do_21348431528472576011",
        "type": "SectionId"
      }
    ],
    "uid": ""
  },
  "object": {
    "id": "do_213484313936035840138",
    "type": "Content",
    "ver": ""
  },
  "tags": [],
  "edata": {
    "target": {
      "id": "do_21348431640099225615",
      "ver": "1.0",
      "type": "MCQ"
    },
    "type": "CHOOSE",
    "values": [
      {
        "option": {
          "label": "<p>Jeff Bezos</p>",
          "value": 0,
          "selected": true
        }
      }
    ]
  }
}
```

#### SUMMARY

This method is used to log telemetry summary events, which includes the progress of the question set, duration to complete the question set, and a number of questions answer correctly, wrongly, or skipped.&#x20;

```json
{
  "eid": "SUMMARY",
  "ets": 1647850446006,
  "ver": "3.0",
  "mid": "SUMMARY:1d26c7ed1b59a70c4b88b44ad29c0c3e",
  "actor": {
    "id": "561c348e631fd225b46a5571cbd42ad1",
    "type": "User"
  },
  "context": {
    "channel": "01268904781886259221",
    "pdata": {
      "id": "preprod.diksha.portal",
      "ver": "3.3.0",
      "pid": "sunbird-portal.contentplayer"
    },
    "env": "contentplayer",
    "sid": "913b3c6c-2874-26dd-ed0c-c23ddc00b718",
    "did": "561c348e631fd225b46a5571cbd42ad1",
    "cdata": [
      {
        "id": "c0c9384a82a75f219468d363e1891963",
        "type": "ContentSession"
      },
      {
        "id": "a12f45a1d7078901adb27b48be4b428d",
        "type": "PlaySession"
      },
      {
        "id": "OgOdqEX6q2n0dT48D76Qb5hqETsqnMAx",
        "type": "ContentSession"
      },
      {
        "id": "oSNXAvhqp0ydXlOfaJUEMVV7nAcxvN2h",
        "type": "PlaySession"
      },
      {
        "id": "2.0",
        "type": "PlayerVersion"
      },
      {
        "id": "do_21348431657166438417",
        "type": "SectionId"
      }
    ],
    "uid": ""
  },
  "object": {
    "id": "do_213484313936035840138",
    "type": "Content",
    "ver": ""
  },
  "tags": [],
  "edata": {
    "type": "content",
    "mode": "play",
    "starttime": 1647850442442,
    "endtime": 1647850446004,
    "timespent": 3.56,
    "pageviews": 4,
    "interactions": 2,
    "extra": [
      {
        "id": "progress",
        "value": "100"
      },
      {
        "id": "endpageseen",
        "value": "true"
      },
      {
        "id": "score",
        "value": "2"
      },
      {
        "id": "correct",
        "value": "2"
      },
      {
        "id": "incorrect",
        "value": "0"
      },
      {
        "id": "partial",
        "value": "0"
      },
      {
        "id": "skipped",
        "value": "2"
      }
    ]
  }
}

```

#### END

This method is used to capture closure after all the activities are completed which includes the summary object and duration to complete the question set

```json
{
  "eid": "END",
  "ets": 1647850446016,
  "ver": "3.0",
  "mid": "END:a6be05876355d991674433b627b57a0d",
  "actor": {
    "id": "561c348e631fd225b46a5571cbd42ad1",
    "type": "User"
  },
  "context": {
    "channel": "01268904781886259221",
    "pdata": {
      "id": "preprod.diksha.portal",
      "ver": "3.3.0",
      "pid": "sunbird-portal.contentplayer"
    },
    "env": "contentplayer",
    "sid": "913b3c6c-2874-26dd-ed0c-c23ddc00b718",
    "did": "561c348e631fd225b46a5571cbd42ad1",
    "cdata": [
      {
        "id": "c0c9384a82a75f219468d363e1891963",
        "type": "ContentSession"
      },
      {
        "id": "a12f45a1d7078901adb27b48be4b428d",
        "type": "PlaySession"
      },
      {
        "id": "OgOdqEX6q2n0dT48D76Qb5hqETsqnMAx",
        "type": "ContentSession"
      },
      {
        "id": "oSNXAvhqp0ydXlOfaJUEMVV7nAcxvN2h",
        "type": "PlaySession"
      },
      {
        "id": "2.0",
        "type": "PlayerVersion"
      },
      {
        "id": "do_21348431657166438417",
        "type": "SectionId"
      }
    ],
    "uid": ""
  },
  "object": {
    "id": "do_213484313936035840138",
    "type": "Content",
    "ver": ""
  },
  "tags": [],
  "edata": {
    "type": "content",
    "mode": "play",
    "pageid": "sunbird-player-Endpage",
    "summary": [
      {
        "progress": 100
      },
      {
        "totalNoofQuestions": 4
      },
      {
        "visitedQuestions": 4
      },
      {
        "endpageseen": true
      },
      {
        "score": 2
      }
    ],
    "duration": 464.966
  }
}
```


# Code Coverage Stats

## Question Set Editor

* Overall Code Coverage:  [61.3%](https://sonarcloud.io/summary/overall?id=Sunbird-inQuiry_editor)
* Lines of code: 4.8K

## Question Set Player

* Overall Code Coverage: 86.97%
* Lines of code: 1.7K

## Question Set Service

* Overall Code Coverage: [84.3%](https://sonarcloud.io/summary/overall?id=Sunbird-inQuiry_inquiry-api-service\&branch=release-5.1.0)
* Lines of code: 28K


# Product Roadmap

Check out the roadmap here <https://project-sunbird.atlassian.net/jira/software/c/projects/IQ/boards/106/roadmap>

{% embed url="<https://project-sunbird.atlassian.net/jira/software/c/projects/IQ/boards/106/roadmap>" %}
Sunbird inQuiry Roadmap on JIRA
{% endembed %}

Release Calendar: <https://calendar.google.com/calendar/embed?src=c_8qv2bqa8r6fkgedt4hmigomjjo%40group.calendar.google.com&ctz=Asia%2FKolkata>


# Overview

There are two options to deploy Sunbird inQuiry:

**Option 1: Independently deploy Sunbird inQuiry building block**

Please use the below community forums link for any quires related to deployment, and we will assist you to complete the deployment. We are currently working on documentation for deploying Sunbird inQuiry independently.

<https://github.com/orgs/Sunbird-inQuiry/discussions>

**Option 2: Deploying Sunbird inQuiry as part of Sunbird-ED**

Please refer to the [Sunbird-Ed deployment ](https://ed.sunbird.org/use/prerequisites-for-your-own-sunbird-ed-instance)for more details.

Below, a deployment view diagram will explain how inQuiry Building block components are deployed in SunbirdEd.&#x20;

* Question & Question Set Service (assessment-service):
  * The service holds Question & QuestionSet APIs.
* Question Set Editor & Player:&#x20;
  * InQuiry BB provides both editor & player as  NPM packages. SunbirdEd portal package those as libraries and provides both creation and consumption experience.
* Flink Jobs:
  * InQuiry BB has below two asynchronous jobs&#x20;
    * questionset-publish:
      * This job is used for question/question set Enrichment. It performs all necessary enrichment to the question/ question set required for Consumption.
    * Auto-crerator-v2:
      * This job is used during the movement of a question/ question set from one instance to another (import QuestionSet)

![](https://3506001968-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FWu4HIWGkb7dD4y0Kup4W%2Fuploads%2FsTOdb2k7bwoOFO02LUwi%2FinQuiry.png?alt=media\&token=47c9845d-828f-40a7-8beb-6f1b9bae4046)


# Developer Installation


# Question & Question Set Service

* Assessment Service in Sunbird inQuiry has a set of Question & QuestionSet API's.
* This page explains installation steps for local environment.

### How to setup

{% embed url="<https://inquiry.sunbird.org/use/developer-installation/question-and-question-set-service/installation>" %}


# Installation

This Page Explains Steps For Local Installation of Assessment Service

### :label: **Prerequisite**

**Runtime Environment:**

* Java: Java 8 (for Neo4j & Cassandra)& Java 11 (for Service)
* Scala: 2.11

**Databases:**

* Neo4j : 3.3.0&#x20;

{% hint style="info" %}
By default, Neo4j requires authentication (user\_name & password). Authentication should be disabled.
{% endhint %}

* Apache Cassandra: 3.9&#x20;
* Redis: 4.0+

**Build Tool:**

* Maven: 3.3.0+

**Source Code Management Tool:**

* Git

### :label: **Installation Steps**

#### **Step 1:**

* Create a directory with name **inquiry-service** and switch to the directory.
* Question & QuestionSet Service uses **knowlg-core** module from Knowlg BB. So we need to clone two repo's inside folder created above
* Clone the Repository (<https://github.com/Sunbird-Knowlg/knowledge-platform.git>) using the below command.

```
git clone https://github.com/Sunbird-Knowlg/knowledge-platform.git
```

* Based on release version, Please checkout to specific tag for knowlg-core module. For Tag information, Please refer to Core Release Tag Section of Assessment Service under Release Notes.

```
git checkout <BRANCH-NAME/Tag>
```

* Clone the Repository (<https://github.com/Sunbird-inQuiry/inquiry-api-service.git>) using the below command.

```
git clone https://github.com/Sunbird-inQuiry/inquiry-api-service.git
```

* Based on release version, Please checkout to specific branch or tag using below command

```
git checkout <BRANCH-NAME/Tag>
```

#### **Step 2:**

* Navigate to inquiry-service/knowledge-platform folder and build **knowlg-core** module using below command

```
mvn clean install -DskipTests -Pknowlg-core
```

* Navigate to the inquiry-service/inquiry-api-service folder and build the entire code base from the location

```
mvn clean install -DskipTests
```

{% hint style="info" %}

1. You need to build entire code base, if installing for first tim&#x65;**.**
2. Assessment Service can be located in path (inquiry-api-service/assessment-api) and you can build the service only from 2nd time onwards.
   {% endhint %}

**Step 3:**

* Create Required Cassandra DB Schemas using cqlsh. Assessment Service Requires below Keyspaces and Tables:

| Keyspace             | Table                          |
| -------------------- | ------------------------------ |
| **hierarchy\_store** | **questionset\_hierarchy**     |
| **question\_store**  | **question\_data**             |
| **category\_store**  | **category\_definition\_data** |

* To create above keyspaces and tables, Please use below scripts:

```
CREATE KEYSPACE IF NOT EXISTS hierarchy_store WITH replication = {
  'class': 'SimpleStrategy',
  'replication_factor': '1'
};

CREATE KEYSPACE IF NOT EXISTS question_store WITH replication = {
  'class': 'SimpleStrategy',
  'replication_factor': '1'
};

CREATE KEYSPACE IF NOT EXISTS category_store WITH replication = {
  'class': 'SimpleStrategy',
  'replication_factor': '1'
};


CREATE TABLE IF NOT EXISTS hierarchy_store.questionset_hierarchy (
  identifier text,
  hierarchy text,
  instructions text,
  outcomeDeclaration text,
  PRIMARY KEY (identifier)
);

CREATE TABLE IF NOT EXISTS question_store.question_data (
  identifier text,
  body blob,
  editorState text,
  answer blob,
  solutions text,
  instructions text,
  hints text,
  media text,
  responseDeclaration text,
  interactions text,
  PRIMARY KEY (identifier)
);

CREATE TABLE IF NOT EXISTS category_store.category_definition_data (
    identifier text PRIMARY KEY,
    forms map<text, text>,
    objectmetadata map<text, text>
);

```

* **For DB Schema/Script, You can also visit below link:**

{% embed url="<https://github.com/project-sunbird/sunbird-learning-platform/blob/master/ansible/roles/cassandra-db-update/templates/data.cql.j2>" %}

**Step 4:**

* Create required Primary Category (e.g: Practice Question Set, Multiple Choice Question)  & Its corresponding category definition using taxonomy-service.
* [taxonomy-service](https://knowlg.sunbird.org/use/installation-guide/services/taxonomy-service) is a micro-service from Knowlg BB.
* Primary Category is a mandatory property for creating any object (Question, QuestionSet) using assessment-service. Sunbird has a set of predefined Primary Categories and its definitions. Users can also create their own Primary Category and its definition using taxonomy-service.
* For Question & QuestionSet below Primary Categories can be used:

| Primary Category         | Target Object Type |
| ------------------------ | ------------------ |
| Practice Question Set    | QuestionSet        |
| Curiosity Question Set   | QuestionSet        |
| Multiple Choice Question | Question           |
| Subjective Question      | Question           |
| FTB Question             | Question           |

&#x20;

* Sunbird Primary Category Curls can be found here:

{% embed url="<https://github.com/Sunbird-inQuiry/inquiry-api-service/blob/master/scripts/definition-scripts/master_category_create>" %}

* Sunbird Primary Category Definition Curls can be found here:

{% embed url="<https://github.com/Sunbird-inQuiry/inquiry-api-service/tree/master/scripts/definition-scripts>" %}

**Step 5:**

* Modify the application configuration (inquiry-api-service/assessment-api/assessment-service/conf/application.conf) and do the maven build using maven command (mvn clean install -DskipTests)  from assessment-service folder location.
* For Configuration details, Please Refer to [Configuration](/use/developer-installation/question-and-question-set-service/configuration) Page.

**Step 6:**

* Update Object Schema If Required. Object Level Schema is available under path *inquiry-api-service/schemas*
* For Detailed Schema, Please Refer to [Schema](/learn/product-and-developer-guide/question-and-question-set-service/schema) Page.

**Step 7:**

* Run the service from assessment-service folder location using below command:

```
mvn play2:run
```

* Above command will make service available at default port (9000) but won’t be initialised.&#x20;
* In order to initialize the service, we should make the 1st call to the service. For Example, health api can be invoked for the same.
* Curl for Health API is as below

```
curl --location --request GET 'http://localhost:9000/health'
```

* **Now Service is Up and Running. You can try available endpoints.**
* Available endpoints can be checked in **inquiry-api-service/assessment-api/assessment-service/conf/routes** file.
* **To Run Service in Debug Mode, below command can be used**

```
mvnDebug play2:run
```

* Above command will make service available at default port (8000) but won’t be initialized. Service initialization starts when the remote debugger starts and gets connected at 8000 port.

### :label: **Api Specification**

* API’s Specification is available [here](http://docs.sunbird.org/latest/apis/questionapi/)

### :label: **Dependencies**

* **Assessment Service** depends upon an async job **async-questionset-publish** for completion of publish operation of the object.
* For local setup and try out api’s, it's not mandatory to have this flink job because publish api just sends the event to the configured kafka topic and the backend job takes events from kafka topic and performs further operation in async mode. So even if the job is not available, publish api sends the  event and returns 200 response.
* **async-questionset-publish** code base is available in below repository.

{% embed url="<https://github.com/Sunbird-inQuiry/data-pipeline.git>" %}


# Configuration

This Page Explains All Configuration Used By Question & QuestionSet Service

We have 3 components under Question & QuestionSet Service:

1. inquiry-api-service (micro-service)
2. async-questionset-publish (flink job for data pipeline)
3. questionset-republish (flink job for data pipeline)

#### inquiry-api-service:

<table><thead><tr><th width="215" align="center">key</th><th width="175">default value</th><th>description</th><th>Optional/Required</th><th>Category</th></tr></thead><tbody><tr><td align="center">play.http.parser.maxMemoryBuffer</td><td>50MB</td><td>Play Framework Config. It allows to configure memory size for request coming to service</td><td>Optional</td><td>Play Framework Config.</td></tr><tr><td align="center">akka.http.parsing.max-content-length</td><td>50MB</td><td>Play Framework Config. It allows to configure size of request coming to service</td><td>Optional</td><td>Play Framework Config.</td></tr><tr><td align="center">schema.base_path</td><td>../../schemas/</td><td>Base Path for Object Level Schema.</td><td>Required</td><td>Microservice Config</td></tr><tr><td align="center">cassandra.lp.connection</td><td>127.0.0.1:9042</td><td>IP and Port of Cassandra Database</td><td>Required</td><td>Database Config</td></tr><tr><td align="center">redis.host</td><td>"localhost"</td><td>IP of Redis Database</td><td>Required</td><td>Database Config</td></tr><tr><td align="center">redis.port</td><td>6379</td><td>Port of Redis Database</td><td>Optional</td><td>Database Config</td></tr><tr><td align="center">redis.maxConnections</td><td>128</td><td>Maximum No of connection allowed</td><td>Optional</td><td>Database Config</td></tr><tr><td align="center">graph.dir</td><td>/data/graphDB</td><td>Graph DB (Neo4j) Configuration</td><td>Optional</td><td>Database Config</td></tr><tr><td align="center">akka.request_timeout</td><td>30</td><td>Request timeout</td><td>Optional</td><td>Microservice Config</td></tr><tr><td align="center">environment.id</td><td>ekstep</td><td>An unique id for representing env</td><td>Required</td><td>Microservice Config</td></tr><tr><td align="center">graph.ids</td><td>["domain"]</td><td>Graph DB (Neo4j) Configuration</td><td>Optional</td><td>Database Config</td></tr><tr><td align="center">graph.passport.key.base</td><td>31b6fd1c4d64e745c867e61a45edc34a</td><td>Graph DB (Neo4j) Configuration</td><td>Required</td><td>Database Config</td></tr><tr><td align="center">route.domain</td><td>"bolt://localhost:7687"</td><td>Graph DB (Neo4j) Configuration</td><td>Required</td><td>Database Config</td></tr><tr><td align="center">route.bolt.write.domain</td><td>"bolt://localhost:7687"</td><td>Graph DB (Neo4j) Configuration</td><td>Required</td><td>Database Config</td></tr><tr><td align="center">route.bolt.read.domain</td><td>"bolt://localhost:7687"</td><td>Graph DB (Neo4j) Configuration</td><td>Required</td><td>Database Config</td></tr><tr><td align="center">route.all</td><td>"bolt://localhost:7687"</td><td>Graph DB (Neo4j) Configuration</td><td>Required</td><td>Database Config</td></tr><tr><td align="center">route.bolt.write.all</td><td>"bolt://localhost:7687"</td><td>Graph DB (Neo4j) Configuration</td><td>Required</td><td>Database Config</td></tr><tr><td align="center">route.bolt.read.all</td><td>"bolt://localhost:7687"</td><td>Graph DB (Neo4j) Configuration</td><td>Required</td><td>Database Config</td></tr><tr><td align="center">shard.id</td><td>1</td><td>Graph DB (Neo4j) Configuration</td><td>Required</td><td>Database Config</td></tr><tr><td align="center">platform.auth.check.enabled</td><td>FALSE</td><td>Flag to enbale disable authentication check</td><td>Optional</td><td>Microservice Config</td></tr><tr><td align="center">platform.cache.ttl</td><td>3600000</td><td>Expiry Time for Cached Record</td><td>Optional</td><td>Microservice Config</td></tr><tr><td align="center">telemetry_env</td><td>dev</td><td>Environment Name for Telemetry</td><td>Optional</td><td>Microservice Config</td></tr><tr><td align="center">installation.id</td><td>ekstep</td><td>Installation Id</td><td>Optional</td><td>Microservice Config</td></tr><tr><td align="center">kafka.urls</td><td>"localhost:9092"</td><td>Kafka Host &#x26; Port</td><td>Required</td><td>Microservice Config</td></tr><tr><td align="center">kafka.topic.send.enable</td><td>TRUE</td><td>This flag is used to decide whether to send the publish event to kafka topic or not</td><td>Optional</td><td>Microservice Config</td></tr><tr><td align="center">kafka.topics.instruction</td><td>"local.assessment.publish.request"</td><td>Kafka Topic name for publish api</td><td>Required</td><td>Microservice Config</td></tr><tr><td align="center">objectcategorydefinition.keyspace</td><td>"category_store"</td><td>Keyspace Name from where service should read primary category definition</td><td>Required</td><td>Microservice Config</td></tr><tr><td align="center">questionset.keyspace</td><td>"hierarchy_store"</td><td>Keyspace Name where questionset hierarchy and other external data (e.g: instructions) should be saved.</td><td>Required</td><td>Microservice Config</td></tr><tr><td align="center">question.keyspace</td><td>"question_store"</td><td>Keyspace Name where question external data (e.g: body, editorState, etc) should be saved.</td><td>Required</td><td>Microservice Config</td></tr><tr><td align="center">question.list.limit</td><td>20</td><td>Number of Identifiers allowed in Question List api</td><td>Optional</td><td>Microservice Config</td></tr><tr><td align="center">neo4j_objecttypes_enabled</td><td>["Question"]</td><td>This config is used to decide whether to write data in graph or not from hierarchy children</td><td>Optional</td><td>Microservice Config</td></tr><tr><td align="center">composite.search.url</td><td>http://localhost:9000</td><td>Host Url of Knowlg search service</td><td>Required</td><td>Microservice Config</td></tr><tr><td align="center">import.request_size_limit</td><td>200</td><td>Request limit for import api</td><td>Optional</td><td>Microservice Config</td></tr><tr><td align="center">import.output_topic_name</td><td>"local.auto.creation.job.request"</td><td>Kafka topic name for import api</td><td>Required</td><td>Microservice Config</td></tr><tr><td align="center">import.required_props.question</td><td>["name", "code", "mimeType", "framework", "channel"]</td><td>Name of required properties of Question object for import api</td><td>Optional</td><td>Microservice Config</td></tr><tr><td align="center">import.required_props.questionset</td><td>["name", "code", "mimeType", "framework", "channel"]</td><td>Name of required properties of QuestionSet object for import api</td><td>Optional</td><td>Microservice Config</td></tr><tr><td align="center">import.remove_props.question</td><td>[]</td><td>Name of properties which need to be removed from Question object for import api</td><td>Optional</td><td>Microservice Config</td></tr><tr><td align="center">import.remove_props.questionset</td><td>[]</td><td>Name of properties which need to be removed from QuestionSet object for import api</td><td>Optional</td><td>Microservice Config</td></tr><tr><td align="center">root_node_visibility</td><td>["Default","Private"]</td><td>Allowed Visibility for Root QuestionSet object</td><td>Optional</td><td>Microservice Config</td></tr><tr><td align="center">master.category.validation.enabled</td><td>Yes</td><td>This flag is used to control framework categories validation</td><td>Optional</td><td>Microservice Config</td></tr><tr><td align="center">question.cache.enable</td><td>true</td><td>This flag control caching data for Live Questions into Redis Cache</td><td>Optional</td><td>Microservice Config</td></tr><tr><td align="center">questionset.cache.enable</td><td>true</td><td>This flag control caching data for Live QuestionSets into Redis Cache</td><td>Optional</td><td>Microservice Config</td></tr><tr><td align="center">assessment.copy.origin_data</td><td>["name", "author", "license", "organisation"]</td><td>This Config holds property names which should be populated as originData into copied node.</td><td>Optional</td><td>Microservice Config</td></tr><tr><td align="center">assessment.copy.props_to_remove</td><td>["downloadUrl", "artifactUrl", "variants","createdOn", "collections", "children", "lastUpdatedOn", "SYS_INTERNAL_LAST_UPDATED_ON","versionKey", "s3Key", "status", "pkgVersion", "toc_url", "mimeTypesCount","contentTypesCount","leafNodesCount", "childNodes", "prevState", "lastPublishedOn","flagReasons", "compatibilityLevel", "size", "publishChecklist", "publishComment","LastPublishedBy", "rejectReasons", "rejectComment", "gradeLevel", "subject","medium", "board", "topic", "purpose", "subtopic", "contentCredits","owner", "collaborators", "creators", "contributors", "badgeAssertions", "dialcodes","concepts", "keywords", "reservedDialcodes", "dialcodeRequired", "leafNodes", "sYS_INTERNAL_LAST_UPDATED_ON","prevStatus","lastPublishedBy", "streamingUrl"]</td><td>This Config holds all property names which should be removed while copying Question/QuestionSet object.</td><td>Optional</td><td>Microservice Config</td></tr><tr><td align="center">cloud_storage_container</td><td>NA</td><td>This Config holds container name of cloud storage where data should be stored/read.</td><td>Required</td><td>Cloud Storage Config</td></tr><tr><td align="center">cloudstorage.metadata.replace_absolute_path</td><td>false</td><td>This flag is used for storing all metadata having cloud storage path as cloud agnostic path in db and return absolute path in read api responses. By default it is disabled.</td><td>Optional</td><td>Microservice Config</td></tr><tr><td align="center">cloudstorage.metadata.list</td><td>NA</td><td>This config holds list of all property where cloud storage path can be present. This Config will be used only if cloudstorage.metadata.replace_absolute_path is enabled.</td><td>Optional</td><td>Microservice Config</td></tr><tr><td align="center">cloudstorage.relative_path_prefix</td><td>CLOUD_STORAGE_BASE_PATH</td><td>This config holds the string value which should be used in place of cloud storage base url. This config will be used only if cloudstorage.metadata.replace_absolute_path is enabled.</td><td>Optional</td><td>Microservice Config</td></tr><tr><td align="center">cloudstorage.read_base_pat</td><td>NA</td><td>This config holds the  storage base url or cname url which should be used to convert urls to absolute url before returning data to user. This config will be used only if cloudstorage.metadata.replace_absolute_path is enabled.</td><td>Optional</td><td>Microservice Config</td></tr><tr><td align="center">cloudstorage.write_base_path</td><td>NA</td><td>This config can hold multiple cloud storage base url  which should be should be replaced by the value of cloudstorage.relative_path_prefix. This config will be used only if cloudstorage.metadata.replace_absolute_path is enabled.</td><td>Optional</td><td>Microservice Config</td></tr></tbody></table>

#### async-questionset-publish (flink job):

| Key                                           | Default Value                                                                           | Description                                                                                                                                                                                                                              | Required/Optional | Category             |
| --------------------------------------------- | --------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------- | -------------------- |
| kafka.input.topic                             | {{ env\_name }}.assessment.publish.request                                              | This config holds value of input kafka topic name from where events should be read for processing                                                                                                                                        | Required          | Kafka Config         |
| kafka.post\_publish.topic                     | {{ env\_name }}.assessment.postpublish.request                                          | This config holds value of kafka topic name for any post publish activity.                                                                                                                                                               | Required          | Kafka Config         |
| kafka.groupId                                 | {{ env\_name }}-questionset-publish-group                                               | This config holds the group name for kafka input topic where flink checkpointer is maintained.                                                                                                                                           | Optional          | Kafka Config         |
| task.consumer.parallelism                     | 1                                                                                       | This config decides how many threads/process to run for consumer                                                                                                                                                                         | Optional          | Flink Config         |
| task.parallelism                              | 1                                                                                       | This config decides how many process to run in parallel for event processing.                                                                                                                                                            | Optional          | Flink Config         |
| task.router.parallelism                       | 1                                                                                       | This config decides how many process to run for event router.                                                                                                                                                                            | Optional          | Flink Config         |
| question.keyspace                             | {{instance}}\_question\_store                                                           | Cassandra db keyspace name where question data is stored. instance variable will have env name                                                                                                                                           | Required          | Database Config      |
| question.table                                | question\_data                                                                          | Cassandra db table name where question data is stored.                                                                                                                                                                                   | Optional          | Database Config      |
| questionset.keyspace                          | {{instance}}\_hierarchy\_store                                                          | Cassandra db keyspace name where questionset data is stored. instance variable will have env name                                                                                                                                        | Required          | Database Config      |
| questionset.table                             | questionset\_hierarchy                                                                  | Cassandra db table name where questionset data is stored.                                                                                                                                                                                | Optional          | Database Config      |
| print\_service.base\_url                      | NA                                                                                      | Print Service Host Url should be configured.                                                                                                                                                                                             | Required          | Job Config           |
| cloud\_storage\_type                          | NA                                                                                      | This config holds cloud storage provider name. e.g: azure, aws, etc.                                                                                                                                                                     | Required          | Cloud Storage Config |
| cloud\_storage\_key                           | NA                                                                                      | This Config holds unique key which represents specific cloud storage account                                                                                                                                                             | Required          | Cloud Storage Config |
| cloud\_storage\_secret                        | NA                                                                                      | This Config holds secret key to access cloud storage.                                                                                                                                                                                    | Required          | Cloud Storage Config |
| cloud\_storage\_endpoint                      | ""                                                                                      | This Config holds endpoint of cloud storage, if needed by cloud storage.                                                                                                                                                                 | Optional          | Cloud Storage Config |
| cloud\_storage\_container                     | NA                                                                                      | This Config holds container name of cloud storage where data should be stored/read.                                                                                                                                                      | Required          | Cloud Storage Config |
| master.category.validation.enabled            | Yes                                                                                     | This flag is used to control framework categories validation                                                                                                                                                                             | Optional          | Job Config           |
| cloudstorage.metadata.replace\_absolute\_path | false                                                                                   | This flag is used for storing all metadata having cloud storage path as cloud agnostic path in db and return absolute path in read api responses. By default it is disabled.                                                             | Optional          | Job Config           |
| cloudstorage.metadata.list                    | \["appIcon","posterImage","artifactUrl","downloadUrl","variants","previewUrl","pdfUrl"] | This config holds list of all property where cloud storage path can be present. This Config will be used only if cloudstorage.metadata.replace\_absolute\_path is enabled.                                                               | Optional          | Job Config           |
| cloudstorage.relative\_path\_prefix           | CLOUD\_STORAGE\_BASE\_PATH                                                              | This config holds the string value which should be used in place of cloud storage base url. This config will be used only if cloudstorage.metadata.replace\_absolute\_path is enabled.                                                   | Optional          | Job Config           |
| cloudstorage.read\_base\_pat                  | "<https://sunbirddevbbpublic.blob.core.windows.net>"                                    | This config holds the  storage base url or cname url which should be used to convert urls to absolute url before returning data to user. This config will be used only if cloudstorage.metadata.replace\_absolute\_path is enabled.      | Optional          | Job Config           |
| cloudstorage.write\_base\_path                | \["<https://sunbirddevbbpublic.blob.core.windows.net>"]                                 | This config can hold multiple cloud storage base url  which should be should be replaced by the value of cloudstorage.relative\_path\_prefix. This config will be used only if cloudstorage.metadata.replace\_absolute\_path is enabled. | Optional          | Job Config           |

#### questionset-republish (flink job):

| Key                       | Default Value                                  | Description                                                                                       | Required/Optional | Category     |
| ------------------------- | ---------------------------------------------- | ------------------------------------------------------------------------------------------------- | ----------------- | ------------ |
| kafka.input.topic         | {{ env\_name }}.assessment.republish.request   | This config holds value of input kafka topic name from where events should be read for processing | Required          | Kafka Config |
| kafka.post\_publish.topic | {{ env\_name }}.assessment.postpublish.request | This config holds value of kafka topic name for any post re-publish activity.                     | Required          | Kafka Config |
| kafka.groupId             | {{ env\_name }}-questionset-republish-group    | This config holds the group name for kafka input topic where flink checkpointer is maintained.    | Required          | Kafka Config |

Rest other configuration of async-questionset-publish job is applicable for this job as well with all default values.


# Question Set Editor

### System Requirements <a href="#system-requirements" id="system-requirements"></a>

To install the editor, ensure that your laptop or desktop has the following minimum system requirements:

* Operating System: Windows 7 and above, or 4.2 Mac OS X 10.0 and above/Linux
* RAM: >2GB
* CPU: 2 cores, >2 GHz

### How to setup

{% embed url="<https://inquiry.sunbird.org/use/developer-installation/question-set-editor/installation>" %}

### Configuration

Before going to the next section, you should know about [object category definition](https://project-sunbird.atlassian.net/wiki/spaces/SingleSource/pages/2696183813/How+to+configure+forms+in+primaryCategory#Overview) is the key part of the configuration to load the editor.\
\
Here is the sample object category definition for [Practise Question Set](https://inquiry.sunbird.org/use/developer-installation/question-set-editor/installation/object-category-definition).

To know more about different types of form field configuration refer the [Sample Form Configuration](https://inquiry.sunbird.org/use/developer-installation/question-set-editor/installation/sample-form-configuration).

To know more about Question Set Editor configuration, please refer the link  (coming soon...)

### NPM Repository

**Web component**

{% embed url="<https://www.npmjs.com/package/@project-sunbird/sunbird-questionset-editor-web-component>" %}

**Angular library**

{% embed url="<https://www.npmjs.com/package/@project-sunbird/sunbird-questionset-editor>" %}


# Installation

## :label: System requirements <a href="#system-requirements" id="system-requirements"></a>

The following are prerequisites to use question set editor&#x20;

| Softwares / Frameworks | Version |
| ---------------------- | ------- |
| Angular                | 15.2.3  |

{% hint style="info" %}
The Question Set Editor is tested against the above version of angular. Updating to latest versions needs further testing.

For more information on installing angular, see [angular.io/cli](https://angular.io/cli). If you are unsure what version of Angular runs on your system, run “ng version” in a command prompt (terminal) window.

\
Angular requires an [active LTS or maintenance LTS](https://nodejs.org/about/releases) version of Node.js.\
\
Refer here for more details on [Angular CLI dependencies](https://www.npmjs.com/package/@angular/cli/v/9.1.12?activeTab=readme)
{% endhint %}

## :diamond\_shape\_with\_a\_dot\_inside: Question Set Editor library for Sunbird platform

Question Set Editor library components is powered by angular. This editor is primarily designed to be used in the sunbirdEd portal and web portal to drive reusability, maintainability hence reducing the redundant development effort significantly. And it can be integrated with any platform irrespective of the platforms and the frontend frameworks. It is exported not only as an [angular library](#use-as-angular-library-in-angular-app) but also as a [web component](#use-as-web-components) aims to make it easy to share, discover, and reuse web components. It creates a framework agnostic way of composing and re-purposing code.

## 📑 Getting started with integration steps

The Question Set Editor can be integrated as a web component and also as an angular library in angular application projects.

## Use as web components 🌏

Question Set Editor Library can also be used as a web component which means if your project does not use a JavaScript framework but prefers platform-based HTML, CSS, and JavaScript, you may wish to use Question Set Editor Library in this way. Simply follow the below-mentioned steps to use it in plain JavaScript project:

* Insert [library](https://github.com/Sunbird-inQuiry/editor/blob/release-5.7.0/web-component/sunbird-questionset-editor.js) as below:

  ```
  <script  type="text/javascript"  src="sunbird-questionset-editor.js"></script>
  ```
* Copy all the files from [here](https://github.com/Sunbird-inQuiry/editor/tree/release-5.7.0/web-component), the library requires these files internally to work well.
* Define an html element where you want to display the editor and set an `id` to it. For example&#x20;

  ```html
  <div id="inQuiryEditor">
  </div>
  ```

  **Note** - You can give any `id` of your choice but the same id should be used to append the questionsetEditorElement.
* Create a custom HTML element: `lib-questionset-editor`

  ```
  const questionsetEditorElement = document.createElement('lib-questionset-editor');
  ```
* Get sample questionsetEditorConfig from here: [questionsetEditorConfig](https://github.com/Sunbird-inQuiry/editor/blob/release-5.7.0/src/app/data.ts#L143) and pass data using `editor-config`

  ```
  questionsetEditorElement.setAttribute('editor-config', JSON.stringify(questionsetEditorConfig));
  ```

  **Note:** Attribute should be in **string** type
* Listen for the output events: `editorEmitter` as:

  ```
  questionsetEditorElement.addEventListener('editorEmitter', (event) => {
    console.log("On editorEvent", event);
  });
  ```
* Append this element to the existing element

  ```
  const inQuiryEditor = document.getElementById("inQuiryEditor");
  inQuiryEditor.appendChild(questionsetEditorElement);
  ```
* ▶️ Refer demo [example](https://github.com/Sunbird-inQuiry/editor/blob/release-5.7.0/web-component-examples/vanilla-js/index.html)
* **Note:** Question Set Editor requires a back-end service for making the API calls. For running the Question Set Editor you need a server where inQuiry services are up and running.&#x20;
* For testing purpose we are using a node.js server where the API's proxy and editor are running on `localhost`. For running the editor and services from `localhost` please refer the [server.js](https://github.com/Sunbird-inQuiry/editor/blob/release-5.7.0/server.js) file and run it using `node server.js`

## Use as web component in the Angular app

* Run command

  ```
  npm i @project-sunbird/sunbird-questionset-editor-web-component
  ```

* Add these entries in an angular JSON file inside assets, scripts, and styles like below

  ```diff
  "assets": [
                "src/favicon.ico",
                "src/assets",
  +             {
  +              "glob": "**/*",
  +              "input": "node_modules/@project-sunbird/sunbird-questionset-editor-web-component/assets/",
  +               "output": "/assets/"
  +             }
              ],
              "styles": [
                "src/styles.scss",
  +              "./node_modules/@project-sunbird/sunbird-questionset-editor-web-component/styles.css"
              ],
              "scripts": [
  +              "node_modules/@project-sunbird/sunbird-questionset-editor-web-component/sunbird-questionset-editor.js"
              ]
  ```

* Integrating `lib-questionset-editor` web component in the angular component

  Create a viewChild in HTML template of the angular component like

  ```html
  <div #questionsetEditor></div>
  ```

  Refer to the `viewChild` in the ts file of the component and create the Questionset Editor using the `document.createElement`, then attach the editor config and listen to the editor events like below and since we are rendering using `viewChild`these steps should be under the `ngAfterViewInit` hook of the angular component.

  <pre class="language-diff"><code class="lang-diff">  import { AfterViewInit, Component, ElementRef, ViewChild } from '@angular/core';
  + import { questionSetEditorConfig } from './data';
  @Component({
    selector: 'app-root',
    templateUrl: './app.component.html',
    styleUrls: ['./app.component.css']
  })

  export class AppComponent implements AfterViewInit {
  +  @ViewChild('questionsetEditor') inQuiryEditor! : ElementRef;
    
  <strong>  ngAfterViewInit() {
  </strong>+   const editorConfig = questionSetEditorConfig;
  +   const questionsetEditorElement = document.createElement('lib-questionset-editor');
  +   questionsetEditorElement.setAttribute('editor-config', JSON.stringify(editorConfig));

  +   questionsetEditorElement.addEventListener('editorEmitter', (event) => {
  +     console.log("On editorEvent", event);
  +   });

  +   this.inQuiryEditor.nativeElement.append(questionsetEditorElement);
    }
  }
  </code></pre>

  **Note:** Click to see the mock - [questionsetEditorConfig](https://github.com/Sunbird-inQuiry/editor/blob/release-5.7.0/src/app/data.ts#L143) and send the input config as a string

  For running different question set in the editor, set the do\_id of Question Set in `data.ts` file as:&#x20;

  ```diff
  export const questionSetEditorConfig = {
    context: {
      ...
      ...
      ...
      },
  +    identifier: 'do_id', // identifier of created questionset
      ...
      ...
    };
  ```

* You're done!  Question Set Editor web component integration in angular application is completed.

  **Note:** Question Set Editor requires a back-end service to make the API calls. For running it locally we need a proxy server. You can use the below steps for doing the proxy and run the services on localhost:3000

* Create a proxy.conf.json in the root folder. Refer: [proxy.conf.json](https://github.com/Sunbird-inQuiry/editor/blob/release-5.7.0/proxy.conf.json)

* Update the packge.json

  ```diff
  {
      ...
      ...
      "scripts": {
        "ng": "ng",
  +      "start": "ng serve --proxy-config proxy.conf.json",
        ...
        ...
      },
      ...
      "dependencies": {
      ...
      ...
      },
      "devDependencies": {
      ...
      ...
      }
    }
  ```

  * Create a latexService.js in the root folder. Refer: [latexService.js](https://github.com/Sunbird-inQuiry/editor/blob/release-5.7.0/latexService.js)

  * Create server.js in the root folder. Refer: [server.js](https://github.com/Sunbird-inQuiry/editor/blob/release-5.7.0/server.js)

    ```
    Update the host variable to which env your pointing. example if you are pointing sunbird dev instance update variable like below
    const BASE_URL = 'https://dev.inquiry.sunbird.org/' //add the base url of your portal
    const API_AUTH_TOKEN = 'XXXX' // Add the API_KEY of your inQuiry API's.
    ```

  * For running the server.js file few packges are to be installed. Please install the below packages.

    ```
    npm i express-http-proxy
    npm i async
    npm i mathjax-full
    npm i svg2img
    ```

  * Now we are ready to run the application.&#x20;
    * Open one terminal in your application's root folder and run the server as below and let it keep on running.

      ```
      node server.js
      ```
    * Open another terminal on root folder and start your application

      ```
      npm run start
      ```

## Use as Angular library in Angular app

For getting started with a new Angular app, check out the [Angular CLI](https://angular.io/tutorial/toh-pt0).

For existing apps, follow the below-mentioned steps:

### :label: Step 1: Install the packages

The following commands will add `sunbird-questionset-editor` library to your package.json file along with its dependencies.

```red
npm i @project-sunbird/sunbird-questionset-editor --save
```

Don't forget to install the below peer dependencies of the library in your application. that need to be installed in order to use the library in your angular project.

```
npm i @project-sunbird/common-form-elements-full --save
npm i ng2-semantic-ui-v9 --save
npm i ngx-infinite-scroll --save
npm i lodash-es --save
npm i jquery.fancytree --save
npm i uuid --save
npm i @project-sunbird/client-services --save
npm i export-to-csv --save
npm i moment --save
npm i @project-sunbird/ckeditor-build-classic --save
npm i @project-sunbird/sunbird-quml-player-web-component --save
npm i ngx-bootstrap@^10.0.0 --save
npm i ngx-chips@2.2.0 --save
npm i jquery --save
npm i express-http-proxy --save
npm i mathjax-full --save
npm i svg2img --save
npm i font-awesome --save
npm i @project-sunbird/sb-styles
```

Note: *As QuestionSet library is build with angular version 15, we are using **"bootstrap": "^4.6.2"** and **ngx-bootstrap@^10.0.0** which are the compatible versions. For more reference Check compatibility document for ng-bootstrap* [*here*](https://valor-software.com/ngx-bootstrap/#/documentation#compatibility)

### :label: Step 2: create and copy required assests

After installing the above dependencies, now we have to copy the required assets from the given folder to the assets folder of your angular application. It contains styles and plugins.

* Copy the assets from: [assets](https://github.com/Sunbird-inQuiry/editor/tree/main/src/assets)

![image](https://user-images.githubusercontent.com/36467967/154430084-44060eda-97a9-4fd4-a3c0-06364a8ba86f.png)

* Create a latexService.js in the root folder. Refer: [latexService.js](https://github.com/Sunbird-inQuiry/editor/blob/main/latexService.js)
* Create a proxy.conf.json in the root folder. Refer: [proxy.conf.json](https://github.com/Sunbird-inQuiry/editor/blob/main/proxy.conf.json)
* Create server.js in the root folder. Refer: [server.js](https://github.com/Sunbird-inQuiry/editor/commits/main/server.js)

### :label: Step 3: Include the styles, scripts and assets in angular.json

Now open the `angular.json` file and add the following under `architect.build.assets` for default project

```diff
{
  ...
  "build": {
    "builder": "@angular-devkit/build-angular:browser",
    "options": {
      ...
      ...
      "aot": false,
      "assets": [
        ...
        ...
+        {
+          "glob": "**/*",
+          "input": "node_modules/@project-sunbird/sunbird-questionset-editor/lib/assets",
+          "output": "/assets/"
+        },
+        {
+          "glob": "**/*",
+          "input": "node_modules/@project-sunbird/sunbird-quml-player-web-component/assets/",
+          "output": "/assets/"
+        }
      ],
      "styles": [
        ...
+        "node_modules/@project-sunbird/sunbird-quml-player-web-component/styles.css",
+        "node_modules/@project-sunbird/sb-styles/assets/_styles.scss",
+        "src/assets/lib/semantic/semantic.min.css",
+        "src/assets/styles/styles.scss",
+        "node_modules/font-awesome/css/font-awesome.css"
      ],
      "scripts": [
        ...
+        "node_modules/@project-sunbird/sunbird-quml-player-web-component/sunbird-quml-player.js",
+        "src/assets/libs/iziToast/iziToast.min.js",
+        "node_modules/jquery.fancytree/dist/jquery.fancytree-all-deps.min.js",
+        "src/assets/lib/dimmer.min.js",
+        "src/assets/lib/transition.min.js",
+        "src/assets/lib/modal.min.js",
+        "src/assets/lib/semantic-ui-tree-picker.js",
+        "node_modules/@project-sunbird/telemetry-sdk/index.js",
+        "node_modules/@project-sunbird/client-services/index.js"
      ]
    }
  }
  ...
  ...
}
```

### :label: Step 4: Change in package.json&#x20;

```diff
{
    ...
    ...
    "scripts": {
      "ng": "ng",
+      "start": "ng serve --proxy-config proxy.conf.json",
      ...
      ...
    },
    ...
    "dependencies": {
    ...
    ...
    },
    "devDependencies": {
    ...
    ...
    }
  }
```

### :label: Step 5: Add question-cursor-implementation.service

Create a **`question-cursor-implementation.service.ts`** in a project and which will implement the `QuestionCursor` and `EditorCursor` abstract class.\
`QuestionCursor` and `EditorCursor` is an abstract class, exported from the library, which needs to be implemented. Basically it has some methods which should make an API request over HTTP

Let's create the `question-cursor-implementation` service by running the following command:

```
cd src/app
ng g service question-cursor-implementation
```

Now open `app.module.ts` file and import like this:

```diff
+ import { EditorCursor } from '@project-sunbird/sunbird-questionset-editor';
+ import { EditorCursorImplementationService } from './editor-cursor-implementation.service';

@NgModule({
  providers: [
+    { provide: EditorCursor, useExisting: EditorCursorImplementationService }
  ],
})
export class AppModule { }

```

For more information refer [question-cursor-implementation.service.ts](https://github.com/Sunbird-inQuiry/editor/blob/main/src/app/editor-cursor-implementation.service.ts).

### :label: Step 5: Import the modules and components

Include `QuestionsetEditorLibraryModule` in your app module:

```diff
  import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
+  import { QuestionsetEditorLibraryModule, EditorCursor } from '@project-sunbird/sunbird-questionset-editor';
  import { RouterModule } from '@angular/router';
  import { EditorCursorImplementationService } from './editor-cursor-implementation.service';

  @NgModule({
   ...

   imports: [ 
+      QuestionsetEditorLibraryModule,
      BrowserAnimationsModule,
      RouterModule.forRoot([])
      ],
   providers: [
    { provide: EditorCursor, useExisting: EditorCursorImplementationService }
   ]

   ...
  })

 export class AppModule { }
```

Once your library is imported, you can use its main component, `lib-questionset-editor` in your Angular application.

Add the tag to the `app.component.html` like so:

```
<lib-questionset-editor [editorConfig]="editorConfig" (editorEmitter)="editorEventListener($event)"></lib-questionset-editor>
```

### :label: Step 6: Send input to render QuestionSet Editor

Create a data.ts file which contains the `questionSetEditorConfig` Refer: [data.ts](https://github.com/Sunbird-inQuiry/editor/blob/main/src/app/data.ts)

(Note: `data.ts` contains the mock config used in component to send it as input to questionset Editor. We need only [questionSetEditorConfig](https://github.com/Sunbird-inQuiry/editor/blob/main/src/app/data.ts#L143).Use the mock config in your component to send input to questionset editor as `editorConfig`)

**app.component.ts**

```diff
   ...
+  import { questionSetEditorConfig } from './data';
   @Component({
     ...
   })
   export class AppComponent {
     ...
+     public editorConfig: any = questionSetEditorConfig;
   }
```

**app.component.html**

```html
<lib-questionset-editor [editorConfig]="editorConfig" (editorEmitter)="editorEventListener($event)"></lib-questionset-editor>
```

### :orange\_circle: Available components

| Feature            | Notes                        | Selector               | Code                                                                                | Input        | Output        |
| ------------------ | ---------------------------- | ---------------------- | ----------------------------------------------------------------------------------- | ------------ | ------------- |
| QuestionSet Editor | Can be used to render Editor | lib-questionset-editor | *`<lib-questionset-editor [editorConfig]="editorConfig"></lib-questionset-editor>`* | editorConfig | editorEmitter |

#### :small\_red\_triangle\_down: Input Parameters

1. editorConfig: Object - \[`Required`]

```javascript
{
  context: Object   // Information about the telemetry and default settings for editor API requests
  config: Object    // default editor config such as sidebar menu list
}
```

For more information refer this documentation: [CONFIGURATION.MD](https://inquiry.sunbird.org/learn/product-and-developer-guide/question-and-question-set-editor/configuration)

#### :small\_red\_triangle\_down: Output Events

1. editorEmitter() - It emits event for each action performed in the editor.

### :label:Step 7: Set the auth token and questionset identifier

From the root directory - go to `server.js` file

```
Update the host variable to which env your pointing. example if you are pointing sunbird dev instance update variable like below
const BASE_URL = 'dev.sunbirded.org'
const API_AUTH_TOKEN = 'XXXX'
const USER_TOKEN= 'YYYY
```

Note: You will need actual `API_AUTH_TOKEN` and `USER_TOKEN`

If you are pointing to sunbird dev (`dev.sunbirded.org`), create a Question Set in sunbird dev, set the do\_id of Question Set in `data.ts` file

```
export const questionSetEditorConfig = {
  context: {
    ...
    ...
    ...
    },
    identifier: 'do_id', // identifier of questionset created in sunbird dev
    ...
    ...
  };
```

### :label: Step 8: Build the library

Run `npm run build-lib` to build the library. The build artifacts will be stored in the dist/ directory.

### :label: Step 9: Run the application

Before running the application, we have to start the node server to proxy the APIs by running the following command:

```
nodemon server.js
```

Once that is done, Use the following CLI command to run your application locally

```
npm run start
```

To see your application in the browser, go to <http://localhost:4200>.

## :bookmark\_tabs: Questionset Editor Contribution Guide <a href="#questionset-editor-contribution-guide" id="questionset-editor-contribution-guide"></a>

### Repo Setup <a href="#questionset-editor-contribution-guide" id="questionset-editor-contribution-guide"></a>

Clone the Repo with the desired release branch: [  ](<  https://github.com/Sunbird-Ed/sunbird-collection-editor.git&#xA;>)<https://github.com/Sunbird-inQuiry/editor>

Go to the root directory

```
  cd editor
```

Install dependencies

```
  npm install
```

Build the library

```
  npm run build-lib
```

It will create a `/dist/questionset-editor-library` folder at the root directory and also copy all the required assets.

#### Starting up the Sample application <a href="#starting-up-the-sample-application" id="starting-up-the-sample-application"></a>

A sample angular application is included as part of this repo

In another terminal tab -

From the root directory - Start the server

```
  npm run start
```

The demo app will launch at `http://localhost:4200`

#### Set the auth token and questionset identifier <a href="#set-the-auth-token-and-questionset-identifier" id="set-the-auth-token-and-questionset-identifier"></a>

From the root directory - go to `server.js` file

```
Update the host variable to which env your pointing. example if you are pointing sunbird dev instance update variable like below
const BASE_URL = 'dev.sunbirded.org'
const API_AUTH_TOKEN = 'XXXX'
const USER_TOKEN= 'YYYY'
```

Note: You will need actual `API_AUTH_TOKEN` and `USER_TOKEN`

If you are pointing to sunbird dev (`dev.sunbirded.org`), create a Question Set in sunbird dev and set the do\_id of Question Set in `data.ts` file

```
export const questionSetEditorConfig = {
  context: {
    ...
    ...
    ...
    },
    identifier: 'do_id', // identifier of questionset created in sunbird dev
    ...
    ...
  };
```

Run Node server to proxy the APIs (Open one more terminal in root folder and run the server.js ) as:

```
  nodemon server.js
```


# Object Category Definition

Here is the sample object category defintion for question set editor:

```
"objectCategoryDefinition": {
            "identifier": "obj-cat:practice-question-set_questionset_01345815127107174426",
            "objectMetadata": {
                "config": {
                    "sourcingSettings": {
                        "collection": {
                            "maxDepth": 1,
                            "objectType": "QuestionSet",
                            "primaryCategory": "Practice Question Set",
                            "isRoot": true,
                            "iconClass": "fa fa-book",
                            "children": {},
                            "hierarchy": {
                                "level1": {
                                    "name": "Section",
                                    "type": "Unit",
                                    "mimeType": "application/vnd.sunbird.questionset",
                                    "primaryCategory": "Practice Question Set",
                                    "iconClass": "fa fa-folder-o",
                                    "children": {
                                        "Question": [
                                            "Multiple Choice Question",
                                            "Subjective Question"
                                        ]
                                    }
                                }
                            }
                        }
                    }
                },
                "schema": {
                    "properties": {
                        "mimeType": {
                            "type": "string",
                            "enum": [
                                "application/vnd.sunbird.questionset"
                            ]
                        }
                    }
                }
            },
            "languageCode": [],
            "name": "Practice Question Set",
            "forms": {
                "childMetadata": {
                    "templateName": "",
                    "required": [],
                    "properties": [
                        {
                            "code": "name",
                            "dataType": "text",
                            "description": "Name of the content",
                            "editable": true,
                            "inputType": "text",
                            "label": "Title",
                            "name": "Title",
                            "placeholder": "Title",
                            "renderingHints": {
                                "class": "sb-g-col-lg-1 required"
                            },
                            "required": true,
                            "visible": true,
                            "validations": [
                                {
                                    "type": "max",
                                    "value": "100",
                                    "message": "Input is Exceeded"
                                },
                                {
                                    "type": "required",
                                    "message": "Title is required"
                                }
                            ]
                        },
                        {
                            "code": "bloomsLevel",
                            "dataType": "text",
                            "description": "Learning level",
                            "editable": true,
                            "inputType": "select",
                            "label": "Learning level",
                            "name": "Learning level",
                            "placeholder": "Select Learning level",
                            "renderingHints": {
                                "class": "sb-g-col-lg-1"
                            },
                            "required": false,
                            "visible": true,
                            "range": [
                                "remember",
                                "understand",
                                "apply",
                                "analyse",
                                "evaluate",
                                "create"
                            ],
                            "validations": []
                        },
                        {
                            "code": "board",
                            "default": "",
                            "visible": true,
                            "editable": false,
                            "dataType": "text",
                            "renderingHints": {
                                "class": "sb-g-col-lg-1"
                            },
                            "description": "Board",
                            "label": "Board/Syllabus",
                            "required": false,
                            "name": "Board/Syllabus",
                            "inputType": "select",
                            "placeholder": "Select Board/Syllabus"
                        },
                        {
                            "code": "medium",
                            "visible": true,
                            "editable": false,
                            "default": "",
                            "dataType": "list",
                            "renderingHints": {
                                "class": "sb-g-col-lg-1"
                            },
                            "description": "",
                            "label": "Medium",
                            "required": false,
                            "name": "Medium",
                            "inputType": "select",
                            "placeholder": "Select Medium"
                        },
                        {
                            "code": "gradeLevel",
                            "visible": true,
                            "editable": false,
                            "default": "",
                            "dataType": "list",
                            "renderingHints": {
                                "class": "sb-g-col-lg-1"
                            },
                            "description": "Class",
                            "label": "Class",
                            "required": false,
                            "name": "Class",
                            "inputType": "select",
                            "placeholder": "Select Class"
                        },
                        {
                            "code": "subject",
                            "visible": true,
                            "editable": false,
                            "default": "",
                            "dataType": "list",
                            "renderingHints": {
                                "class": "sb-g-col-lg-1"
                            },
                            "description": "",
                            "label": "Subject",
                            "required": false,
                            "name": "Subject",
                            "inputType": "select",
                            "placeholder": "Select Subject"
                        }
                    ]
                },
                "create": {
                    "templateName": "",
                    "required": [],
                    "properties": [
                        {
                            "name": "Basic details",
                            "fields": [
                                {
                                    "code": "appIcon",
                                    "name": "Icon",
                                    "label": "Icon",
                                    "placeholder": "Icon",
                                    "description": "Icon for the question set",
                                    "dataType": "text",
                                    "inputType": "appIcon",
                                    "editable": true,
                                    "required": true,
                                    "visible": true,
                                    "renderingHints": {
                                        "class": "sb-g-col-lg-1 required"
                                    }
                                },
                                {
                                    "code": "name",
                                    "name": "Name",
                                    "label": "Name",
                                    "placeholder": "Name",
                                    "description": "Name of the QuestionSet",
                                    "dataType": "text",
                                    "inputType": "text",
                                    "editable": true,
                                    "required": true,
                                    "visible": true,
                                    "renderingHints": {
                                        "class": "sb-g-col-lg-1 required"
                                    },
                                    "validations": [
                                        {
                                            "type": "max",
                                            "value": "120",
                                            "message": "Input is Exceeded"
                                        },
                                        {
                                            "type": "required",
                                            "message": "Name is required"
                                        }
                                    ]
                                },
                                {
                                    "code": "description",
                                    "name": "Description",
                                    "label": "Description",
                                    "placeholder": "Description",
                                    "description": "Description of the content",
                                    "dataType": "text",
                                    "inputType": "textarea",
                                    "editable": true,
                                    "required": true,
                                    "visible": true,
                                    "renderingHints": {
                                        "class": "sb-g-col-lg-1 required"
                                    },
                                    "validations": [
                                        {
                                            "type": "required",
                                            "message": "description is required"
                                        }
                                    ]
                                },
                                {
                                    "code": "keywords",
                                    "name": "Keywords",
                                    "label": "keywords",
                                    "placeholder": "Enter Keywords",
                                    "description": "Keywords for the Question Set",
                                    "dataType": "list",
                                    "inputType": "keywords",
                                    "editable": true,
                                    "required": false,
                                    "visible": true,
                                    "renderingHints": {
                                        "class": "sb-g-col-lg-1"
                                    }
                                },
                                {
                                    "code": "instructions",
                                    "name": "Instructions",
                                    "label": "Instructions",
                                    "placeholder": "Enter Instructions",
                                    "description": "Instructions for the question set",
                                    "dataType": "text",
                                    "inputType": "richtext",
                                    "editable": true,
                                    "required": false,
                                    "visible": true,
                                    "renderingHints": {
                                        "class": "sb-g-col-lg-2 required"
                                    },
                                    "validations": [
                                        {
                                            "type": "maxLength",
                                            "value": "500",
                                            "message": "Input is Exceeded"
                                        }
                                    ]
                                },
                                {
                                    "code": "primaryCategory",
                                    "name": "Type",
                                    "label": "Type",
                                    "placeholder": "",
                                    "description": "Type or Category of the Question Set",
                                    "dataType": "text",
                                    "inputType": "text",
                                    "editable": false,
                                    "required": false,
                                    "visible": true,
                                    "renderingHints": {
                                        "class": "sb-g-col-lg-1"
                                    }
                                },
                                {
                                    "code": "additionalCategories",
                                    "name": "Additional Category",
                                    "label": "Additional Category",
                                    "placeholder": "Select Additional Category",
                                    "description": "Additonal Category of the Question Set",
                                    "default": "",
                                    "dataType": "list",
                                    "inputType": "nestedselect",
                                    "editable": true,
                                    "required": false,
                                    "visible": true,
                                    "renderingHints": {
                                        "class": "sb-g-col-lg-1"
                                    }
                                }
                            ]
                        },
                        {
                            "name": "Framework details",
                            "fields": [
                                {
                                    "code": "board",
                                    "name": "Board/Syllabus",
                                    "label": "Board/Syllabus",
                                    "placeholder": "Select Board/Syllabus",
                                    "description": "Board or Syallbus of the Question Set",
                                    "default": "",
                                    "dataType": "text",
                                    "inputType": "select",
                                    "editable": true,
                                    "required": true,
                                    "visible": true,
                                    "depends": [],
                                    "renderingHints": {
                                        "class": "sb-g-col-lg-1 required"
                                    },
                                    "validations": [
                                        {
                                            "type": "required",
                                            "message": "Board is required"
                                        }
                                    ]
                                },
                                {
                                    "code": "medium",
                                    "name": "Medium",
                                    "label": "Medium",
                                    "placeholder": "Select Medium",
                                    "description": "Medium of Instruction for the Question Set",
                                    "default": "",
                                    "dataType": "list",
                                    "inputType": "select",
                                    "editable": true,
                                    "required": true,
                                    "visible": true,
                                    "depends": [
                                        "board"
                                    ],
                                    "renderingHints": {
                                        "class": "sb-g-col-lg-1 required"
                                    },
                                    "validations": [
                                        {
                                            "type": "required",
                                            "message": "Medium is required"
                                        }
                                    ]
                                },
                                {
                                    "code": "gradeLevel",
                                    "name": "Class",
                                    "label": "Class",
                                    "placeholder": "Select Class",
                                    "description": "Class of the Question Set",
                                    "default": "",
                                    "dataType": "list",
                                    "inputType": "select",
                                    "editable": true,
                                    "required": true,
                                    "visible": true,
                                    "depends": [
                                        "board",
                                        "medium"
                                    ],
                                    "renderingHints": {
                                        "class": "sb-g-col-lg-1 required"
                                    },
                                    "validations": [
                                        {
                                            "type": "required",
                                            "message": "Class is required"
                                        }
                                    ]
                                },
                                {
                                    "code": "subject",
                                    "name": "Subject",
                                    "label": "Subject",
                                    "placeholder": "Select Subject",
                                    "description": "Subject of the Question Set",
                                    "default": "",
                                    "dataType": "list",
                                    "inputType": "select",
                                    "editable": true,
                                    "required": true,
                                    "visible": true,
                                    "depends": [
                                        "board",
                                        "medium",
                                        "gradeLevel"
                                    ],
                                    "renderingHints": {
                                        "class": "sb-g-col-lg-1 required"
                                    },
                                    "validations": [
                                        {
                                            "type": "required",
                                            "message": "Subject is required"
                                        }
                                    ]
                                },
                                {
                                    "code": "topic",
                                    "name": "Topic",
                                    "label": "Topics",
                                    "placeholder": "Choose Topics",
                                    "description": "Choose Topics covered in the Question Set",
                                    "default": "",
                                    "dataType": "list",
                                    "inputType": "topicselector",
                                    "editable": true,
                                    "required": false,
                                    "visible": true,
                                    "depends": [
                                        "board",
                                        "medium",
                                        "gradeLevel",
                                        "subject"
                                    ],
                                    "renderingHints": {
                                        "class": "sb-g-col-lg-1"
                                    }
                                },
                                {
                                    "code": "audience",
                                    "name": "Audience",
                                    "label": "Audience",
                                    "placeholder": "Select Audience",
                                    "description": "Audience of the Question Set",
                                    "dataType": "list",
                                    "inputType": "select",
                                    "editable": true,
                                    "required": true,
                                    "visible": true,
                                    "range": [
                                        "Student",
                                        "Teacher",
                                        "Administrator"
                                    ],
                                    "renderingHints": {
                                        "class": "sb-g-col-lg-1 required"
                                    },
                                    "validations": [
                                        {
                                            "type": "required",
                                            "message": "Audience is required"
                                        }
                                    ]
                                }
                            ]
                        },
                        {
                            "name": "Question set behaviour",
                            "fields": [
                                {
                                    "code": "maxTime",
                                    "name": "MaxTimer",
                                    "label": "Set Maximum Time",
                                    "placeholder": "HH:mm:ss",
                                    "description": "This is the maximum time allowed for the users to complete the assessment",
                                    "default": "3600",
                                    "dataType": "text",
                                    "inputType": "timer",
                                    "editable": true,
                                    "required": true,
                                    "visible": true,
                                    "renderingHints": {
                                        "class": "sb-g-col-lg-1"
                                    },
                                    "validations": [
                                        {
                                            "type": "time",
                                            "message": "Please enter in hh:mm:ss",
                                            "value": "HH:mm:ss"
                                        },
                                        {
                                            "type": "max",
                                            "value": "05:59:59",
                                            "message": "max time should be less than 05:59:59"
                                        }
                                    ]
                                },
                                {
                                    "code": "warningTime",
                                    "name": "Warning Time",
                                    "label": "Set Warning Timer",
                                    "placeholder": "hh:mm:ss",
                                    "description": "Timer to warn users about the time left to complete the assessment",
                                    "dataType": "list",
                                    "inputType": "timer",
                                    "editable": true,
                                    "required": false,
                                    "visible": true,
                                    "depends": [
                                        "maxTime"
                                    ],
                                    "renderingHints": {
                                        "class": "sb-g-col-lg-1"
                                    },
                                    "validations": [
                                        {
                                            "type": "time",
                                            "message": "Please enter hh:mm:ss",
                                            "value": "HH:mm:ss"
                                        },
                                        {
                                            "type": "compare",
                                            "criteria": {
                                                "<=": [
                                                    "maxTime"
                                                ]
                                            },
                                            "message": "warning time should be less than max timer"
                                        }
                                    ]
                                },
                                {
                                    "code": "showTimer",
                                    "name": "Show Timer",
                                    "label": "Show Timer",
                                    "placeholder": "Show Timer",
                                    "description": "Show Timer",
                                    "default": "No",
                                    "dataType": "text",
                                    "inputType": "select",
                                    "range": [
                                        "Yes",
                                        "No"
                                    ],
                                    "editable": true,
                                    "required": false,
                                    "visible": true,
                                    "depends": [
                                        "maxTime"
                                    ],
                                    "renderingHints": {
                                        "class": "sb-g-col-lg-1"
                                    }
                                },
                                {
                                    "code": "requiresSubmit",
                                    "name": "Submit Confirmation",
                                    "label": "Select Submit Confirmation Page",
                                    "placeholder": "Submit Confirmation",
                                    "description": "Allows users to review and submit the assessment",
                                    "dataType": "text",
                                    "inputType": "select",
                                    "output": "identifier",
                                    "range": [
                                        {
                                            "identifier": "Yes",
                                            "label": "Enable"
                                        },
                                        {
                                            "identifier": "No",
                                            "label": "Disable"
                                        }
                                    ],
                                    "editable": true,
                                    "required": false,
                                    "visible": true,
                                    "renderingHints": {
                                        "class": "sb-g-col-lg-1"
                                    }
                                },
                                {
                                    "code": "maxAttempts",
                                    "name": "Max Attempts",
                                    "label": "Max Attempts",
                                    "placeholder": "Max Attempts",
                                    "description": "Max Attempts",
                                    "dataType": "number",
                                    "inputType": "select",
                                    "editable": true,
                                    "required": false,
                                    "visible": true,
                                    "range": [
                                        1,
                                        2,
                                        3,
                                        4,
                                        5,
                                        6,
                                        7,
                                        8,
                                        9,
                                        10,
                                        11,
                                        12,
                                        13,
                                        14,
                                        15,
                                        16,
                                        17,
                                        18,
                                        19,
                                        20,
                                        21,
                                        22,
                                        23,
                                        24,
                                        25
                                    ],
                                    "renderingHints": {
                                        "class": "sb-g-col-lg-1"
                                    }
                                },
                                {
                                    "code": "summaryType",
                                    "name": "summaryType",
                                    "label": "Summary Type",
                                    "placeholder": "Select Summary Type",
                                    "description": "summaryType",
                                    "dataType": "text",
                                    "inputType": "select",
                                    "editable": true,
                                    "required": false,
                                    "visible": true,
                                    "range": [
                                        "Complete",
                                        "Score",
                                        "Duration",
                                        "Score & Duration"
                                    ],
                                    "renderingHints": {
                                        "class": "sb-g-col-lg-1"
                                    }
                                }
                            ]
                        },
                        {
                            "name": "Question set behaviour",
                            "fields": [
                                {
                                    "code": "author",
                                    "name": "Author",
                                    "label": "Author",
                                    "placeholder": "Author",
                                    "description": "Author of the question set",
                                    "dataType": "text",
                                    "inputType": "text",
                                    "editable": true,
                                    "required": true,
                                    "visible": true,
                                    "renderingHints": {
                                        "class": "sb-g-col-lg-1 required"
                                    },
                                    "validations": [
                                        {
                                            "type": "required",
                                            "message": "Author is required"
                                        }
                                    ]
                                },
                                {
                                    "code": "attributions",
                                    "name": "Attributions",
                                    "label": "Attributions",
                                    "placeholder": "Enter Attributions",
                                    "description": "Attributions of the question set",
                                    "dataType": "text",
                                    "inputType": "text",
                                    "editable": true,
                                    "required": false,
                                    "visible": true,
                                    "renderingHints": {
                                        "class": "sb-g-col-lg-1"
                                    }
                                },
                                {
                                    "code": "copyright",
                                    "name": "Copyright & year",
                                    "label": "Copyright & year",
                                    "placeholder": "Copyright & year",
                                    "description": "Copyright & year",
                                    "dataType": "text",
                                    "inputType": "text",
                                    "editable": true,
                                    "required": false,
                                    "visible": true,
                                    "renderingHints": {
                                        "class": "sb-g-col-lg-1"
                                    }
                                },
                                {
                                    "code": "license",
                                    "name": "license",
                                    "label": "license",
                                    "placeholder": "Select license",
                                    "description": "license",
                                    "dataType": "text",
                                    "inputType": "select",
                                    "editable": true,
                                    "required": false,
                                    "visible": true,
                                    "range": "",
                                    "renderingHints": {
                                        "class": "sb-g-col-lg-1"
                                    }
                                }
                            ]
                        }
                    ]
                },
                "publishchecklist": {
                    "templateName": "",
                    "required": [],
                    "properties": []
                },
                "unitMetadata": {
                    "templateName": "",
                    "required": [],
                    "properties": [
                        {
                            "code": "name",
                            "dataType": "text",
                            "description": "Name of the content",
                            "editable": true,
                            "inputType": "text",
                            "label": "Title",
                            "name": "Title",
                            "placeholder": "Title",
                            "renderingHints": {
                                "class": "sb-g-col-lg-1 required"
                            },
                            "required": true,
                            "visible": true,
                            "validations": [
                                {
                                    "type": "max",
                                    "value": "120",
                                    "message": "Input is Exceeded"
                                },
                                {
                                    "type": "required",
                                    "message": "Title is required"
                                }
                            ]
                        },
                        {
                            "code": "description",
                            "dataType": "text",
                            "description": "Description of the content",
                            "editable": true,
                            "inputType": "textarea",
                            "label": "Description",
                            "name": "Description",
                            "placeholder": "Description",
                            "renderingHints": {
                                "class": "sb-g-col-lg-1 required"
                            },
                            "required": true,
                            "visible": true,
                            "validations": [
                                {
                                    "type": "max",
                                    "value": "500",
                                    "message": "Input is Exceeded"
                                }
                            ]
                        },
                        {
                            "code": "instructions",
                            "name": "Instructions",
                            "label": "Instructions",
                            "placeholder": "Enter Instructions",
                            "description": "Instructions for the section",
                            "dataType": "text",
                            "inputType": "richtext",
                            "editable": true,
                            "required": false,
                            "visible": true,
                            "renderingHints": {
                                "class": "sb-g-col-lg-2"
                            },
                            "validations": [
                                {
                                    "type": "maxLength",
                                    "value": "500",
                                    "message": "Input is Exceeded"
                                }
                            ]
                        },
                        {
                            "code": "maxQuestions",
                            "name": "Show Questions",
                            "label": "Count of questions to be displayed in this section",
                            "placeholder": "Input count of questions to be displayed",
                            "description": "By default all questions are shown unless specific count is entered.",
                            "default": "",
                            "dataType": "number",
                            "inputType": "select",
                            "editable": true,
                            "required": false,
                            "visible": true,
                            "renderingHints": {
                                "class": "sb-g-col-lg-1"
                            }
                        },
                        {
                            "code": "shuffle",
                            "name": "Shuffle Questions",
                            "label": "Shuffle Questions",
                            "placeholder": "Shuffle Questions",
                            "description": "If shuffle questions is selected, users are presented with questions in a random order whenever they attempt the assessment",
                            "default": "false",
                            "dataType": "boolean",
                            "inputType": "checkbox",
                            "editable": true,
                            "required": false,
                            "visible": true,
                            "renderingHints": {
                                "class": "sb-g-col-lg-1"
                            }
                        },
                        {
                            "code": "showFeedback",
                            "name": "Show Feedback",
                            "label": "Show Question Feedback",
                            "placeholder": "Select Option",
                            "description": "If feedback is selected, users are informed whether they have correctly answered question or not",
                            "dataType": "text",
                            "inputType": "select",
                            "range": [
                                "Yes",
                                "No"
                            ],
                            "editable": true,
                            "required": false,
                            "visible": true,
                            "renderingHints": {
                                "class": "sb-g-col-lg-1"
                            }
                        },
                        {
                            "code": "showSolutions",
                            "name": "Show Solution",
                            "label": "Show Solution",
                            "placeholder": "Select Option",
                            "description": "If show solution is selected then solutions for each question will be shown to the user",
                            "dataType": "text",
                            "inputType": "select",
                            "range": [
                                "Yes",
                                "No"
                            ],
                            "editable": true,
                            "required": false,
                            "visible": true,
                            "renderingHints": {
                                "class": "sb-g-col-lg-1"
                            }
                        }
                    ]
                }
            }
        }
```


# Sample Form Configuration

In this section we have covered the sample configuration of various types of fields which can be configured in questionset.

## &#x20;Field Configuration Properties:

```
{
    "code": string, // property to match the backend schema ("name", "description", etc...)
    "name": string, // name of the field ("Name", "Board", "Medium", "License", "Copyright Year", etc)
    "label": string, // title of the field 
    "placeholder": string, // placeholder text to appear within the field
    "description": string, // to specify description about the field and to show as tooltip
    "default": string, // specify default value
    "dataType": string, // to specify the datatype of the field outcome ("list", "number", "text")
    "inputType": string, // to map the field type and the component ("text", "textarea", "select", "nestedselect", etc)
    "editable": boolean, // to enable or disable the field
    "required": boolean, // to specify if the field is mandatory or not (currently, not used.)
    "visible": boolean, // to hide or show the field 
    "depends": array, // array of "code" to specify that this field is dependant on other fields
    "range": array, // Array or array of objects of inputs to fields such as "select", "nestedselect", "multiselect"
    "options": array/function/map, // to specify the inputs to fields such as "select", "nestedselect", "multiselect", "framework", "frameworkCategorySelect"
    "renderingHints": json, // to specify any additional configuration ex:({"class": "sb-g-col-lg-1 required"})
    "validations": array // Array of objects to specity the validations of a field. Each validation object takes properties such as "type", "message", "value", "criteria"
    "output": string, // this field is specific to framework terms and it's associations. The field will decide the property for the field outcome ex:("name", "label", "identifier")
    "sourceCategory": string, // this field is specific to framework categories to map the category and association ex: (to map "subjectIds" with "subject" or to map "targetMediumIds" with "medium")
    "terms": array, // Array or array of object of inputs to fields related to framework and it's categories
}
```

## How to configure different types of fields

In QuestionSet Editor these are the following of fields which we are using:

### **Text**

```
{
    "code": "name",
    "dataType": "text",
    "description": "Name of the Practice Question Set", // tooltip message
    "editable": true,
    "inputType": "text",
    "label": "Name",
    "name": "Name",
    "placeholder": "Enter name of the question set",
    "renderingHints": {
        "class": "sb-g-col-lg-1 required"// this defines field to take space of 1 comun and add * in the Label of field
    },
    "required": true,
    "visible": true,
    "validations": [
        {
            "type": "maxLength",
            "value": "120",
            "message": "Input is Exceeded" // this defines the max length of fields
        },
        {
            "type": "required",
            "message": "Name is required" // this adds the required validation
        }
    ]
}
```

![](https://3506001968-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FWu4HIWGkb7dD4y0Kup4W%2Fuploads%2F4jWPniODablSl4gqcw1R%2Ftext.png?alt=media\&token=14eb076a-c0a3-45fc-8a4e-0f0493edd098)

### **Textarea**

```
{
    "code": "description",
    "dataType": "text",
    "description": "Description of the content",
    "editable": true,
    "inputType": "textarea",
    "label": "Description",
    "name": "Description",
    "placeholder": "Description",
    "renderingHints": {
        "class": "sb-g-col-lg-1 required"
    },
    "required": true,
    "visible": true,
    "validations": [
        {
            "type": "required",
            "message": "description is required" // this adds the required validation
        }
    ]
}
```

![](https://3506001968-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FWu4HIWGkb7dD4y0Kup4W%2Fuploads%2FV0sBs6DB0jFIfzdLbc6B%2Ftextarea.png?alt=media\&token=201d8873-447b-478b-9da6-7f597f15d6e2)

### **Richtext**

```
{
    "code": "instructions",
    "dataType": "text",
    "description": "Instructions for the question set",
    "editable": true,
    "inputType": "richtext",
    "label": "Instructions",
    "name": "Instruction",
    "placeholder": "Enter Instructions",
    "renderingHints": {
        "class": "sb-g-col-lg-2 required"
    },
    "validations": [
        {
            "type": "required",
            "message": "Instruction is required"
        }
    ],
    "required": true,
    "visible": true
}
```

![](https://3506001968-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FWu4HIWGkb7dD4y0Kup4W%2Fuploads%2FBu6gON5ufCuY3Qf8Y1p4%2FrichText.png?alt=media\&token=f5b982fa-9894-42fd-96eb-6e5cac4acc79)

### **Keywords**

```
{
    "code": "keywords",
    "visible": true,
    "editable": true,
    "dataType": "list",
    "name": "Keywords",
    "renderingHints": {
        "class": "sb-g-col-lg-1"
    },
    "description": "Keywords for the content",
    "inputType": "keywords",
    "label": "keywords",
    "placeholder": "Enter Keywords",
    "required": false,
    "validations": [] // when no validation is required on field
}
```

![](https://3506001968-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FWu4HIWGkb7dD4y0Kup4W%2Fuploads%2FG21rwxEaEN8s1k22YRIE%2Fkeywords.png?alt=media\&token=158fcf6b-99b8-46dd-b58e-be9801724473)

### Multi Select

```
{
    "code": "additionalCategories",
    "dataType": "list",
    "description": "Additonal Category of the Content",
    "editable": true,
    "inputType": "nestedselect",
    "label": "Additional Category",
    "name": "Additional Category",
    "placeholder": "Select Additional Category",
    "renderingHints": {
        "class": "sb-g-col-lg-1"
    },
    "default": "",
    "required": false,
    "visible": true
}
```

![](https://3506001968-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FWu4HIWGkb7dD4y0Kup4W%2Fuploads%2FIRi8E3nuSfjrOQKEuKtC%2Fnestedselect.png?alt=media\&token=f7ce75d2-85f1-40ed-9c3a-b2834831122b)

### **Single Select**

```
{
    "code": "board",
    "default": "",
    "visible": true,
    "depends": [],
    "editable": true,
    "dataType": "text",
    "renderingHints": {
        "class": "sb-g-col-lg-1"
    },
    "description": "Board",
    "label": "Board/Syllabus",
    "required": false,
    "name": "Board/Syllabus",
    "inputType": "select",
    "placeholder": "Select Board/Syllabus"
}
```

![](https://3506001968-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FWu4HIWGkb7dD4y0Kup4W%2Fuploads%2Fj4MSCh6HGEHV4Jb8Mgl1%2Fselect.png?alt=media\&token=87d5d801-6834-4368-ade5-6d11a33135b4)

### **Topic Selector**

```
{
    "code": "topic",
    "visible": true,
    "editable": true,
    "dataType": "list",
    "depends": [
        "board",
        "medium",
        "gradeLevel",
        "subject"
    ],
    "default": "",
    "renderingHints": {
        "class": "sb-g-col-lg-1"
    },
    "name": "Topic",
    "description": "Choose a Topics",
    "inputType": "topicselector",
    "label": "Topics",
    "placeholder": "Choose Topics",
    "required": false
}
```

![](https://3506001968-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FWu4HIWGkb7dD4y0Kup4W%2Fuploads%2F7DDtaUYgheXE2kzCRS9L%2Ftopicselect1.png?alt=media\&token=3c4bd229-ba73-4c65-b54e-6c6cf72f9a7d)

![](https://3506001968-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FWu4HIWGkb7dD4y0Kup4W%2Fuploads%2FjUxbHKnGf3aKg6zWPcpW%2Ftopicselect2.png?alt=media\&token=73419922-cad0-4ab1-b11b-04b9dc9736fb)

### **Checkbox**

```
{
    "code": "showSolutions",
    "dataType": "text",
    "description": "Show Solution",
    "editable": true,
    "inputType": "checkbox",
    "label": "Show Solution",
    "name": "Show Solution",
    "placeholder": "Show Solution",
    "renderingHints": {
        "class": "sb-g-col-lg-1"
    },
    "required": false,
    "visible": true
}
```

![](https://3506001968-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FWu4HIWGkb7dD4y0Kup4W%2Fuploads%2FhhrmnGvIpM5q1mVZKrqz%2Fcheckbox.png?alt=media\&token=53381d93-9bfd-4f25-aca0-7f08e1092a31)

**Timer**

```
{
    "code": "maxTime",
    "visible": true,
    "editable": true,
    "dataType": "text",
    "name": "MaxTimer",
    "renderingHints": {
        "class": "sb-g-col-lg-1 required"
    },
    "description": "MaxTime for the content",
    "inputType": "timer",
    "label": "Max Time",
    "placeholder": "HH:mm:ss",
    "required": true,
    "validations": [
        {
            "type": "required", // for adding required validation
            "message": "Maxtime is required"
        },
        {
            "type": "maxTime", // for adding maxTime validation, its only applicable for timer fields
            "value": "05:30",
            "message": "Maxtime should be less than or equal to 05:30"
        },
        {
            "type": "minTime", for adding minTime validation, its only applicable for timer field
            "value": "00:01",
            "message": "Maxtime should be greater than 00:00"
        }
    ]
}
```

![](https://3506001968-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FWu4HIWGkb7dD4y0Kup4W%2Fuploads%2FXYrWT1hCI1itxKP5UDvZ%2Ftimer.png?alt=media\&token=015647c7-cd95-4cdd-9e86-2f3f6cfdf591)

## How to define the width of fields and add asterisks(<mark style="color:red;">\*</mark>) on field label <a href="#root-node-form" id="root-node-form"></a>

**renderHints** is the property defines whether the fields should take space of two column or one column and to add asterisks(<mark style="color:red;">\*</mark>) in the label of field to make it look required field

* Two column space fields should have renderHints as:

```
"renderingHints": {
                        "class": "sb-g-col-lg-2"
                   }
```

![sb-g-col-lg-2](https://3506001968-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FWu4HIWGkb7dD4y0Kup4W%2Fuploads%2FSACOpzmtP6uFGkTxsMZM%2FrichText.png?alt=media\&token=f6bf4628-4f43-4e06-8865-0cb0a58424a4)

* One column space fields should have renderHints as:

```
"renderingHints": {
                        "class": "sb-g-col-lg-1"
                   }
```

![sb-g-col-lg-1](https://3506001968-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FWu4HIWGkb7dD4y0Kup4W%2Fuploads%2F69Lt3VJjeoIyeoDF5QyE%2Fsb-col-lg1.png?alt=media\&token=54235d2d-834a-4c46-9a1a-db478aaa997f)

* For adding asterisks in the Label of field

```
"renderingHints": {
                        "class": "required"
                   }
```

Note:  sb-g-col-lg-1 or sb-g-col-lg-2 can be used with combination of required as:

```
"renderingHints": {
                        "class": "sb-g-col-lg-1 required"
                    }
```

or

```
"renderingHints": {
                        "class": "sb-g-col-lg-2 required"
                    }
```

## How to add validations on fields <a href="#root-node-form" id="root-node-form"></a>

Validation property defines the different types of validations which can be done on fields

We are using required, maxLength,compare

* **required**: for making the field to be required you need to add the required validations as:

```
"validations": [
    {
        "type": "required",
        "message": "Any message to be shown below the field if field is not filled"
    }
  ]
```

* **maxLength:** for adding restriction of length on field text, textarea, richtext.

```
  "validations": [
    {
        "type": "maxLength",
        "value": "120",
        "message": "Input is Exceeded"
    }
]
```

* **compare:** for comparing one field with another.

In the case of timer warningTime should be less than or equal to maxTime so in warning time we can add the compare validation as:

```
"validations": [
    {
        "type": "compare",
        "criteria": {
            "<=": [
                "maxTime"
            ]
        },
        "message": "warning time should be less than max timer"
    }
]
```

## Sample QuestionSet form <a href="#root-node-form" id="root-node-form"></a>

![QuestionSet form](https://3506001968-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FWu4HIWGkb7dD4y0Kup4W%2Fuploads%2FhTkuLCbwrMRzUnzA5kvQ%2FrootNodeForm.png?alt=media\&token=b632f389-078e-4d95-851b-d431b5bc5645)

## **Sample Section Form**

![Sample section form](https://3506001968-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FWu4HIWGkb7dD4y0Kup4W%2Fuploads%2F2XfYpslEnDWRTfKEns7F%2FsectionForm.png?alt=media\&token=f0e4a4fd-94f8-45b9-8516-83cf10c3ae7b)

## Sample Publish Check List <a href="#publish-check-list" id="publish-check-list"></a>

![Sample publish checklist](https://3506001968-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FWu4HIWGkb7dD4y0Kup4W%2Fuploads%2F9fS6ch6hYhfN0SwYSsl7%2FpublishChecklist.png?alt=media\&token=82254d5b-1e35-4543-b3e9-da19f7fbeac8)


# Question set Player

### System Requirements <a href="#system-requirements" id="system-requirements"></a>

To install the player, ensure that your laptop or desktop has the following minimum system requirements:

* Operating System: Windows 7 and above, or 4.2 Mac OS X 10.0 and above/Linux
* RAM: >2GB
* CPU: 2 cores, >2 GHz

### How to setup

{% embed url="<https://inquiry.sunbird.org/use/developer-installation/question-set-player/installation>" %}

### NPM Repository

#### Web Component

{% embed url="<https://www.npmjs.com/package/@project-sunbird/sunbird-quml-player-web-component>" %}

#### Angular Library

{% embed url="<https://www.npmjs.com/package/@project-sunbird/sunbird-quml-player>" %}


# Installation

## :label: System requirements <a href="#system-requirements" id="system-requirements"></a>

The following are prerequisites to using the QuML player&#x20;

| Softwares / Frameworks | Version |
| ---------------------- | ------- |
| Angular                | 15.2.3  |

{% hint style="info" %}
The QuML player is tested against the above version of angular. Updating to the latest versions needs further testing.

For more information on installing angular, see [angular.io/cli](https://angular.io/cli). If you are unsure what version of Angular runs on your system, run “ng version” in a command prompt (terminal) window.\
\
Angular requires an [active LTS or maintenance LTS](https://nodejs.org/about/releases) version of Node.js.\
\
Refer here for more details on [Angular CLI dependencies](https://www.npmjs.com/package/@angular/cli/v/9.1.12?activeTab=readme)
{% endhint %}

## :diamond\_shape\_with\_a\_dot\_inside: The QuML player for the Sunbird!

The QuML player library components are powered by Angular. This player is primarily designed to be used on Sunbird consumption platforms (mobile app, web portal, offline desktop app) to drive reusability and maintainability, hence reducing the redundant development effort significantly, and it can be integrated with any platform irrespective of the platforms and the frontend frameworks. It is exported not only as an [angular library](#use-as-angular-library-in-angular-app) but also as a [web component](#use-as-web-components) aims to make it easy to share, discover, and reuse web components. It creates a framework agnostic way of composing and repurposing code.

## 📑 Getting started with integration steps

The QuML player can be integrated as a web component and also as an angular library in angular application projects and it can also be integrated into any mobile framework as a web component.

## Use as web components 🌏

QuML Library can also be used as a web component which means if your project does not use a JavaScript framework but prefers platform-based HTML, CSS, and JavaScript, you may wish to use QuML Library in this way. Simply follow the below-mentioned steps to use it in plain JavaScript project:

* Insert [library](https://github.com/Sunbird-inQuiry/player/blob/main/web-component/sunbird-quml-player.js) as below:

  ```
  <script  type="text/javascript"  src="sunbird-quml-player.js"></script>
  ```
* Create an asset folder and copy all the files from [here](https://github.com/Sunbird-inQuiry/player/tree/main/web-component/assets), the library requires these assets internally to work well.
* Create a custom HTML element: `sunbird-quml-player`

  ```
  const  qumlPlayerElement = document.createElement('sunbird-quml-player');
  ```
* Get sample playerConfig from here: [playerConfig](https://github.com/Sunbird-inQuiry/player/blob/main/projects/quml-demo-app/src/app/quml-library-data.ts) and pass data using `player-config`

  ```
  qumlPlayerElement.setAttribute('player-config', JSON.stringify(playerConfig));
  ```

  **Note:** Attribute should be in **string** type
* Pass the Question List API baseUrl for, e.g.

  ```
  window.questionListUrl = 'https://dev.inquiry.sunbird.org/api/question/v2/list';
  ```
* Listen for the output events: `playerEvent` and `telemetryEvent`

  ```
  qumlPlayerElement.addEventListener('playerEvent', (event) => {
    console.log("On playerEvent", event);
  });
  qumlPlayerElement.addEventListener('telemetryEvent', (event) => {
    console.log("On telemetryEvent", event);
  });
  ```
* Append this element to the existing element

  ```
  const myPlayer = document.getElementById("my-player");
  myPlayer.appendChild(qumlPlayerElement);
  ```
* ▶️ Refer demo [example](https://github.com/Sunbird-inQuiry/player/blob/main/web-component-examples/vanilla-js/index.html)

## Use as web component in the Angular app

* Run command

  ```
  npm i @project-sunbird/sunbird-quml-player-web-component
  ```
* Add these entries in an angular JSON file inside assets, scripts, and styles like below

  ```
  "assets": [
    "src/favicon.ico",
    "src/assets",
    {
      "glob": "**/*.*",
      "input": "./node_modules/@project-sunbird/sunbird-quml-player-web-component/assets",
      "output": "/assets/"
    }
  ],
  "styles": [
    "src/styles.scss",
    "node_modules/@project-sunbird/sunbird-quml-player-web-component/styles.css"
  ],
  "scripts": [
    "node_modules/@project-sunbird/sunbird-quml-player-web-component/sunbird-quml-player.js"
  ]
  ```
* Import CUSTOM\_ELEMENTS\_SCHEMA in the app module and add it to the NgModule as part of schemas like below

  ```
  ...
  import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
  ...

  @NgModule({
   ...
   schemas: [CUSTOM_ELEMENTS_SCHEMA],
   ...
  })
  ```
* Integrating sunbird-quml-player web component in the angular component

  Create a viewChild in HTML template of the angular component like

  ```
  <div #qumlPlayer></div>
  ```

  Refer to the `viewChild` in the ts file of the component and create the QuML player using the `document.createElement`, then attach the player config and listen to the player and telemetry events like below and since we are rendering using `viewChild`these steps should be under the `ngAfterViewInit` hook of the angular component.

  ```
  ....

  @ViewChild('qumlPlayer') qumlPlayer: ElementRef;

    ....
   ngAfterViewInit() {
      const playerConfig = <Config need be added>;
        const qumlElement = document.createElement('sunbird-quml-player');
        qumlElement.setAttribute('player-config', JSON.stringify(playerConfig));

        qumlElement.addEventListener('playerEvent', (event) => {
          console.log("On playerEvent", event);
        });

        qumlElement.addEventListener('telemetryEvent', (event) => {
          console.log("On telemetryEvent", event);
        });
        this.qumlPlayer.nativeElement.append(qumlElement);
    }
    ....
  ```

  **Note:**: Click to see the mock - [playerConfig](https://github.com/Sunbird-inQuiry/player/blob/main/projects/quml-demo-app/src/app/quml-library-data.ts) and send the input config as a string
* Pass the Question List API baseUrl for, e.g.

  ```
  ngAfterViewInit() {
    ...
    (window as any).questionListUrl = "https://dev.inquiry.sunbird.org/api/question/v2/list";
    ...
  }
  ```
* You're done! Sunbird QuML Player is now ready to play in your application. Use the following CLI command to run your application locally

  ```
  npm run start
  ```

  To see your application in the browser, Go to [http://localhost:4200](http://localhost:4200/).

## Use as Angular library in Angular app

For help in getting started with a new Angular app, check out the [Angular CLI](https://angular.io/cli). If you have an Angular ≥ 9 CLI project, you could simply use our schematics to add sunbird-quml-player library to it.

For existing apps, follow the below-mentioned steps:

### 🏷️ Installation

Just run the following:

```
ng add @project-sunbird/sunbird-quml-player
```

It will install sunbird-quml-player for the default application specified in your `angular.json`. If you have multiple projects, and you want to target a specific application, you could specify the `--project` option

```
ng add @project-sunbird/sunbird-quml-player --project myProject
```

Schematics will create `question-cursor-implementation.service.ts`. Please update the `listUrl` in it. For more information refer [question-cursor-implementation.service.ts](https://github.com/Sunbird-inQuiry/player/blob/main/projects/quml-demo-app/src/app/question-cursor-implementation.service.ts) and do not forget to add your question list API URL here, for example&#x20;

```
listUrl = "https://dev.inquiry.sunbird.org/api/question/v2/list";
```

#### Manual installation

If you prefer not to use schematics or want to add `sunbird-quml-player` to an older project, you'll need to do the following:

<details>

<summary>Click here to show detailed instructions!</summary>

#### 🏷️ Step 1: Install Packages

These are the peer Dependencies of the library, need to be installed in order to use this library.

```
npm install @project-sunbird/sunbird-quml-player --save
npm install @project-sunbird/sb-styles --save
npm install @project-sunbird/client-services --save
npm install bootstrap@^4.6.2 --save
npm install jquery --save
npm install katex --save
npm install lodash-es --save
npm install ngx-bootstrap@^10.0.0 --save
```

Note: *As QuML library is build with angular version 15, we are using **bootstrap@^4.6.2** and **ngx-bootstrap@^10.0.0** which are the compatible versions. For more reference Check compatibility document for ng-bootstrap* [*here*](https://valor-software.com/ngx-bootstrap/#/documentation#compatibility)

### 🏷️ Step 2: Add question-cursor-implementation.service

Create a **question-cursor-implementation.service.ts** in a project and which will implement the `QuestionCursor` abstract class.\
`QuestionCursor` is an abstract class, exported from the library, which needs to be implemented. Basically, it has some methods which should make an API request over HTTP

For more information refer [question-cursor-implementation.service.ts](https://github.com/Sunbird-inQuiry/player/blob/main/projects/quml-demo-app/src/app/question-cursor-implementation.service.ts) and do not forget to add your question list API URL here, for example: listUrl = "<https://dev.inquiry.sunbird.org/api/question/v2/list>";

#### 🏷️ Step 3: Include the styles, scripts and assets in angular.json

Add the following under `architect.build.assets` for default project

```
{
  ...
  "build": {
    "builder": "@angular-devkit/build-angular:browser",
    "options": {
      ...
      ...
      "assets": [
        ...
        ...
        {
         "glob": "**/*.*",
         "input": "./node_modules/@project-sunbird/sunbird-quml-player/lib/assets/",
         "output": "/assets/"
        }
      ],
      "styles": [
        ...
        "src/styles.css",
        "./node_modules/@project-sunbird/sb-styles/assets/_styles.scss",
        "./node_modules/@project-sunbird/sunbird-quml-player/lib/assets/styles/quml-carousel.css",
        "./node_modules/katex/dist/katex.min.css"
      ],
      "scripts": [
        ...
        "./node_modules/katex/dist/katex.min.js",
        "./node_modules/jquery/dist/jquery.min.js"
      ]
    }
  }
  ...
  ...
},
```

### 🏷️ Step 4: Import the modules and components

Import the required modules such as **CarouselModule**, **QumlLibraryModule**, **HttpClientModule** and **question-cursor-implementation.service** as below:

```
  import { HttpClientModule } from '@angular/common/http';
  import { QumlLibraryModule, QuestionCursor } from '@project-sunbird/sunbird-quml-player';
  import { CarouselModule } from 'ngx-bootstrap/carousel';
  import { QuestionCursorImplementationService } from './question-cursor-implementation.service';

  @NgModule({
   ...

   imports: [ QumlLibraryModule, CarouselModule.forRoot(), HttpClientModule ],
   providers: [{
     provide: QuestionCursor,
     useClass: QuestionCursorImplementationService
   }]

   ...
  })

 export class AppModule { }
```

</details>

Note: To avoid CORS errors, add proxy configuration for API's refer - [proxy.conf.json](https://github.com/Sunbird-inQuiry/player/blob/main/projects/quml-demo-app/src/proxy.conf.json)

### 🏷️ Send input to render QuML player

Users can get a response from the `api/questionset/v1/hierarchy/:do_id` or can use the provided mock config for the demo

Use the mock config in your component to send input to the QuML player as `playerConfig` Click to see the mock - [samplePlayerConfig](https://github.com/Sunbird-inQuiry/player/blob/main/projects/quml-demo-app/src/app/quml-library-data.ts)

```
<quml-main-player [playerConfig]="samplePlayerConfig" ><quml-main-player>
```

### 🟠 Available components

| Feature     | Notes                      | Selector         | Code                                                                   | Input        | Output                      |
| ----------- | -------------------------- | ---------------- | ---------------------------------------------------------------------- | ------------ | --------------------------- |
| QuML Player | Can be used to render QuML | quml-main-player | *`<quml-main-player [playerConfig]="playerConfig"><quml-main-player>`* | playerConfig | playerEvent, telemetryEvent |

#### 🔻 Input Parameters

playerConfig: Object - \[`Required`]

```
{
  context: Object    // Optional. Information about the telemetry and default settings for quml API requests
  metadata: Object  // Question hierarchy response
  config: Object   // default player config such as sidebar menu list
}
```

**Note:** **context** is optional, which is used for capturing the telemetry event. If context is not passed in playerConfig telemetry event of player will not be captured.

* Here is the detailed description of playerConfig: [player-configuration](https://inquiry.sunbird.org/learn/product-and-developer-guide/question-set-player/player-configuration)

#### 🔻 Output Events

1. playerEvent() - It provides heartbeat event for each action performed in the player.
2. telemetryEvent() - It provides the sequence of telemetry events such as `START, INTERACT, IMPRESSION, SUMMARY, END`

### 🏷️ Run the application

You are done! Use the following CLI command to run your application locally

```
npm run start
```

To see your application in the browser, go to [http://localhost:4200](http://localhost:4200/).

## 📑 QuML Player Contribution Guide

### Repo Setup

* Install Node 14.20.x and Angular 15
* Clone the Repo with desired release branch - <https://github.com/Sunbird-inQuiry/player>
* Add the baseUrl in the *environment.ts* and *proxy.conf.json* files
* If there are any changes in API endpoints, update the *app.constant.ts* file
* Change the default content ID in the `app.component.ts` file if pointing to different baseUrl
* Run `npm i` in root folder
* Run `npm i` in `projects/quml-library`
* Open two terminal windows (on the root folder)
* Run `npm run build` once this run completes, run the next command - let it be running on 1st terminal window
* Run `npm run serve` on the second terminal window (This will copy assets from the `quml-library` to the library dist folder)
* Now it will be served on `http://localhost:4200/`
* To run the web-component `npm run build-web-component`


# Release Plan & Calendar

{% embed url="<https://docs.google.com/spreadsheets/d/1HZwE4XXIzQQwiXlnLfEhI-f5hypmaSoEqruAS9PCil0/edit#gid=995731450>" %}




---

[Next Page](/llms-full.txt/1)

