# xAPI.js

Communicate over xAPI using JavaScript.

**xAPI.js** is a collection of strongly typed JavaScript libraries for enabling learning content and learning systems to speak to each other over the xAPI protocol. They are fully compliant to the official specifications provided by the [ADL initative](https://www.adlnet.gov).

## Wrapper Library

For communicating with an LRS directly using xAPI, use the xAPI Wrapper Library.

{% content-ref url="/pages/-M7ZAeXAVoPnGx1KIftl" %}
[xAPI Wrapper Library](/xapi-wrapper-library/introduction)
{% endcontent-ref %}

## Profile Libraries

If you wish to use a standardised profile to communicate with an LRS, use one of the profile libraries.

{% content-ref url="/pages/-M7ZEdX70AFL7ATsZtiI" %}
[cmi5 Profile Library](/cmi5-profile-library/introduction)
{% endcontent-ref %}


# Introduction

## Overview

The **xAPI.js Wrapper Library** is a strongly typed JavaScript library for enabling learning content and learning systems to speak to each other. It is a complete implementation and fully compliant against the [xAPI Specification](https://github.com/adlnet/xAPI-Spec) (v1.0.0 - v1.0.3).

For an example implementation of this library, you can find the [xAPI Wrapper Demo](https://github.com/xapijs/xapi-demo) source on GitHub.

## First Steps

{% content-ref url="/pages/-M7Z5bjoPWQtoEMZjO5C" %}
[Getting Started](/xapi-wrapper-library/getting-started)
{% endcontent-ref %}

{% content-ref url="/pages/-M7ZC5mnhHFXvI2\_imsH" %}
[The XAPI Class](/xapi-wrapper-library/xapi-class)
{% endcontent-ref %}

## Resource APIs

### The Statement Resource API

{% content-ref url="/pages/-M7ZCekLNwrybchgRgsW" %}
[Statement Resource](/xapi-wrapper-library/statement-resource)
{% endcontent-ref %}

### The Document Resource APIs

{% content-ref url="/pages/-M7ZD6AK5io42P9CHGzz" %}
[State Resource](/xapi-wrapper-library/state-resource)
{% endcontent-ref %}

{% content-ref url="/pages/-M7ZDdFJOAlN4-yO5gKy" %}
[Activity Profile Resource](/xapi-wrapper-library/activity-profile-resource)
{% endcontent-ref %}

{% content-ref url="/pages/-M7ZED51NyQEUoqsiuxk" %}
[Agent Profile Resource](/xapi-wrapper-library/agent-profile-resource)
{% endcontent-ref %}

### Other Resource APIs

{% content-ref url="/pages/-MGjhz3OHRZz5Zm4vcl5" %}
[Activities Resource](/xapi-wrapper-library/activities-resource)
{% endcontent-ref %}

{% content-ref url="/pages/-M7ZC2i7hw6GhC5c5ymO" %}
[About Resource](/xapi-wrapper-library/about-resource)
{% endcontent-ref %}

{% content-ref url="/pages/-M7ZDz7R-B0\_8\_j1TeiN" %}
[Agents Resource](/xapi-wrapper-library/agents-resource)
{% endcontent-ref %}

## Helper Methods and Constants

{% content-ref url="/pages/-MHD5XLOtCCt4wNGV7wv" %}
[Helpers](/xapi-wrapper-library/helpers)
{% endcontent-ref %}

{% content-ref url="/pages/-MHD2c8yQsUil-BOh4XG" %}
[Verbs](/xapi-wrapper-library/verbs)
{% endcontent-ref %}

{% content-ref url="/pages/-MHD37JNgN9no1fr5\_2Y" %}
[Attachment Usages](/xapi-wrapper-library/attachment-usages)
{% endcontent-ref %}


# Getting Started

How to get the library up and running in your project.

The library has been configured to work in multiple environments:

* UMD (Browser, client-side applications)
* ESM (Browser, client-side applications)
* CJS (Server-side applications)

## UMD (Browser, client-side applications)

For browser-based applications you can link the UMD package directly from unpkg.com in a `script` tag.

```markup
<script src="https://unpkg.com/@xapi/xapi"></script>

<script type="text/javascript">
  // Create LRS connection
  const endpoint = "https://my-lms.com/endpoint";
  const username = "username";
  const password = "password";
  const auth = XAPI.toBasicAuth(username, password);
  const xapi = new XAPI({
    endpoint: endpoint,
    auth: auth
  });

  // Create your statement
  const myStatement = { ... };

  // Send your statement
  xapi.sendStatement({
    statement: myStatement
  });
</script>
```

## ES Module (Browser, client-side applications)

For client-side applications built using imports, an ES Module is available for you to install and `import`  into your project.

```bash
npm i @xapi/xapi --save
```

```typescript
import XAPI, { Statement } from "@xapi/xapi";

// Create LRS connection
const endpoint = "https://my-lms.com/endpoint";
const username = "username";
const password = "password";
const auth = XAPI.toBasicAuth(username, password);
const xapi: XAPI = new XAPI({
  endpoint: endpoint,
  auth: auth
});

// Create your statement
const myStatement: Statement = { ... };

// Send your statement
xapi.sendStatement({
  statement: myStatement
});
```

## CJS (Server-side applications)

For server-side applications built using require, a CommonJS module is available for you to install and `require` into your project.

```bash
npm i @xapi/xapi --save
```

```javascript
const XAPI = require("@xapi/xapi");

const endpoint = "https://my-lms.com/endpoint";
const username = process.env.LRS_USERNAME || "";
const password = process.env.LRS_PASSWORD || "";
const auth = XAPI.toBasicAuth(username, password);
const xapi = new XAPI({
  endpoint: endpoint,
  auth: auth
});

// Create your statement
const myStatement = { ... };

// Send your statement
xapi.sendStatement({
  statement: myStatement
});
```

Alternatively, the module can also be imported using `.mjs`.

```javascript
import XAPI from "@xapi/xapi";

const endpoint = "https://my-lms.com/endpoint";
const username = process.env.LRS_USERNAME || "";
const password = process.env.LRS_PASSWORD || "";
const auth = XAPI.toBasicAuth(username, password);
const xapi = new XAPI({
  endpoint: endpoint,
  auth: auth
});

// Create your statement
const myStatement = { ... };

// Send your statement
xapi.sendStatement({
  statement: myStatement
});
```


# The XAPI Class

The xAPI class which manages the communication with the LRS.

## new XAPI()

To use any of the Resources, you will need to create a new instance of [XAPI](https://github.com/xapijs/xapi/tree/fd040c6f049f68fce317538626906de57ffebf44/src/XAPI.ts) with credentials.

```typescript
const endpoint = "https://my-lms.com/endpoint/";
const auth = XAPI.toBasicAuth(username, password);
const xapi = new XAPI({
  endpoint: endpoint,
  auth: auth
});
```

### **Parameters**

| Parameter | Type                                                                             | Required | Description                                                                                                                                                                       |
| --------- | -------------------------------------------------------------------------------- | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| endpoint  | string                                                                           | true     | The URL of the endpoint.                                                                                                                                                          |
| auth      | string                                                                           | false    | The `Authorization` header value to be appended to all requests. Defaults to `Basic 0g==`, which is equivalent of `Basic` followed by a base64 encoded version of the string `:`. |
| version   | [Versions](https://github.com/xapijs/xapi/blob/master/src/constants/Versions.ts) | false    | The version of xAPI to use. Defaults to  `1.0.3`.                                                                                                                                 |
| adapter   | [Adapter](https://github.com/xapijs/xapi/blob/develop/src/adapters/index.ts#L23) | false    | The underlying adapter to make HTTP requests with. Accepts  `axios`, `fetch` or a custom adapter function. Defaults to `axios`.                                                   |

### **Returns**

This returns an [XAPI](https://github.com/xapijs/xapi/tree/fd040c6f049f68fce317538626906de57ffebf44/src/XAPI.ts) object which you can use to communicate with the LRS.


# Statement Resource

Manages learner statements.

## sendStatement

Sends a statement to the LRS.

### **Examples**

#### **Example 1: Send Basic Statement**

```typescript
import XAPI, { Statement } from "@xapi/xapi";

// new XAPI() etc

const myStatement: Statement = {
  actor: {
    objectType: "Agent",
    name: "Test Agent",
    mbox: "mailto:hello@example.com"
  },
  verb: {
    id: "http://example.com/verbs/tested",
    display: {
        "en-GB": "tested"
    }
  },
  object: {
    objectType: "Activity",
    id: "https://github.com/xapijs/xapi"
  }
};

xapi.sendStatement({
  statement: myStatement
});
```

#### **Example 2: Send Embedded Attachment Statement**

```typescript
import CryptoJS from "crypto-js";
import { arrayBufferToWordArray } from "...";

const attachmentContent: string = "hello world";
const arrayBuffer: ArrayBuffer = new TextEncoder().encode(attachmentContent);

const myStatement: Statement = {
  // actor, verb, object etc,
  attachments: [{
    usageType: XAPI.AttachmentUsages.SUPPORTING_MEDIA,
    display: {
        "en-US": "Text Attachment"
    },
    description: {
        "en-US": `The text attachment contains "${attachmentContent}"`
    },
    contentType: "text/plain",
    length: arrayBuffer.byteLength,
    sha2: CryptoJS.SHA256(arrayBufferToWordArray(arrayBuffer)).toString()
  }]
}

xapi.sendStatement({
  statement: myStatement,
  attachments: [arrayBuffer]
});
```

This example requires [CryptoJS](https://cryptojs.gitbook.io/docs/) to generate a sha2 of the attachment data and [convert the array buffer to a word array](https://github.com/xapijs/xapi/blob/d7eac9d07166df5c1f995e17a8ac98bbee99c548/test/arrayBufferToWordArray.ts).

### **Parameters**

| Parameter   | Type                                                                                                                            | Required | Description                                             |
| ----------- | ------------------------------------------------------------------------------------------------------------------------------- | -------- | ------------------------------------------------------- |
| statement   | [Statement](https://github.com/xapijs/xapi/tree/fd040c6f049f68fce317538626906de57ffebf44/src/interfaces/Statement/Statement.ts) | true     | The statement you wish to send to the LRS.              |
| attachments | ArrayBuffer\[]                                                                                                                  | false    | An array of attachment data converted to `ArrayBuffer`. |

### **Returns**

This method returns an `AxiosPromise` with the success `data` containing a string array of statement IDs if successful, or if unsuccessful the rejection contains an error message.

## sendStatements

Sends multiple statements to the LRS.

#### **Example 1: Send Basic Statements**

```typescript
import XAPI, { Statement } from "@xapi/xapi";

// new XAPI() etc

const myStatement: Statement = {
  actor: {
    objectType: "Agent",
    name: "Test Agent",
    mbox: "mailto:hello@example.com"
  },
  verb: {
    id: "http://example.com/verbs/tested",
    display: {
        "en-GB": "tested"
    }
  },
  object: {
    objectType: "Activity",
    id: "https://github.com/xapijs/xapi"
  }
};

// Define another statement
const myStatementTwo: Statement = {
  ...myStatement
};

xapi.sendStatements({
  statements: [myStatement, myStatementTwo]
});
```

#### **Example 2: Send Embedded Attachment Statements**

```typescript
import CryptoJS from "crypto-js";
import { arrayBufferToWordArray } from "...";

const attachmentContent: string = "hello world";
const arrayBuffer: ArrayBuffer = new TextEncoder().encode(attachmentContent);

const myStatement: Statement = {
  // actor, verb, object etc,
  attachments: [{
    usageType: XAPI.AttachmentUsages.SUPPORTING_MEDIA,
    display: {
        "en-US": "Text Attachment"
    },
    description: {
        "en-US": `The text attachment contains "${attachmentContent}"`
    },
    contentType: "text/plain",
    length: arrayBuffer.byteLength,
    sha2: CryptoJS.SHA256(arrayBufferToWordArray(arrayBuffer)).toString()
  }]
}

// Define another statement
const myStatementTwo: Statement = {
  ...myStatement
};

// Send through the attachments in the same sequence as they
// appear in the statements, for brevity we are using the same
// attachment here twice

xapi.sendStatement({
  statements: [myStatement, myStatementTwo],
  attachments: [arrayBuffer, arrayBuffer]
});
```

This example requires [CryptoJS](https://cryptojs.gitbook.io/docs/) to generate a sha2 of the attachment data and [convert the array buffer to a word array](https://github.com/xapijs/xapi/blob/d7eac9d07166df5c1f995e17a8ac98bbee99c548/test/arrayBufferToWordArray.ts).

### **Parameters**

| Parameter   | Type                                                                                                                               | Required | Description                                             |
| ----------- | ---------------------------------------------------------------------------------------------------------------------------------- | -------- | ------------------------------------------------------- |
| statements  | [Statement](https://github.com/xapijs/xapi/tree/fd040c6f049f68fce317538626906de57ffebf44/src/interfaces/Statement/Statement.ts)\[] | true     | The statements you wish to send to the LRS.             |
| attachments | ArrayBuffer\[]                                                                                                                     | false    | An array of attachment data converted to `ArrayBuffer`. |

### **Returns**

This method returns an `AxiosPromise` with the success `data` containing a string array of statement IDs if successful, or if unsuccessful the rejection contains an error message.

## getStatement

To receive a single statement, you must use the `getStatement` method and pass the statement ID in the query. Optionally, you can provide additional parameters to the query to change the data format returned from the LRS.

### **Examples**

#### **Example 1: Get Basic Statement**

```typescript
xapi.getStatement({
  statementId: "abcdefgh-1234"
}).then((result: AxiosResponse<Statement>) => {
  const statement: Statement = result.data;
  // do stuff with `statement`
});
```

#### **Example 2: Get Embedded Attachment Statement**

```typescript
xapi.getStatement({
  statementId: "abcdefgh-1234",
  attachments: true
}).then((result: AxiosResponse<StatementResponseWithAttachments>) => {
  const parts: [Statement, ...Part[]] = result.data;
  const statement: Statement = parts[0];
  const attachment: unknown = parts[1];
})
```

### **Parameters**

| Parameter   | Type    | Required | Description                                                                                                                                                                                                                                                                                                                                                                                                                                      |
| ----------- | ------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| statementId | string  | true     | The identifier of the statement to request.                                                                                                                                                                                                                                                                                                                                                                                                      |
| attachments | boolean | false    | Whether to return the attachment(s) associated with the statement, if any.                                                                                                                                                                                                                                                                                                                                                                       |
| format      | string  | false    | <p>What human readable names and descriptions are included in the statement.</p><ul><li><code>exact</code> format returns the statements exactly as they were received by the LRS.</li><li><code>ids</code> only ids are returned with none of the human readable descriptions.</li><li><code>canonical</code> format requests the LRS to return its own internal definitions of objects, rather than those provided in the statement.</li></ul> |

### **Returns**

This method returns an `AxiosPromise` with the success `data` containing the [Statement](https://github.com/xapijs/xapi/tree/fd040c6f049f68fce317538626906de57ffebf44/src/interfaces/Statement/Statement.ts) of the supplied `statementId`.

When getting a statement with `attachments: true`, the success `data` is returned as an array. The first array item is of type `Statement`, and the following are of type `Part`  and are the attachments supplied with the statement.

## getStatements

To receive an array of statements based upon a query, you must use the `getStatements` method. See the [GetStatementsQuery](https://github.com/xapijs/xapi/tree/fd040c6f049f68fce317538626906de57ffebf44/src/interfaces/XAPI/GetStatementsQuery.ts) interface for a full list of ways to create your query.

### **Example**

```typescript
const myAgent: Agent = {...};

xapi.getStatements({
  agent: myAgent
}).then((result: AxiosResponse<StatementsResponse>) => {
  const statementsResponse: StatementsResponse = result.data;
  // do stuff with `statementsResponse.statements`
});
```

### **Parameters**

| Parameter           | Type                  | Required | Description                                                                         |
| ------------------- | --------------------- | -------- | ----------------------------------------------------------------------------------- |
| agent               | Agent                 | false    | The agent to filter the query by.                                                   |
| verb                | string                | false    | The verb identifier to filter the query by.                                         |
| activity            | string                | false    | The activity identifier to filter the query by.                                     |
| registration        | string                | false    | The registration to filter the query by.                                            |
| related\_activities | boolean               | false    | Whether to include any activity in the statement as part of the filter to query by. |
| related\_agents     | boolean               | false    | Whether to include any agent in the statement as part of the filter to query by.    |
| since               | Timestamp (ISOString) | false    | Filters only statements after the given Timestamp.                                  |
| until               | Timestamp (ISOString) | false    | Filters only statements before the given Timestamp.                                 |
| limit               | number                | false    | Number of statements to return.                                                     |
| ascending           | boolean               | false    | Determines whether to return the statements in ascending order.                     |
| attachments         | boolean               | false    | Determines whether to return the attachments for the resulting statements.          |

### **Returns**

This method returns an `AxiosPromise` with the success `data` containing a [StatementsResponse](https://github.com/xapijs/xapi/tree/fd040c6f049f68fce317538626906de57ffebf44/src/interfaces/XAPI/StatementsResponse.ts) object.

When getting statements with `attachments: true`, the success `data` is returned as an array. The first array item is of type `StatementsResponse`, and the following are of type `Part`  and are the attachments supplied with the statement.

## getMoreStatements

To be used in conjunction with `getStatements`. If the `more` property is populated on your initial request, more data is available. Send the value of the `more` property to this method to get the next page of statements.

### **Example**

```typescript
const myAgent: Agent = {...};

xapi.getStatements({
  agent: myAgent
}).then((result: AxiosReponse<StatementsResponse>) => {
  // data
  xapi.getMoreStatements({
    more: result.data.more
  }).then((result: AxiosResponse<StatementsResponse>) => {
    // more data
  });
});
```

### **Parameters**

| Parameter | Type   | Required | Description                                                                             |
| --------- | ------ | -------- | --------------------------------------------------------------------------------------- |
| more      | string | true     | The `more` property passed from the `getStatements`/`getMoreStatements` query response. |

### **Returns**

This method returns an `AxiosPromise` with the success `data` containing a [StatementsResponse](https://github.com/xapijs/xapi/tree/fd040c6f049f68fce317538626906de57ffebf44/src/interfaces/XAPI/StatementsResponse.ts) object or an Array containing `StatementsResponse` and `Part` if the original query has `attachments: true`. When working in TypeScript you may need to cast your `result.data` return type explicitly as `StatementsResponse` or `StatementsResponseWithAttachments`.

## voidStatement

Voids a statement in the LRS by the supplied Actor.

### **Example**

```typescript
const actor: Actor = { ... };
xapi.voidStatement({
  actor: actor,
  statementId: "abcdefgh-1234"
});
```

**Parameters**

| Parameter   | Type                                                                                                                          | Required | Description                                                   |
| ----------- | ----------------------------------------------------------------------------------------------------------------------------- | -------- | ------------------------------------------------------------- |
| actor       | [Actor](https://github.com/xapijs/xapi/tree/fd040c6f049f68fce317538626906de57ffebf44/src/interfaces/Statement/Actor/Actor.ts) | true     | The Actor who is voiding the statement e.g. an administrator. |
| statementId | string                                                                                                                        | true     | The statement to be voided.                                   |

### **Returns**

This method returns an `AxiosPromise` with the success `data` containing an array of statement ID strings of the void statement.

## voidStatements

Voids multiple statements in the LRS by the supplied Actor.

### **Example**

```typescript
const actor: Actor = { ... };
xapi.voidStatements({
   actor: actor,
   statementIds: ["abcdefgh-1234", "ijklmnop-5678"]
});
```

**Parameters**

| Parameter    | Type                                                                                                                          | Required | Description                                                   |
| ------------ | ----------------------------------------------------------------------------------------------------------------------------- | -------- | ------------------------------------------------------------- |
| actor        | [Actor](https://github.com/xapijs/xapi/tree/fd040c6f049f68fce317538626906de57ffebf44/src/interfaces/Statement/Actor/Actor.ts) | true     | The Actor who is voiding the statement e.g. an administrator. |
| statementIds | string\[]                                                                                                                     | true     | The statements to be voided.                                  |

### **Returns**

This method returns an `AxiosPromise` with the success `data` containing an array of statement ID strings of the void statements.

## getVoidedStatement

To receive a single voided statement, you must use the `getVoidedStatement` method and pass the original statement ID in the query (not the original statement's void statement id). Optionally, you can provide additional parameters to the query to change the data format returned from the LRS.

### **Example**

```typescript
xapi.getVoidedStatement({
  statementId: "abcdefgh-1234"
}).then((result: AxiosResponse<Statement>) => {
  const voidStatement: Statement = result.data;
  // do stuff with `voidStatement`
});
```

### **Parameters**

| Parameter         | Type    | Required | Description                                                                                                                                                                                                                                                                                                                                                                                                                                             |
| ----------------- | ------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| voidedStatementId | string  | true     | The identifier of the voided statement to request.                                                                                                                                                                                                                                                                                                                                                                                                      |
| attachments       | boolean | false    | Whether to return the attachment(s) associated with the voided statement, if any.                                                                                                                                                                                                                                                                                                                                                                       |
| format            | string  | false    | <p>What human readable names and descriptions are included in the voided statement.</p><ul><li><code>exact</code> format returns the statements exactly as they were received by the LRS.</li><li><code>ids</code> only ids are returned with none of the human readable descriptions.</li><li><code>canonical</code> format requests the LRS to return its own internal definitions of objects, rather than those provided in the statement.</li></ul> |

### **Returns**

This method returns an `AxiosPromise` with the success `data` containing the [Statement](https://github.com/xapijs/xapi/tree/fd040c6f049f68fce317538626906de57ffebf44/src/interfaces/Statement/Statement.ts) of the supplied `voidedStatementId`.

When getting a statement with `attachments: true`, the success `data` is returned as an array. The first array item is of type `Statement`, and the following are of type `Part`  and are the attachments supplied with the statement.


# State Resource

Manages learner state for an activity.

## createState

Creates or merges into a state document by the agent, activity identifier and state identifier.

### **Example**

```typescript
const agent: Agent = {
  objectType: "Agent",
  name: "Test Agent",
  mbox: "mailto:test@agent.com"
};
const activityId: string = "https://example.com/activities/test-activity";
const stateId: string = activityId + "/states/myStateId";
const state: DocumentJson = {
  myKey: "myValue"
};

xapi.createState({
  agent: agent,
  activityId: activityId,
  stateId: stateId,
  state: state
});
```

### **Parameters**

| Parameter    | Type                                                                                                                            | Required | Description                                                  |
| ------------ | ------------------------------------------------------------------------------------------------------------------------------- | -------- | ------------------------------------------------------------ |
| agent        | [Agent](https://github.com/xapijs/xapi/tree/fd040c6f049f68fce317538626906de57ffebf44/src/interfaces/Statement/Actor/Agent.ts)   | true     | The agent experiencing the AU.                               |
| activityId   | string                                                                                                                          | true     | The URI of the activity.                                     |
| stateId      | string                                                                                                                          | true     | The URI of the state to be created or merged into.           |
| state        | [DocumentJson](https://github.com/xapijs/xapi/blob/d7eac9d07166df5c1f995e17a8ac98bbee99c548/src/resources/document/Document.ts) | true     | The state data to be stored.                                 |
| registration | string                                                                                                                          | false    | The registration associated with this state.                 |
| etag         | string                                                                                                                          | false    | The ETag of the original document if merging.                |
| matchHeader  | string                                                                                                                          | false    | The ETag header type. Accepts "If-Match" or "If-None-Match". |

### **Returns**

This method returns an `AxiosPromise`  with empty success `data` if successful.

## setState

Creates or overwrites a state document by the agent, activity identifier and state identifier.

### **Example**

```typescript
const agent: Agent = {
  objectType: "Agent",
  name: "Test Agent",
  mbox: "mailto:test@agent.com"
};
const activityId: string = "https://example.com/activities/test-activity";
const stateId: string = activityId + "/states/myStateId";
const state: Document = {
  myKey: "myValue"
};

xapi.setState(agent, activityId, stateId, state);
```

### **Parameters**

| Parameter    | Type                                                                                                                          | Required | Description                                                  |
| ------------ | ----------------------------------------------------------------------------------------------------------------------------- | -------- | ------------------------------------------------------------ |
| agent        | [Agent](https://github.com/xapijs/xapi/tree/fd040c6f049f68fce317538626906de57ffebf44/src/interfaces/Statement/Actor/Agent.ts) | true     | The agent experiencing the AU.                               |
| activityId   | string                                                                                                                        | true     | The URI of the activity.                                     |
| stateId      | string                                                                                                                        | true     | The URI of the state to be created or overwritten.           |
| state        | [Document](https://github.com/xapijs/xapi/blob/d7eac9d07166df5c1f995e17a8ac98bbee99c548/src/resources/document/Document.ts)   | true     | The state data to be stored.                                 |
| registration | string                                                                                                                        | false    | The registration associated with this state.                 |
| etag         | string                                                                                                                        | false    | The ETag of the original document if overwriting.            |
| matchHeader  | string                                                                                                                        | false    | The ETag header type. Accepts "If-Match" or "If-None-Match". |
| contentType  | string                                                                                                                        | false    | The content type of the state data.                          |

### **Returns**

This method returns an `AxiosPromise` with empty success `data` if successful.

## getStates

Gets an array of state identifiers by the agent and activity identifier.

### **Example**

```typescript
const agent: Agent = {
  objectType: "Agent",
  name: "Test Agent",
  mbox: "mailto:test@agent.com"
};
const activityId: string = "https://example.com/activities/test-activity";

xapi.getStates({
  agent: agent,
  activityId: activityId
}).then((result: AxiosResponse<string[]>) => {
  const states: string[] = result.data;
  console.log(states); // ["https://example.com/activities/test-activity/states/myStateId"]
});
```

### **Parameters**

| Parameter      | Type                                                                                                                          | Required | Description                                          |
| -------------- | ----------------------------------------------------------------------------------------------------------------------------- | -------- | ---------------------------------------------------- |
| agent          | [Agent](https://github.com/xapijs/xapi/tree/fd040c6f049f68fce317538626906de57ffebf44/src/interfaces/Statement/Actor/Agent.ts) | true     | The agent experiencing the AU.                       |
| activityId     | string                                                                                                                        | true     | The URI of the activity.                             |
| registration   | string                                                                                                                        | false    | The registration associated with this state.         |
| since          | Timestamp                                                                                                                     | false    | Only return States stored since specified Timestamp. |
| useCacheBuster | boolean                                                                                                                       | false    | Enables cache busting.                               |

### **Returns**

This method returns an `AxiosPromise` with the success `data` containing an array of state identifiers if successful.

## getState

Gets a state document by the agent, activity identifier and the state identifier.

### **Example**

```typescript
const agent: Agent = {
  objectType: "Agent",
  name: "Test Agent",
  mbox: "mailto:test@agent.com"
};
const activityId: string = "https://example.com/activities/test-activity";
const stateId: string = activityId + "/states/myStateId";

xapi.getState({
  agent: agent,
  activityId: activityId,
  stateId: stateId
}).then((result: AxiosResponse<Document>) => {
  const state = result.data;
  // do stuff with state
});
```

### **Parameters**

| Parameter      | Type                                                                                                                          | Required | Description                                  |
| -------------- | ----------------------------------------------------------------------------------------------------------------------------- | -------- | -------------------------------------------- |
| agent          | [Agent](https://github.com/xapijs/xapi/tree/fd040c6f049f68fce317538626906de57ffebf44/src/interfaces/Statement/Actor/Agent.ts) | true     | The agent experiencing the AU.               |
| activityId     | string                                                                                                                        | true     | The URI of the activity.                     |
| stateId        | string                                                                                                                        | true     | The URI of the state to be retrieved.        |
| registration   | string                                                                                                                        | false    | The registration associated with this state. |
| useCacheBuster | boolean                                                                                                                       | false    | Enables cache busting.                       |

### **Returns**

This method returns an `AxiosPromise` with the success `data` containing the stored [Document](https://github.com/xapijs/xapi/blob/d7eac9d07166df5c1f995e17a8ac98bbee99c548/src/resources/document/Document.ts) if successful.

## deleteState

Deletes a state document by the agent, activity identifier and the state identifier.

### **Example**

```typescript
const agent: Agent = {
  objectType: "Agent",
  name: "Test Agent",
  mbox: "mailto:test@agent.com"
};
const activityId: string = "https://example.com/activities/test-activity";
const stateId: string = activityId + "/states/myStateId";

xapi.deleteState({
  agent: agent,
  activityId: activityId,
  stateId: stateId
});
```

### **Parameters**

| Parameter    | Type                                                                                                                          | Required | Description                                  |
| ------------ | ----------------------------------------------------------------------------------------------------------------------------- | -------- | -------------------------------------------- |
| agent        | [Agent](https://github.com/xapijs/xapi/tree/fd040c6f049f68fce317538626906de57ffebf44/src/interfaces/Statement/Actor/Agent.ts) | true     | The agent experiencing the AU.               |
| activityId   | string                                                                                                                        | true     | The URI of the activity.                     |
| stateId      | string                                                                                                                        | true     | The URI of the state to be deleted.          |
| registration | string                                                                                                                        | false    | The registration associated with this stage. |
| etag         | string                                                                                                                        | false    | The ETag of the original document.           |

### **Returns**

This method returns an `AxiosPromise` with empty success `data` if successful.

## deleteStates

Deletes all state documents by the agent and activity identifier.

### **Example**

```typescript
const agent: Agent = {
  objectType: "Agent",
  name: "Test Agent",
  mbox: "mailto:test@agent.com"
};
const activityId: string = "https://example.com/activities/test-activity";

xapi.deleteStates({
  agent: agent,
  activityId: activityId
});
```

### **Parameters**

| Parameter    | Type                                                                                                                          | Required | Description                                       |
| ------------ | ----------------------------------------------------------------------------------------------------------------------------- | -------- | ------------------------------------------------- |
| agent        | [Agent](https://github.com/xapijs/xapi/tree/fd040c6f049f68fce317538626906de57ffebf44/src/interfaces/Statement/Actor/Agent.ts) | true     | The agent experiencing the AU.                    |
| activityId   | string                                                                                                                        | true     | The URI of the activity.                          |
| registration | string                                                                                                                        | false    | The registration associated with this stage.      |
| etag         | string                                                                                                                        | false    | The ETag of the original document if overwriting. |

### **Returns**

This method returns an `AxiosPromise` with empty success `data` if successful.


# Activity Profile Resource

Manages cross-learner state for an activity.

## createActivityProfile

Creates or merges into an activity profile document by the activity identifier and activity profile identifier.

### **Example**

```typescript
const activityId: string = "https://example.com/activities/test-activity";
const profileId: string = activityId + "/profiles/myProfileId";
const profile: DocumentJson = {
  myKey: "myValue"
};

xapi.createActivityProfile({
  activityId: activityId,
  profileId: profileId,
  profile: profile
});
```

### **Parameters**

| Parameter   | Type                                                                                                                            | Required | Description                                                   |
| ----------- | ------------------------------------------------------------------------------------------------------------------------------- | -------- | ------------------------------------------------------------- |
| activityId  | string                                                                                                                          | true     | The URI of the activity.                                      |
| profileId   | string                                                                                                                          | true     | The URI of the activity profile to be created or merged into. |
| profile     | [DocumentJson](https://github.com/xapijs/xapi/blob/d7eac9d07166df5c1f995e17a8ac98bbee99c548/src/resources/document/Document.ts) | true     | The profile data to be stored.                                |
| etag        | string                                                                                                                          | false    | The ETag of the original document if merging.                 |
| matchHeader | string                                                                                                                          | false    | The ETag header type. Accepts "If-Match" or "If-None-Match".  |

### **Returns**

This method returns an `AxiosPromise`  with empty success `data` if successful.

## setActivityProfile

Creates or overwrites an activity profile document by the activity identifier and activity profile identifier.

### **Example**

```typescript
const activityId: string = "https://example.com/activities/test-activity";
const profileId: string = activityId + "/profiles/myProfileId";
const profile = {
  myKey: "myValue"
};

xapi.setActivityProfile({
  activityId: activityId,
  profileId: profileId,
  profile: profile
});
```

### **Parameters**

| Parameter   | Type                                                                                                                        | Required | Description                                                   |
| ----------- | --------------------------------------------------------------------------------------------------------------------------- | -------- | ------------------------------------------------------------- |
| activityId  | string                                                                                                                      | true     | The URI of the activity.                                      |
| profileId   | string                                                                                                                      | true     | The URI of the activity profile to be created or overwritten. |
| profile     | [Document](https://github.com/xapijs/xapi/blob/d7eac9d07166df5c1f995e17a8ac98bbee99c548/src/resources/document/Document.ts) | true     | The profile data to be stored.                                |
| etag        | string                                                                                                                      | true     | The ETag of the original document.                            |
| matchHeader | string                                                                                                                      | true     | The ETag header type. Accepts "If-Match" or "If-None-Match".  |
| contentType | string                                                                                                                      | false    | The content type of the profile data.                         |

### **Returns**

This method returns an `AxiosPromise`  with empty success `data` if successful.

## getActivityProfiles

Gets an array of activity profile identifiers by the activity identifier.

### **Example**

```typescript
const activityId: string = "https://example.com/activities/test-activity";

xapi.getActivityProfiles({
  activityId: activityId
}).then((result: AxiosResponse<string[]>) => {
  const profiles: string[] = result.data;
  console.log(profiles); // ["https://example.com/activities/test-activity/profiles/myProfileId"]
});
```

### **Parameters**

| Parameter      | Type      | Required | Description                                                     |
| -------------- | --------- | -------- | --------------------------------------------------------------- |
| activityId     | string    | true     | The URI of the activity.                                        |
| since          | Timestamp | false    | Only return Activity Profiles stored since specified Timestamp. |
| useCacheBuster | boolean   | false    | Enables cache busting.                                          |

### **Returns**

This method returns an `AxiosPromise` with the success `data` containing an array of activity profile identifiers if successful.

## getActivityProfile

Gets an activity profile document by the activity identifier and the activity profile identifier.

### **Example**

```typescript
const activityId: string = "https://example.com/activities/test-activity";
const profileId: string = activityId + "/profiles/myProfileId";

xapi.getActivityProfile({
  activityId: activityId,
  profileId: profileId
}).then((result: AxiosResponse<Document>) => {
  const profile: Document = result.data;
  // do stuff with profile
});
```

### **Parameters**

| Parameter      | Type    | Required | Description                             |
| -------------- | ------- | -------- | --------------------------------------- |
| activityId     | string  | true     | The URI of the activity.                |
| profileId      | string  | true     | The URI of the profile to be retrieved. |
| useCacheBuster | boolean | false    | Enables cache busting.                  |

### **Returns**

This method returns an `AxiosPromise` with the success `data` containing the stored [Document](https://github.com/xapijs/xapi/blob/d7eac9d07166df5c1f995e17a8ac98bbee99c548/src/resources/document/Document.ts) if successful.

## deleteActivityProfile

Deletes an activity profile document by the activity identifier and the activity profile identifier.

### **Example**

```typescript
const activityId: string = "https://example.com/activities/test-activity";
const profileId: string = activityId + "/profiles/myProfileId";

xapi.deleteActivityProfile({
  activityId: activityId,
  profileId: profileId
});
```

### **Parameters**

| Parameter  | Type   | Required | Description                           |
| ---------- | ------ | -------- | ------------------------------------- |
| activityId | string | true     | The URI of the activity.              |
| profileId  | string | true     | The URI of the profile to be deleted. |
| etag       | string | false    | The ETag of the original document.    |

### **Returns**

This method returns an `AxiosPromise` with empty success `data` if successful.


# Agent Profile Resource

Manage information about a particular person.

## createAgentProfile

Creates or merges into an agent profile document by the agent and agent profile identifier.

### **Example**

```typescript
const agent: Agent = {
  objectType: "Agent",
  name: "Test Agent",
  mbox: "mailto:test@agent.com"
};
const profileId: string = "https://example.com/profiles/myProfileId";
const profile: DocumentJson = {
  myKey: "myValue"
};

xapi.createAgentProfile({
  agent: agent,
  profileId: profileId,
  profile: profile
});
```

### **Parameters**

| Parameter   | Type                                                                                                                            | Required | Description                                                  |
| ----------- | ------------------------------------------------------------------------------------------------------------------------------- | -------- | ------------------------------------------------------------ |
| agent       | [Agent](https://github.com/xapijs/xapi/tree/fd040c6f049f68fce317538626906de57ffebf44/src/interfaces/Statement/Actor/Agent.ts)   | true     | The agent experiencing the AU.                               |
| profileId   | string                                                                                                                          | true     | The URI of the agent profile to be created or merged into.   |
| profile     | [DocumentJson](https://github.com/xapijs/xapi/blob/d7eac9d07166df5c1f995e17a8ac98bbee99c548/src/resources/document/Document.ts) | true     | The profile data to be stored.                               |
| etag        | string                                                                                                                          | false    | The ETag of the original document if merging.                |
| matchHeader | string                                                                                                                          | false    | The ETag header type. Accepts "If-Match" or "If-None-Match". |
| contentType | string                                                                                                                          | false    | The content type of the profile data.                        |

### **Returns**

This method returns an `AxiosPromise` with empty success `data` if successful.

## setAgentProfile

Creates or overwrites an agent profile document by the agent and agent profile identifier.

### **Example**

```typescript
const agent: Agent = {
  objectType: "Agent",
  name: "Test Agent",
  mbox: "mailto:test@agent.com"
};
const profileId: string = "https://example.com/profiles/myProfileId";
const profile: Document = {
  myKey: "myValue"
};

xapi.setAgentProfile({
  agent: agent,
  profileId: profileId,
  profile: profile
});
```

### **Parameters**

| Parameter   | Type                                                                                                                          | Required | Description                                                  |
| ----------- | ----------------------------------------------------------------------------------------------------------------------------- | -------- | ------------------------------------------------------------ |
| agent       | [Agent](https://github.com/xapijs/xapi/tree/fd040c6f049f68fce317538626906de57ffebf44/src/interfaces/Statement/Actor/Agent.ts) | true     | The agent experiencing the AU.                               |
| profileId   | string                                                                                                                        | true     | The URI of the agent profile to be created or overwritten.   |
| profile     | [Document](https://github.com/xapijs/xapi/blob/d7eac9d07166df5c1f995e17a8ac98bbee99c548/src/resources/document/Document.ts)   | true     | The profile data to be stored.                               |
| etag        | string                                                                                                                        | true     | The ETag of the original document if overwriting.            |
| matchHeader | string                                                                                                                        | true     | The ETag header type. Accepts "If-Match" or "If-None-Match". |

### **Returns**

This method returns an `AxiosPromise` with empty success `data` if successful.

## getAgentProfiles

Gets an array of agent profile identifiers by the agent.

### **Example**

```typescript
const agent: Agent = {
  objectType: "Agent",
  name: "Test Agent",
  mbox: "mailto:test@agent.com"
};

xapi.getAgentProfiles({
  agent: agent
}).then((result: AxiosResponse<string[]>) => {
  const profiles: string[] = result.data;
  console.log(profiles); // ["https://example.com/profiles/myProfileId"]
});
```

### **Parameters**

| Parameter      | Type                                                                                                                          | Required | Description                                                  |
| -------------- | ----------------------------------------------------------------------------------------------------------------------------- | -------- | ------------------------------------------------------------ |
| agent          | [Agent](https://github.com/xapijs/xapi/tree/fd040c6f049f68fce317538626906de57ffebf44/src/interfaces/Statement/Actor/Agent.ts) | true     | The agent experiencing the AU.                               |
| since          | Timestamp                                                                                                                     | false    | Only return Agent Profiles stored since specified Timestamp. |
| useCacheBuster | boolean                                                                                                                       | false    | Enables cache busting.                                       |

### **Returns**

This method returns an `AxiosPromise` with the success `data` containing an array of agent profile identifiers if successful.

## getAgentProfile

Gets an agent profile document by the agent and the agent profile identifier.

### **Example**

```typescript
const agent: Agent = {
  objectType: "Agent",
  name: "Test Agent",
  mbox: "mailto:test@agent.com"
};
const profileId: string = "https://example.com/profiles/myProfileId";

xapi.getAgentProfile({
  agent: agent,
  profileId: profileId
}).then((result: AxiosResponse<Document>) => {
  const profile: Document = result.data;
  // do stuff with profile
});
```

### **Parameters**

| Parameter      | Type                                                                                                                          | Required | Description                             |
| -------------- | ----------------------------------------------------------------------------------------------------------------------------- | -------- | --------------------------------------- |
| agent          | [Agent](https://github.com/xapijs/xapi/tree/fd040c6f049f68fce317538626906de57ffebf44/src/interfaces/Statement/Actor/Agent.ts) | true     | The agent experiencing the AU.          |
| profileId      | string                                                                                                                        | true     | The URI of the profile to be retrieved. |
| useCacheBuster | boolean                                                                                                                       | false    | Enables cache busting.                  |

### **Returns**

This method returns an `AxiosPromise` with the success `data` containing the stored [Document](https://github.com/xapijs/xapi/blob/d7eac9d07166df5c1f995e17a8ac98bbee99c548/src/resources/document/Document.ts) if successful.

## deleteAgentProfile

Deletes an agent profile document by the agent and the agent profile identifier.

### **Example**

```typescript
const agent: Agent = {
  objectType: "Agent",
  name: "Test Agent",
  mbox: "mailto:test@agent.com"
};
const profileId: string = "https://example.com/profiles/myProfileId";

xapi.deleteAgentProfile({
  agent: agent,
  profileId: profileId
});
```

### **Parameters**

| Parameter | Type                                                                                                                          | Required | Description                           |
| --------- | ----------------------------------------------------------------------------------------------------------------------------- | -------- | ------------------------------------- |
| agent     | [Agent](https://github.com/xapijs/xapi/tree/fd040c6f049f68fce317538626906de57ffebf44/src/interfaces/Statement/Actor/Agent.ts) | true     | The agent experiencing the AU.        |
| profileId | string                                                                                                                        | true     | The URI of the profile to be deleted. |
| etag      | string                                                                                                                        | false    | The ETag of the original document.    |

### **Returns**

This method returns an `AxiosPromise` with empty success `data` if successful.


# About Resource

Get information about the LRS.

## getAbout

Gets information about the LRS.

### **Example**

```typescript
xapi.getAbout().then((result: AxiosResponse<About>) => {
  const about: About = result.data;
  console.log(about); // {versions: ["1.0.3"]}
});
```

### **Parameters**

| Parameter      | Type    | Required | Description            |
| -------------- | ------- | -------- | ---------------------- |
| useCacheBuster | boolean | false    | Enables cache busting. |

### **Returns**

This method returns an `AxiosPromise` with the success `data` containing an [About](https://github.com/xapijs/xapi/tree/fd040c6f049f68fce317538626906de57ffebf44/src/interfaces/About/About.ts) object.


# Agents Resource

Gets agent information about a particular person.

## getAgent

Gets all agents used by a single person.

### **Example**

```typescript
const agent: Agent = {
  objectType: "Agent",
  name: "Test Agent",
  mbox: "mailto:test@agent.com"
};

xapi.getAgent({
  agent: agent
}).then((result: AxiosResponse<Person>) => {
  const person: Person = result.data;
  // do stuff with person
});
```

### **Parameters**

| Parameter      | Type                                                                                                                          | Required | Description                    |
| -------------- | ----------------------------------------------------------------------------------------------------------------------------- | -------- | ------------------------------ |
| agent          | [Agent](https://github.com/xapijs/xapi/tree/fd040c6f049f68fce317538626906de57ffebf44/src/interfaces/Statement/Actor/Agent.ts) | true     | The agent experiencing the AU. |
| useCacheBuster | boolean                                                                                                                       | false    | Enables cache busting.         |

### **Returns**

This method returns an `AxiosPromise` with the success `data` containing the [Person](https://github.com/xapijs/xapi/tree/fd040c6f049f68fce317538626906de57ffebf44/src/interfaces/Statement/Actor/Person.ts) if successful.


# Activities Resource

Gets activity information about a particular activity.

## getActivity

Gets the full definition of an activity.

### Example

```typescript
const activityId: string = "https://example.com/activities/test-activity";

xapi.getActivity({
  activityId: activityId
}).then((result: AxiosReponse<Activity>) => {
  const activity: Activity = result.data;
  console.log(activity);
});
```

### Parameters

| Parameter      | Type    | Required | Description              |
| -------------- | ------- | -------- | ------------------------ |
| activityId     | string  | true     | The URI of the activity. |
| useCacheBuster | boolean | false    | Enables cache busting.   |

### **Returns**

This method returns an `AxiosPromise` with the success `data` containing an [Activity](https://github.com/xapijs/xapi/blob/master/src/interfaces/Statement/Activity/Activity.ts) if successful.


# Helpers

A selection of useful helpers for converting data into the required formats.

## toBasicAuth

Converts a username and password string combination into a `Basic` Authorization token. `toBasicAuth` is a static method of the `XAPI` Class.

```typescript
const username = "username";
const password = "password";
const auth = XAPI.toBasicAuth(username, password);
console.log(auth); // Basic dXNlcm5hbWU6cGFzc3dvcmQ=
```

## calculateISO8601Duration

Useful for calculating ISO8601 durations when submitting statements that require durations. `calculateISO8601Duration` is a static method of the `XAPI` Class.

```typescript
const startDate: Date = new Date();
const endDate: Date = new Date(startDate);
endDate.setDate(endDate.getDate() + 1);
const duration = XAPI.calculateISO8601Duration(startDate, endDate));
console.log(duration); // P1DT
```

## getXAPILaunchData

Gets the launch data if the module was launched using [xAPI Launch](http://adlnet.github.io/xapi-launch/). `getXAPILaunchData` is a static method of the `XAPI` Class.

```typescript
XAPI.getXAPILaunchData().then((result) => {
  const launchData: XAPILaunchData = result.data;
  this.xapi = new XAPI({
    endpoint: launchData.endpoint
  });
  const actor = launchData.actor;
});
```

## getTinCanLaunchData

Gets the launch data if the module was launched as a TinCan module. `getTinCanLaunchData` is a static method of the `XAPI` Class.

```typescript
const tinCanLaunchData: TinCanLaunchParameters = XAPI.getTinCanLaunchData();
const xapi = new XAPI({
  endpoint: tinCanLaunchData.endpoint,
  auth: tinCanLaunchData.auth
});
const actor = tinCanLaunchData.actor;
```

## getSearchQueryParamsAsObject

Converts search query parameters from a string into an object. `getSearchQueryParamsAsObject` is a static method of the `XAPI` Object. Used in `getTinCanLaunchData` and `getXAPILaunchData`. If any JSON is detected an attempt is made to parse it, else properties are returned as decoded strings.

```
// Location: index.html?endpoint=https%3A%2F%2Fcloud.scorm.com%2Flrs%2FABCDEFGHIJ%2F

const queryParamsString = location.search;
const queryParamsObject = XAPI.getSearchQueryParamsAsObject(queryParamsString);

console.log(queryParamsObject);
// { endpoint: "https://cloud.scorm.com/lrs/ABCDEFGHIJ/" }
```

For backwards compatibility with some LMS/LRS (SCORM Cloud), if an `actor` property is found containing string arrays for `name`, `mbox` and `account` these are coerced into objects containing the first array entry only. Also if the property is `account` the first array object is converted from:&#x20;

`[{ accountServiceHomePage: "...", accountName: "..." }]`

into:

`{ homePage: "...", name: "..." }`

## getAxios

Returns the internal Axios instance. Useful for configuring interceptors or providing other advanced configuration.

```
const xapi = new XAPI({
  ...
});

const axios = xapi.getAbout();

// Do stuff with `axios`
```


# Verbs

For a non-exhaustive list of pre-made verbs for creating statements, see the [Verbs](https://github.com/xapijs/xapi/blob/main/src/constants/Verbs.ts) class. Verbs are a static property of the `XAPI` Object.

```typescript
import XAPI, { Statement } from "@xapi/xapi";

const statement: Statement = {
  actor: actor,
  verb: XAPI.Verbs.INITIALIZED,
  object: object
};
```


# Attachment Usages

For a non-exhaustive list of pre-made identifiers for creating statement attachments,  see the [AttachmentUsages](https://github.com/xapijs/xapi/blob/master/src/constants/AttachmentUsages.ts) enum. AttachmentUsages are a static property of the `XAPI` Object.

```typescript
import XAPI, { Attachment } from "@xapi/xapi";

const attachment: Attachment = {
    usageType: XAPI.AttachmentUsages.SUPPORTING_MEDIA,
    display: {
        "en-US": "Image Attachment"
    },
    description: {
        "en-US": "An image of something"
    },
    contentType: "image/jpeg",
    length: imageArrayBufferByteLength,
    sha2: imageArrayBufferSHA2
};
```


# Introduction

## Overview

The **cmi5 Profile Library** is a strongly typed JavaScript library for enabling learning content to speak to learning systems. It is a complete implementation and fully compliant against the [cmi5 Specification](https://github.com/AICC/CMI-5_Spec_Current) (Quartz, 1st Edition).

For an example implementation of this library, you can find the [cmi5 Profile Demo](https://github.com/xapijs/cmi5-demo) source on GitHub.

## First Steps

{% content-ref url="/pages/-M7ZGgNNIHXiPzCmXS\_S" %}
[Getting Started](/cmi5-profile-library/getting-started)
{% endcontent-ref %}

{% content-ref url="/pages/-M7ZGrnGtxjqOBLJX6jn" %}
[The Cmi5 Class](/cmi5-profile-library/cmi5-class)
{% endcontent-ref %}

## Cmi5 Methods

{% content-ref url="/pages/-M7ZHLb-RFAeJcmxoh18" %}
["cmi5 defined" Statement methods](/cmi5-profile-library/cmi5-defined-statements)
{% endcontent-ref %}

{% content-ref url="/pages/-M7ZEdXCH6j2FHNuvU-b" %}
["cmi5 allowed" Statement methods](/cmi5-profile-library/cmi5-allowed-statements)
{% endcontent-ref %}

## Helper Methods

{% content-ref url="/pages/-M7ZGyp73BM3\_py9jlH1" %}
[Helpers](/cmi5-profile-library/helpers)
{% endcontent-ref %}


# Getting Started

The library has been configured to work in multiple environments:

* UMD (Browser)
* ESM (Client-side applications)

### UMD (Browser)

```markup
<script src="https://unpkg.com/@xapi/cmi5"><script>

<script type="text/javascript">
  // Create Cmi5 instance
  const cmi5 = new Cmi5();

  // Initialize AU
  cmi5.initialize();
<script>
```

### ES module (Client-side applications)

For client-side applications built using imports, an ES Module is available for you to install and `import`  into your project.

```bash
npm i @xapi/cmi5 --save
```

```typescript
import Cmi5 from "@xapi/cmi5";

// Create Cmi5 instance
const cmi5: Cmi5 = new Cmi5();

// Initialize AU
cmi5.initialize();
```


# The Cmi5 Class

## new Cmi5()

To use any methods, you will need to create a new instance of [Cmi5](https://github.com/xapijs/cmi5/blob/master/src/Cmi5.ts). The credentials are obtained from the LMS automatically via the URL launch parameters.

### **Example**

```typescript
import Cmi5 from "@xapi/cmi5";

// Create Cmi5 instance
const cmi5: Cmi5 = new Cmi5();

// Initialize AU
cmi5.initialize();
```

### **Returns**

This returns a [Cmi5](https://github.com/xapijs/cmi5/blob/master/src/Cmi5.ts) object which you can use to communicate with the LRS.


# "cmi5 defined" Statement methods

The core "cmi5 defined" statement methods for communicating module status.

## initialize

Initializes the session, must be called before performing other methods.

### **Example**

```typescript
import Cmi5 from "@xapi/cmi5";

const cmi5 = new Cmi5();

cmi5.initialize();
```

### **Parameters**

| Parameter    | Type   | Required | Description                                                                                                                 |
| ------------ | ------ | -------- | --------------------------------------------------------------------------------------------------------------------------- |
| sessionState | Object | false    | An auth token and initialized date from a previous initialisation. Useful for persisting sessions across browser refreshes. |

### **Returns**

This returns a `Promise` containing an array with the resulting statementId if successful, or `undefined` if a `sessionState` is provided.

## complete

Completes the AU. Required for satisfaction if `LaunchData.moveOn` is equal to `Completed`, `CompletedAndPassed` or `CompletedOrPassed`.

### **Example**

```typescript
import Cmi5 from "@xapi/cmi5";

const cmi5 = new Cmi5();

// initialize etc

cmi5.complete();
```

### **Parameters**

| Parameter | Type                                                                                                      | Required | Description                    |
| --------- | --------------------------------------------------------------------------------------------------------- | -------- | ------------------------------ |
| options   | [SendStatementOptions](https://github.com/xapijs/cmi5/blob/master/src/interfaces/SendStatementOptions.ts) | false    | The additional options object. |

### Returns

This returns a `Promise` containing an array with the resulting statementId if successful.

## pass

Passes the AU. Required for satisfaction if `LaunchData.moveOn` is equal to `Passed`, `CompletedAndPassed` or `CompletedOrPassed`.

### **Examples**

#### **Example 1: Pass**

```typescript
import Cmi5 from "@xapi/cmi5";

const cmi5 = new Cmi5();

// initialize etc

cmi5.pass();
```

#### **Example 2: Pass with score**

```typescript
import Cmi5 from "@xapi/cmi5";
import { ResultScore } from "@xapi/xapi";

const cmi5 = new Cmi5();

// initialize etc

const score: ResultScore = {
  scaled: 0.95,
  raw: 95
  min: 0
  max: 100
}

cmi5.pass(score);
```

#### **Example 3: Pass with score and objective**

```typescript
import Cmi5 from "@xapi/cmi5";
import { ResultScore, ObjectiveActivity } from "@xapi/xapi";

const cmi5 = new Cmi5();

// initialize etc

const score: ResultScore = {
  scaled: 0.95,
  raw: 95
  min: 0
  max: 100
}

const objective: ObjectiveActivity = {
  objectType: "Activity",
  id: "https://github.com/xapijs/cmi5/objectives/test",
  definition: {
    type: "http://adlnet.gov/expapi/activities/objective",
    name: {
      "en-US": "Example Objective"
    },
    description: {
      "en-US": "An example objective."
    }
  }
}

cmi5.pass(score, objective);
```

### **Parameters**

| Parameter          | Type                                                                                                                                                                                                                                     | Required | Description                                                             |
| ------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- | ----------------------------------------------------------------------- |
| score              | [ResultScore](https://github.com/xapijs/xapi/blob/master/src/XAPI/interfaces/Statement/Result.ts)                                                                                                                                        | false    | The score achieved by the learner.                                      |
| objectiveOrOptions | [ObjectiveActivity](https://github.com/xapijs/xapi/blob/master/src/XAPI/interfaces/Statement/Activity/ObjectiveActivity.ts) or [SendStatementOptions](https://github.com/xapijs/cmi5/blob/master/src/interfaces/SendStatementOptions.ts) | false    | The objective achieved by the learner or the additional options object. |

Note: If using score and/or objective parameters, types for these are in `@xapi/xapi` and must be installed as a dev dependency `npm i --save-dev @xapi/xapi`.

### **Returns**

This returns a `Promise` containing an array with the resulting statementId if successful.

## fail

Fails the AU. Required to mark the AU as Failed if `LaunchData.moveOn` is equal to `Passed`, `CompletedAndPassed` or `CompletedOrPassed`.

### **Examples**

#### **Example 1: Fail**

```typescript
import Cmi5 from "@xapi/cmi5";

const cmi5 = new Cmi5();

// initialize etc

cmi5.fail();
```

#### **Example 2: Fail with score**

```typescript
import Cmi5 from "@xapi/cmi5";
import { ResultScore } from "@xapi/xapi";

const cmi5 = new Cmi5();

// initialize etc

const score: ResultScore = {
  scaled: 0.25,
  raw: 25
  min: 0
  max: 100
}

cmi5.fail(score);
```

### **Parameters**

| Parameter | Type                                                                                                      | Required | Description                        |
| --------- | --------------------------------------------------------------------------------------------------------- | -------- | ---------------------------------- |
| score     | [ResultScore](https://github.com/xapijs/xapi/blob/master/src/XAPI/interfaces/Statement/Result.ts)         | false    | The score achieved by the learner. |
| options   | [SendStatementOptions](https://github.com/xapijs/cmi5/blob/master/src/interfaces/SendStatementOptions.ts) | false    | The additional options object.     |

Note: If using the score parameter, types for this are in `@xapi/xapi` and must be installed as a dev dependency `npm i --save-dev @xapi/xapi`.

### **Returns**

This returns a `Promise` containing an array with the resulting statementId if successful.

## terminate

Terminates the session, must be the last method called before closing the window.

### **Example**

```typescript
import Cmi5 from "@xapi/cmi5";

const cmi5 = new Cmi5();

// initialize etc

cmi5.terminate();
```

### **Returns**

This returns a `Promise` containing an array with the resulting statementId if successful.


# "cmi5 allowed" Statement methods

The optional "cmi5 allowed" statement methods for communicating module status.

## progress

Sends the learner's progress for the AU.

### **Example**

```typescript
import Cmi5 from "@xapi/cmi5";

const cmi5 = new Cmi5();

// initialize etc

cmi5.progress(50);
```

### **Parameters**

| Parameter | Type   | Required | Description                                      |
| --------- | ------ | -------- | ------------------------------------------------ |
| percent   | number | true     | The learners progress of the AU as a percentage. |

### **Returns**

This returns a `Promise` containing an array with the resulting statementId if successful.

## interactionTrueFalse

Sends the learner's boolean based answer to an interaction.

### **Example**

```typescript
import Cmi5 from "@xapi/cmi5";
import { LanguageMap } from "@xapi/xapi";

const cmi5 = new Cmi5();

const testId = "test1";
const questionId = "is-true-true";
const answer = true;
const correctAnswer = true;
const success = answer === correctAnswer;
const name: LanguageMap = {
  "en-US": "Is True True"
};
const description: LanguageMap = {
  "en-US": "In a boolean context, is true truthy?"
};

cmi5.interactionTrueFalse(testId, questionId, answer, correctAnswer, name, description, success);
```

### **Parameters**

| Parameter     | Type                                                                                                                        | Required | Description                                                  |
| ------------- | --------------------------------------------------------------------------------------------------------------------------- | -------- | ------------------------------------------------------------ |
| testId        | string                                                                                                                      | true     | The identifier of the test.                                  |
| questionId    | string                                                                                                                      | true     | The identifier of the question.                              |
| answer        | boolean                                                                                                                     | true     | The answer supplied by the learner.                          |
| correctAnswer | boolean                                                                                                                     | false    | The correct answer decided by the learning designer.         |
| name          | [LanguageMap](https://github.com/xapijs/xapi/blob/master/src/XAPI/interfaces/Statement/LanguageMap.ts)                      | false    | The name of the interaction.                                 |
| description   | [LanguageMap](https://github.com/xapijs/xapi/blob/master/src/XAPI/interfaces/Statement/LanguageMap.ts)                      | false    | The description of the interaction.                          |
| success       | boolean                                                                                                                     | false    | Whether the learner interaction result was a success or not. |
| duration      | [Period](https://github.com/xapijs/cmi5/blob/master/src/interfaces/Period.ts)                                               | false    | The period it took the learner to perform the interaction.   |
| objective     | [ObjectiveActivity](https://github.com/xapijs/xapi/blob/master/src/XAPI/interfaces/Statement/Activity/ObjectiveActivity.ts) | false    | The objective achieved by the learner.                       |

### **Returns**

This returns a `Promise` containing an array with the resulting statementId if successful.

## interactionChoice

Sends the learner's choice based answer to an interaction.

### **Example**

```typescript
import Cmi5 from "@xapi/cmi5";
import { LanguageMap, InteractionComponent } from "@xapi/xapi";

const cmi5 = new Cmi5();

const testId = "test1";
const questionId = "first-two-choices";
const answerIds: string[] = ["choice1", "choice4"];
const correctAnswerIds: string[] = ["choice1", "choice2"];
const success = false;
const choices: InteractionComponent[] = [{
  id: "choice1",
  description: {
    "en-US": "Choice 1"
  }
},
{
  id: "choice2",
  description: {
    "en-US": "Choice 2"
  }
},
{
  id: "choice3",
  description: {
    "en-US": "Choice 3"
  }
},
{
  id: "choice4",
  description: {
    "en-US": "Choice 4"
  }
}];

const name: LanguageMap = {
  "en-US": "First Two Choices"
}; 
const description: LanguageMap = {
  "en-US": "What are the first two choices?"
};

cmi5.interactionChoice(testId, questionId, answerIds, correctAnswerIds, choices, name, description, success);
```

### **Parameters**

| Parameter        | Type                                                                                                                                                             | Required | Description                                                          |
| ---------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- | -------------------------------------------------------------------- |
| testId           | string                                                                                                                                                           | true     | The identifier of the test.                                          |
| questionId       | string                                                                                                                                                           | true     | The identifier of the question.                                      |
| answerIds        | string\[]                                                                                                                                                        | true     | The Id(s) of the answer(s) supplied by the learner.                  |
| correctAnswerIds | string\[]                                                                                                                                                        | false    | The correct Id(s) of the answer(s) decided by the learning designer. |
| choices          | [InteractionComponent](https://github.com/xapijs/xapi/blob/master/src/XAPI/interfaces/Statement/Activity/ActivityDefinition/InteractionActivityDefinition.ts)\[] | false    | The identifiers and descriptions of the possible answers.            |
| name             | [LanguageMap](https://github.com/xapijs/xapi/blob/master/src/XAPI/interfaces/Statement/LanguageMap.ts)                                                           | false    | The name of the interaction.                                         |
| description      | [LanguageMap](https://github.com/xapijs/xapi/blob/master/src/XAPI/interfaces/Statement/LanguageMap.ts)                                                           | false    | The description of the interaction.                                  |
| success          | boolean                                                                                                                                                          | false    | Whether the learner interaction result was a success or not.         |
| duration         | [Period](https://github.com/xapijs/cmi5/blob/master/src/interfaces/Period.ts)                                                                                    | false    | The period it took the learner to perform the interaction.           |
| objective        | [ObjectiveActivity](https://github.com/xapijs/xapi/blob/master/src/XAPI/interfaces/Statement/Activity/ObjectiveActivity.ts)                                      | false    | The objective achieved by the learner.                               |

### **Returns**

This returns a `Promise` containing an array with the resulting statementId if successful.

## interactionFillIn

Sends the learner's short text based answer to an interaction.

### **Example**

```typescript
import Cmi5 from "@xapi/cmi5";
import { LanguageMap } from "@xapi/xapi";

const cmi5 = new Cmi5();

const testId = "test1";
const questionId = "hello";
const answers = ["whos there?"];
const correctAnswers = ["world", "World"];
const success = false;
const name: LanguageMap = {
  "en-US": "Hello"
};
const description: LanguageMap = {
  "en-US": "Hello?"
};

cmi5.interactionFillIn(testId, questionId, answers, correctAnswers, name, description, success);
```

### **Parameters**

| Parameter      | Type                                                                                                                        | Required | Description                                                  |
| -------------- | --------------------------------------------------------------------------------------------------------------------------- | -------- | ------------------------------------------------------------ |
| testId         | string                                                                                                                      | true     | The identifier of the test.                                  |
| questionId     | string                                                                                                                      | true     | The identifier of the question.                              |
| answers        | string\[]                                                                                                                   | true     | The answer(s) to the question.                               |
| correctAnswers | string\[]                                                                                                                   | false    | The correct possible answer(s) to the question.              |
| name           | [LanguageMap](https://github.com/xapijs/xapi/blob/master/src/XAPI/interfaces/Statement/LanguageMap.ts)                      | false    | The name of the interaction.                                 |
| description    | [LanguageMap](https://github.com/xapijs/xapi/blob/master/src/XAPI/interfaces/Statement/LanguageMap.ts)                      | false    | The description of the interaction.                          |
| success        | boolean                                                                                                                     | false    | Whether the learner interaction result was a success or not. |
| duration       | [Period](https://github.com/xapijs/cmi5/blob/master/src/interfaces/Period.ts)                                               | false    | The period it took the learner to perform the interaction.   |
| objective      | [ObjectiveActivity](https://github.com/xapijs/xapi/blob/master/src/XAPI/interfaces/Statement/Activity/ObjectiveActivity.ts) | false    | The objective achieved by the learner.                       |

### **Returns**

This returns a `Promise` containing an array with the resulting statementId if successful.

## interactionLongFillIn

Sends the learner's long text based answer to an interaction.

### **Example**

```typescript
import Cmi5 from "@xapi/cmi5";
import { LanguageMap } from "@xapi/xapi";

const cmi5 = new Cmi5();

const testId = "test1";
const questionId = "hello-long";
const answers = ["whos there?"];
const correctAnswers = ["world", "World"];
const success = false;
const name: LanguageMap = {
  "en-US": "Hello"
};
const description: LanguageMap = {
  "en-US": "Hello?"
};

cmi5.interactionFillIn(testId, questionId, answers, correctAnswers, name, description, success);
```

### **Parameters**

| Parameter      | Type                                                                                                                        | Required | Description                                                  |
| -------------- | --------------------------------------------------------------------------------------------------------------------------- | -------- | ------------------------------------------------------------ |
| testId         | string                                                                                                                      | true     | The identifier of the test.                                  |
| questionId     | string                                                                                                                      | true     | The identifier of the question.                              |
| answers        | string\[]                                                                                                                   | true     | The answer(s) to the question.                               |
| correctAnswers | string\[]                                                                                                                   | false    | The correct possible answer(s) to the question.              |
| name           | [LanguageMap](https://github.com/xapijs/xapi/blob/master/src/XAPI/interfaces/Statement/LanguageMap.ts)                      | false    | The name of the interaction.                                 |
| description    | [LanguageMap](https://github.com/xapijs/xapi/blob/master/src/XAPI/interfaces/Statement/LanguageMap.ts)                      | false    | The description of the interaction.                          |
| success        | boolean                                                                                                                     | false    | Whether the learner interaction result was a success or not. |
| duration       | [Period](https://github.com/xapijs/cmi5/blob/master/src/interfaces/Period.ts)                                               | false    | The period it took the learner to perform the interaction.   |
| objective      | [ObjectiveActivity](https://github.com/xapijs/xapi/blob/master/src/XAPI/interfaces/Statement/Activity/ObjectiveActivity.ts) | false    | The objective achieved by the learner.                       |

### **Returns**

This returns a `Promise` containing an array with the resulting statementId if successful.

## interactionLikert

Sends the learner's Likert based answer to an interaction.

### **Example**

```typescript
import Cmi5 from "@xapi/cmi5";
import { InteractionComponent } from "@xapi/xapi";

const cmi5 = new Cmi5();

const testId = "test1";
const questionId = "highest-value";
const answerId = "likert4";
const correctAnswerId = "likert4";
const scale: InteractionComponent[] = [{
  id: "likert0",
  description: {
    "en-US": "Very Unsatisfied"
  }
},
{
  id: "likert1",
  description: {
    "en-US": "Unsatisfied"
  }
},
{
  id: "likert2",
  description: {
    "en-US": "Neutral"
  }
},
{
  id: "likert3",
  description: {
    "en-US": "Satisfied"
  }
},
{
  id: "likert4",
  description: {
    "en-US": "Very Satisfied"
  }
}];
const name: LanguageMap = {
  "en-US": "Highest Value"
};
const description: LanguageMap = {
  "en-US": "What is the highest value on this scale?"
};

cmi5.interactionLikert(testId, questionId, answerId, correctAnswerId, scale, name, description)
```

### **Parameters**

| Parameter       | Type                                                                                                                                                             | Required | Description                                                    |
| --------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- | -------------------------------------------------------------- |
| testId          | string                                                                                                                                                           | true     | The identifier of the test.                                    |
| questionId      | string                                                                                                                                                           | true     | The identifier of the question.                                |
| answerId        | string                                                                                                                                                           | true     | The Id of the answer supplied by the learner.                  |
| correctAnswerId | string                                                                                                                                                           | false    | The correct Id of the answer decided by the learning designer. |
| scale           | [InteractionComponent](https://github.com/xapijs/xapi/blob/master/src/XAPI/interfaces/Statement/Activity/ActivityDefinition/InteractionActivityDefinition.ts)\[] | false    | The identifiers and descriptions of the Likert scale.          |
| name            | [LanguageMap](https://github.com/xapijs/xapi/blob/master/src/XAPI/interfaces/Statement/LanguageMap.ts)                                                           | false    | The name of the interaction.                                   |
| description     | [LanguageMap](https://github.com/xapijs/xapi/blob/master/src/XAPI/interfaces/Statement/LanguageMap.ts)                                                           | false    | The description of the interaction.                            |
| success         | boolean                                                                                                                                                          | false    | Whether the learner interaction result was a success or not.   |
| duration        | [Period](https://github.com/xapijs/cmi5/blob/master/src/interfaces/Period.ts)                                                                                    | false    | The period it took the learner to perform the interaction.     |
| objective       | [ObjectiveActivity](https://github.com/xapijs/xapi/blob/master/src/XAPI/interfaces/Statement/Activity/ObjectiveActivity.ts)                                      | false    | The objective achieved by the learner.                         |

### **Returns**

This returns a `Promise` containing an array with the resulting statementId if successful.

## interactionMatching

Sends the learner's matching based answer to an interaction.

### Example

```typescript
import Cmi5 from "@xapi/cmi5";
import { LanguageMap, InteractionComponent } from "@xapi/xapi";

const cmi5 = new Cmi5();

const testId = "test1";
const questionId = "food-groups";
const answers = {
apple: "fruit",
carrot: "vegetable"
};
const correctAnswers = {
apple: "fruit",
carrot: "vegetable"
};
const success = true;
const source: InteractionComponent[] = [{
  id: "apple",
  description: {
    "en-US": "Apple"
  }
}, {
  id: "carrot",
  description: {
    "en-US": "Carrot"
  }
}];
const target: InteractionComponent[] = [{
  id: "fruit",
  description: {
    "en-US": "Fruit"
  }
},
{
  id: "vegetable",
  description: {
    "en-US": "Vegetable"
  }
}];
const name: LanguageMap = {
  "en-US": "Food Groups"
};
const description: LanguageMap = {
  "en-US": "Match the food items to their groups."
};

cmi5.interactionMatching(testId, questionId, answers, correctAnswers, source, target, name, description, success);
```

### Parameters

| Parameter      | Type                                                                                                                                                             | Required | Description                                                                                   |
| -------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- | --------------------------------------------------------------------------------------------- |
| testId         | string                                                                                                                                                           | true     | The identifier of the test.                                                                   |
| questionId     | string                                                                                                                                                           | true     | The identifier of the question.                                                               |
| answers        | {\[key: string]: string}                                                                                                                                         | true     | The source-target key-value pairings of the answers supplied by the learner.                  |
| correctAnswers | {\[key: string]: string}                                                                                                                                         | false    | The correct source-target key-value pairings of the answers decided by the learning designer. |
| source         | [InteractionComponent](https://github.com/xapijs/xapi/blob/master/src/XAPI/interfaces/Statement/Activity/ActivityDefinition/InteractionActivityDefinition.ts)\[] | false    | The identifiers and descriptions of the sources.                                              |
| target         | [InteractionComponent](https://github.com/xapijs/xapi/blob/master/src/XAPI/interfaces/Statement/Activity/ActivityDefinition/InteractionActivityDefinition.ts)\[] | false    | The identifiers and descriptions of the targets.                                              |
| name           | [LanguageMap](https://github.com/xapijs/xapi/blob/master/src/XAPI/interfaces/Statement/LanguageMap.ts)                                                           | false    | The name of the interaction.                                                                  |
| description    | [LanguageMap](https://github.com/xapijs/xapi/blob/master/src/XAPI/interfaces/Statement/LanguageMap.ts)                                                           | false    | The description of the interaction.                                                           |
| success        | boolean                                                                                                                                                          | false    | Whether the learner interaction result was a success or not.                                  |
| duration       | [Period](https://github.com/xapijs/cmi5/blob/master/src/interfaces/Period.ts)                                                                                    | false    | The period it took the learner to perform the interaction.                                    |
| objective      | [ObjectiveActivity](https://github.com/xapijs/xapi/blob/master/src/XAPI/interfaces/Statement/Activity/ObjectiveActivity.ts)                                      | false    | The objective achieved by the learner.                                                        |

### Returns

This returns a `Promise` containing an array with the resulting statementId if successful.

## interactionPerformance

Sends the learner's performance based answer to an interaction.

### Example

```typescript
import Cmi5, { Performance, PerformanceCriteria } from "@xapi/cmi5";
import { LanguageMap } from "@xapi/xapi";

const cmi5 = new Cmi5();

const testId = "test1";
const questionId = "trex-runner";
const answers: Performance = {
  distance: 500
};
const correctAnswers: PerformanceCriteria[] = [{
  id: "distance",
  min: 100
}];
const success = true;
const name: LanguageMap = {
  "en-US": "T-Rex Runner"
};
const description: LanguageMap = {
  "en-US": "Get a score of minimum 100 on T-Rex Runner"
};

cmi5.interactionPerformance(testId, questionId, answers, correctAnswers, name, description, success);
```

### Parameters

| Parameter      | Type                                                                                                                        | Required | Description                                                                                   |
| -------------- | --------------------------------------------------------------------------------------------------------------------------- | -------- | --------------------------------------------------------------------------------------------- |
| testId         | string                                                                                                                      | true     | The identifier of the test.                                                                   |
| questionId     | string                                                                                                                      | true     | The identifier of the question.                                                               |
| answers        | [Performance](https://github.com/xapijs/cmi5/blob/master/src/interfaces/Performance.ts)                                     | true     | The source-target key-value pairings of the answers supplied by the learner.                  |
| correctAnswers | [PerformanceCriteria](https://github.com/xapijs/cmi5/blob/master/src/interfaces/PerformanceCriteria.ts)\[]                  | false    | The correct source-target key-value pairings of the answers decided by the learning designer. |
| name           | [LanguageMap](https://github.com/xapijs/xapi/blob/master/src/XAPI/interfaces/Statement/LanguageMap.ts)                      | false    | The name of the interaction.                                                                  |
| description    | [LanguageMap](https://github.com/xapijs/xapi/blob/master/src/XAPI/interfaces/Statement/LanguageMap.ts)                      | false    | The description of the interaction.                                                           |
| success        | boolean                                                                                                                     | false    | Whether the learner interaction result was a success or not.                                  |
| duration       | [Period](https://github.com/xapijs/cmi5/blob/master/src/interfaces/Period.ts)                                               | false    | The period it took the learner to perform the interaction.                                    |
| objective      | [ObjectiveActivity](https://github.com/xapijs/xapi/blob/master/src/XAPI/interfaces/Statement/Activity/ObjectiveActivity.ts) | false    | The objective achieved by the learner.                                                        |

### Returns

This returns a `Promise` containing an array with the resulting statementId if successful.

## interactionSequencing

Sends the learner's sequence based answer to an interaction.

### Example

```typescript
import Cmi5 from "@xapi/cmi5";
import { LanguageMap, InteractionComponent } from "@xapi/xapi";

const cmi5 = new Cmi5();

const testId = "test1";
const questionId = "number-order";
const answerIds: string[] = ["one", "three", "two", "four"];
const correctAnswerIds: string[] = ["one", "two", "three", "four"];
const choices = InteractionComponent[] = [{
  id: "one",
  description: {
    "en-US": "One"
  }
},
{
  id: "two",
  description: {
    "en-US": "Two"
  }
},
{
  id: "three",
  description: {
    "en-US": "Three"
  }
},
{
  id: "four",
  description: {
    "en-US": "Four"
  }
}];
const success = false;
const name: LanguageMap = {
  "en-US": "Number Order"
};
const description: LanguageMap = {
  "en-US": "Put the numbers in order"
};

cmi5.interactionSequencing(testId, questionId, answerIds, correctAnswerIds, choices, name, description, success);
```

### Parameters

| Parameter        | Type                                                                                                                                                             | Required | Description                                                              |
| ---------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- | ------------------------------------------------------------------------ |
| testId           | string                                                                                                                                                           | true     | The identifier of the test.                                              |
| questionId       | string                                                                                                                                                           | true     | The identifier of the question.                                          |
| answerIds        | string\[]                                                                                                                                                        | true     | The Id sequence of the answers supplied by the learner.                  |
| correctAnswerIds | string\[]                                                                                                                                                        | false    | The correct Id sequence of the answers decided by the learning designer. |
| choices          | [InteractionComponent](https://github.com/xapijs/xapi/blob/master/src/XAPI/interfaces/Statement/Activity/ActivityDefinition/InteractionActivityDefinition.ts)\[] | false    | The identifiers and descriptions of the options.                         |
| name             | [LanguageMap](https://github.com/xapijs/xapi/blob/master/src/XAPI/interfaces/Statement/LanguageMap.ts)                                                           | false    | The name of the interaction.                                             |
| description      | [LanguageMap](https://github.com/xapijs/xapi/blob/master/src/XAPI/interfaces/Statement/LanguageMap.ts)                                                           | false    | The description of the interaction.                                      |
| success          | boolean                                                                                                                                                          | false    | Whether the learner interaction result was a success or not.             |
| duration         | [Period](https://github.com/xapijs/cmi5/blob/master/src/interfaces/Period.ts)                                                                                    | false    | The period it took the learner to perform the interaction.               |
| objective        | [ObjectiveActivity](https://github.com/xapijs/xapi/blob/master/src/XAPI/interfaces/Statement/Activity/ObjectiveActivity.ts)                                      | false    | The objective achieved by the learner.                                   |

### Returns

This returns a `Promise` containing an array with the resulting statementId if successful.

## interactionNumeric

Sends the learner's numeric based answer to an interaction.

### Example

```typescript
import Cmi5, { NumericCriteria } from "@xapi/cmi5";
import { LanguageMap } from "@xapi/xapi";

const cmi5 = new Cmi5();

const testId = "test1";
const questionId = "human-legs";
const answer = 2;
const correctAnswer: NumericCriteria = {
  exact: 2
};
const success = true;
const name: LanguageMap = {
  "en-US": "Human Legs"
};
const description: LanguageMap = {
  "en-US": "How many legs does a human have?"
};
cmi5.interactionNumeric(testId, questionId, answer, correctAnswer, name, description, success);
```

### Parameters

| Parameter        | Type                                                                                                                        | Required | Description                                                  |
| ---------------- | --------------------------------------------------------------------------------------------------------------------------- | -------- | ------------------------------------------------------------ |
| testId           | string                                                                                                                      | true     | The identifier of the test.                                  |
| questionId       | string                                                                                                                      | true     | The identifier of the question.                              |
| answer           | number                                                                                                                      | true     | The answer supplied by the learner.                          |
| correctAnswerIds | [NumericCriteria](https://github.com/xapijs/cmi5/blob/master/src/interfaces/NumericCriteria.ts)                             | false    | The correct answer decided by the learning designer.         |
| name             | [LanguageMap](https://github.com/xapijs/xapi/blob/master/src/XAPI/interfaces/Statement/LanguageMap.ts)                      | false    | The name of the interaction.                                 |
| description      | [LanguageMap](https://github.com/xapijs/xapi/blob/master/src/XAPI/interfaces/Statement/LanguageMap.ts)                      | false    | The description of the interaction.                          |
| success          | boolean                                                                                                                     | false    | Whether the learner interaction result was a success or not. |
| duration         | [Period](https://github.com/xapijs/cmi5/blob/master/src/interfaces/Period.ts)                                               | false    | The period it took the learner to perform the interaction.   |
| objective        | [ObjectiveActivity](https://github.com/xapijs/xapi/blob/master/src/XAPI/interfaces/Statement/Activity/ObjectiveActivity.ts) | false    | The objective achieved by the learner.                       |

### Returns

This returns a `Promise` containing an array with the resulting statementId if successful.

## interactionOther

Sends the learner's "other" based answer to an interaction.

### Example

```typescript
import Cmi5, { NumericCriteria } from "@xapi/cmi5";
import { LanguageMap } from "@xapi/xapi";

const cmi5 = new Cmi5();

const testId = "test1";
const questionId = "plymouth-location";
const answer = "(53.756898, -4.501819)";
const correctAnswer = "(53.756898, -4.501819)";
const success = true;
const name: LanguageMap = {
  "en-US": "Plymouth Location"
};
const description: LanguageMap = {
  "en-US": "On this map, please mark Plymouth, Devon"
};
cmi5.interactionOther(testId, questionId, answer, correctAnswer, name, description, success);
```

### **Parameters**

| Parameter     | Type                                                                                                                        | Required | Description                                                  |
| ------------- | --------------------------------------------------------------------------------------------------------------------------- | -------- | ------------------------------------------------------------ |
| testId        | string                                                                                                                      | true     | The identifier of the test.                                  |
| questionId    | string                                                                                                                      | true     | The identifier of the question.                              |
| answer        | string                                                                                                                      | true     | The answer to the question.                                  |
| correctAnswer | string                                                                                                                      | false    | The correct possible answer to the question.                 |
| name          | [LanguageMap](https://github.com/xapijs/xapi/blob/master/src/XAPI/interfaces/Statement/LanguageMap.ts)                      | false    | The name of the interaction.                                 |
| description   | [LanguageMap](https://github.com/xapijs/xapi/blob/master/src/XAPI/interfaces/Statement/LanguageMap.ts)                      | false    | The description of the interaction.                          |
| success       | boolean                                                                                                                     | false    | Whether the learner interaction result was a success or not. |
| duration      | [Period](https://github.com/xapijs/cmi5/blob/master/src/interfaces/Period.ts)                                               | false    | The period it took the learner to perform the interaction.   |
| objective     | [ObjectiveActivity](https://github.com/xapijs/xapi/blob/master/src/XAPI/interfaces/Statement/Activity/ObjectiveActivity.ts) | false    | The objective achieved by the learner.                       |

### **Returns**

This returns a `Promise` containing an array with the resulting statementId if successful.


# Helpers

A selection of useful helpers.

## getLaunchParameters

This gets the launch parameters supplied in the URL. Can be used before initializing.

### **Example**

```typescript
import Cmi5, { LaunchParameters } from "@xapi/cmi5";

const cmi5 = new Cmi5();

const launchParameters: LaunchParameters = cmi5.getLaunchParameters();
```

### **Returns**

This returns a [LaunchParameters](https://github.com/xapijs/cmi5/blob/master/src/interfaces/LaunchParameters.ts) object.

## getLaunchData

This gets the launch data from the LMS. Can **not** be used before initializing the AU.

### **Example**

```typescript
import Cmi5, { LaunchData } from "@xapi/cmi5";

const cmi5 = new Cmi5();

cmi5.initialize().then(() => {
  const launchData: LaunchData = cmi5.getLaunchData();
});
```

### **Returns**

This returns a [LaunchData](https://github.com/xapijs/cmi5/blob/master/src/interfaces/LaunchData.ts) object.

## getAuthToken

This gets the session's authToken. Useful for storing in non-volatile storage local to the user (e.g. SessionStorage) to preserve the state between page refreshes. Pass this value and `initializedDate` to `initialize` to restore the previous session.

### Example

```typescript
// Storing the auth token
const cmi5 = new Cmi5();

cmi5.initialize().then(() => {
  const authToken = cmi5.getAuthToken();
  sessionStorage.set("cmi5-auth-token", authToken);
});
```

<pre class="language-typescript"><code class="lang-typescript"><strong>// Restoring the auth token in a new Cmi5 instance
</strong><strong>const cmi5 = new Cmi5();
</strong>const authToken = sessionStorage.get("cmi5-auth-token");

cmi5.initialize({
  authToken,
  initializedDate: ...
});
</code></pre>

### Returns

This returns a `string` or `null` if the Cmi5 instance has not been initialized.

## getInitializedDate

This gets the session's initializedDate. Useful for storing in non-volatile storage local to the user (e.g. SessionStorage) to preserve the state between page refreshes. Pass this value and `authToken` to `initialize` to restore the previous session.

### Example

```typescript
// Storing the auth token
const cmi5 = new Cmi5();

cmi5.initialize().then(() => {
  const initializedDate = cmi5.getInitializedDate();
  sessionStorage.set("cmi5-initialized-date", initializedDate);
});
```

<pre class="language-typescript"><code class="lang-typescript"><strong>// Restoring the initialized date in a new Cmi5 instance
</strong><strong>const cmi5 = new Cmi5();
</strong>const initializedDate = new Date(sessionStorage.get("cmi5-initialized-date"));

cmi5.initialize({
  initializedDate,
  authToken: ...
});
</code></pre>

### Returns

This returns a `Date` or `null` if the Cmi5 instance has not been initialized.

## getLearnerPreferences

This gets the learner preferences from the LMS. Can **not** be used before initializing the AU.

### **Example**

```typescript
import Cmi5, { LearnerPreferences } from "@xapi/cmi5";

const cmi5 = new Cmi5();

cmi5.initialize().then(() => {
  const learnerPreferences: LearnerPreferences = cmi5.getLearnerPreferences();
});
```

## Cmi5.isCmiAvailable

This returns `true` if the environment has all the necessary parameters for initialisation.

### Example

```typescript
import Cmi5 from "@xapi/cmi5";

const isCmiAvailable: boolean = Cmi5.isCmiAvailable();
```

### Returns

This returns a `Boolean`.

## isAuthenticated

This returns `true` if the instance constructed successfully.

### Example

```typescript
import Cmi5 from "@xapi/cmi5";

const cmi5 = new Cmi5();

cmi5.initialize().then(() => {
  const isAuthenticated: boolean = cmi5.isAuthenticated();
});
```

### Returns

This returns a `Boolean`.

## Cmi5.instance

Creates a new Cmi5 singleton instance, or if already called returns the same singleton Cmi5 instance.

### Example

```typescript
import Cmi5 from "@xapi/cmi5";

const cmi5instance: Cmi5 = Cmi5.instance;
```

### Returns

This returns a global `Cmi5` singleton instance.

## Cmi5.clearInstance

Clears the Cmi5 singleton instance.

### Example

```typescript
import Cmi5 from "@xapi/cmi5";

const cmi5instance: Cmi5 = Cmi5.instance;

Cmi5.clearInstance();
```

## moveOn

Automatically satisfies the AU based upon the Launch Data from the LMS. It will send the "cmi5 defined" statements for:

* **Pass** or **fail** if a score is provided and the mastery score is configured
* **complete** statement
* **terminate** statement (unless disabled in the options parameter)

### **Example**

```typescript
import Cmi5 from "@xapi/cmi5";

const cmi5 = new Cmi5();

// initialize etc

cmi5.moveOn();
```

### **Parameters**

| Parameter | Type                                                                                        | Required | Description                    |
| --------- | ------------------------------------------------------------------------------------------- | -------- | ------------------------------ |
| options   | [MoveOnOptions](https://github.com/xapijs/cmi5/blob/master/src/interfaces/MoveOnOptions.ts) | false    | The additional options object. |

This returns a `Promise` containing an array with the resulting statementIds if successful.

## Cmi5.xapi

Returns the internal xAPI.js Wrapper library instance. Useful for accessing any xAPI Resources using the Cmi5 authentication. Can only be accessed after successfully calling the `initialize` method.

### Example

```typescript
import Cmi5 from "@xapi/cmi5";
import XAPI from "@xapi/xapi"; // For types as a developer dependency, not required but may be useful!

const cmi5: Cmi5 = new Cmi5();
await cmi5.initialize();

const xapi: XAPI = cmi5.xapi;
xapi.getStatement(...);
```

### Returns

This returns the internal `XAPI` instance, authenticated with the LRS endpoint and authentication token.


