Communication with the remote Application

Accessing the application

The extension system for Applications in itslearning uses its own system for providing SSO between itslearning and the remote web application.

Whenever a user creates a new application's instance in the course, itslearning passes data as a regular HTTP URI query string. The request is made to the add instance page, which URL is specified during registration of the application. The request can look as follows:

Raw HTTP request for creating an application instance

Likewise, when we open once created application's instance, there's another request sent, this time to the view page of the application. The query string is similar to the previous one:

Raw HTTP request for viewing the content of the application instance.

Query string parameters passed from itslearning to the application:

Parameter name

Sample value




Session id that must be used for communicating with itslearning rest api (used as part of Authorization header)



Numeric unique id of the learning object



numeric learning object instance id, identifies a unique use of the learning object (e.g. in a course)



Numeric unique id for current user. No relation to PersonId from Plugins.


GMT Standard Time

Id of timezone that can be used in .net framework: TimeZoneInfo tzi = TimeZoneInfo.FindSystemTimeZoneById(windowsTimeZoneId)



Id of timezone on Olson format


Bent Audun

First name of current user



Last name of current user



Culture name that specifies e.g. date time format. RFC 1766 standard in the format "<languagecode2>-<country/regioncode2>") like used by Microsoft.NET Framework, see



Culture name for current user's language. RFC 1766 standard in the format "<languagecode2>-<country/regioncode2>") like used by Microsoft.NET Framework, see



True/False. True if user expects 12 hour format for times (7:00 PM) or False when user expects 24 hour time format (19:00).



True/False, if user has checked the accessibility setting in itslearning


Read, Participate, 
Evaluate, Modify, ModifyInstance

Permissions user has to this particular learning object instance. Comma separated string.
Read - user is allowed to view the learning object
Participate (only avaliable for Learning Activity) - user is allowed to participate on learning object (e.g. submit answer)
Evaluate (only avaliable for Learning Activity) - user is allowed to evaluate (e.g. assess answers, view reports etc)
Modify - user is allowed to modify the learning object
ModifyInstance - Only applicable for applications that support sharing. User should be allowed to edit instance content stored in your application and also e.g. update deadline stored in itslearning (use rest api method). If your application supports sharing - the user will not have Modify permission when accessing an instance that is connected to a library "master" instance, even though user is author. Shared content must be edited from the library – and then Modify permission will be sent.

If "Read, Participate" is sent from itslearning, it means that the user can view learning object and e.g. submit answer, but should not be allowed to edit learning object or e.g. assess answers.



The role of the user in the current context (course). One of Admin, Instructor, Member, Learner



The customer the user request is coming from. Integer.



The role that the user has in itslearning. Can be one of Staff, Learner, Guest. This parameter should not be used as a permission system, but rather to for example prevent Learner's from seeing parts of the application that you'd only like Staff users to see.



Time stamp in UTC


The level of HTML the user is allowed to use.

HighlyRestricted (Only some basic tags are allowed)

Restricted (More tags are restricted)

LessRestricted (Some tags are restricted)

Everything (Everything is allowed)



True/False. Can be send in specific cases to indicate a readonly state should be used e.g. preview option.



If "True" itslearning's common AddPage used. If "False" itslearning's common AddPage wasn't used. If application can't use itslearning's common AddPage, parameter won't be present.


A signature created from all of the above parameters and shared secret.

The signature is calculated by alphabetically ordering the query string parameters by their name [a-z] and creating an MD5 hash of it. The parameter values are URL encoded before signing (using the C# .NET method HttpUtility.UrlEncode(parameter.Value, Encoding.UTF8. ). A parameter called "SharedSecret" is included which holds the shared secret (Only for computing the signature. It is not sent in the query string.)

Example code to validate signature:

/// <summary>
/// Checks if the request signature is valid and the request is not expired.
/// </summary>
/// <param name="queryString"></param>
/// <param name="sharedSecret"></param>
/// <param name="requestLifetimeInMinutes"></param>
/// <param name="parameters"></param>
internal static void ValidateQueryString(string queryString, string sharedSecret, int requestLifetimeInMinutes, NameValueCollection parameters)
if (string.IsNullOrEmpty(queryString)) throw new ArgumentNullException("queryString");
if (string.IsNullOrEmpty(sharedSecret)) throw new ArgumentNullException("sharedSecret");
if (parameters == null) throw new ArgumentNullException("parameters");
// Check if timestamp is correct and within acceptable range
string timestampString = parameters["Timestamp"];
if (string.IsNullOrEmpty(timestampString))
throw new SecurityAccessDeniedException("Timestamp is not specified.");
DateTime timestamp;
if (
!DateTime.TryParse(timestampString, CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal,
out timestamp))
throw new SecurityAccessDeniedException(
"Query string has an invalid timestamp(check that UTC time is passed and that server time is correct)");
timestamp = timestamp.ToUniversalTime();
if (timestamp < DateTime.UtcNow.AddMinutes(-requestLifetimeInMinutes) ||
timestamp > DateTime.UtcNow.AddMinutes(requestLifetimeInMinutes))
throw new SecurityAccessDeniedException(
"Query string has an invalid timestamp(check that UTC time is passed and that server time is correct)");
// Check signature
string signature = parameters["Signature"];
if (string.IsNullOrEmpty(signature))
throw new SecurityAccessDeniedException("Signature is not specified.");
// Remove signature from the querystring
queryString = HttpUtility.UrlDecode(queryString);
string queryStringWithoutSignature =
queryString.Replace(string.Format("&Signature={0}", signature), string.Empty);
if (ComputeHash(queryStringWithoutSignature + sharedSecret) != signature)
throw new SecurityAccessDeniedException("Signature is invalid.");
/// <summary>
/// Calculates MD5 of the string.
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
internal static string ComputeHash(string input)
var md5Hasher = new MD5CryptoServiceProvider();
byte[] data = md5Hasher.ComputeHash(Encoding.Default.GetBytes(input));
var sb = new StringBuilder();
// Loop through each byte of the hashed data and format each one as a hexadecimal string.
for (int i = 0; i < data.Length; i++)
return sb.ToString();

The following parameters are extended data:

Extended data will only be passed as query string parameters if the app has been approved by a site admin to receive such data.


Person email address.


Person mobile phone.


Person synchronization key.


Custom field 1 name used on the site .


Custom field 1 value for the person.


Custom field 2 name used on the site.


Custom field 2 value for the person.


Custom field 3 name used on the site.


Custom field 3 value for the person.


Custom field 4 name used on the site.


Custom field 4 value for the person.


Custom field 5 name used on the site.


Custom field 5 value for the person.

Deleting a remote instance of the application

Deletion workflow

When an application instance is permanently deleted from itslearning, the URL which is registered as "Delete instance URL" is called.

Your application needs to handle the call by marking the LearningObjectInstance and/or LearningObject as deleted and send the response with code "OK" (200).

If the delete operation takes a long time (delete files, communicate with external systems, etc.), you can only mark your instance as deleted and delete asynchronously.

If the application experiences any difficulties when deleting or marking an instance as deleted, it can return an error and write a problem description into a response. If this is the case, a request will be sent again.

Query string parameters passed on deletion:

Here's sample HTTP request from itslearning to the application sent upon deleting:

Raw HTTP request for deleting the application instance.
Connection: Keep-Alive

The parameters explained:

Parameter name

Sample value




Numeric unique id of the learning object



Numeric learning object instance id, identifies a unique use of the learning object (e.g. in a course)



Use this parameter to identify if it is safe to delete shared content. It is set to True when the last learning object instance is deleted, which indicates that it is now safe to delete the learning object.

This means if a test is shared between several courses, the parameter will be False when one instance is deleted from one of the course. This means you can only delete test results for that particular instance, but not test content (description, questions) or results from other instances. Only when the test is deleted from the last course will this be set to True, which means it's safe to delete all content and data on your side. See more details about this below.



Time stamp in UTC


A signature created from all of the above parameters and shared secret

Deleting shared instances

If your application supports sharing, your learning objects can have multiple instances. For example, you have a test, which is shared with several courses, which means you have a multiple number of learning object instances per learning object. It can be so that not all instances are deleted, so an application needs to determine, if a learning object needs to be deleted or not.

For such purposes there is a parameter called "SafeToDeleteLearningObject". This parameter is transferred through the SSO between itslearning and the application and shows if it’s safe to delete the learning object itself (which means all learning object instances are already deleted). Applications, that don’t support sharing, are always receiving SafeToDeleteLearningObject=True, because there's always one learning object instance per learning object.

Example 1 (Single learning object):

Instance in itslearning and application:

The delete request URL:
The application can easily delete the learning object and its instance.

Example 2 (Shared learning object):

Instance in library:

Shared instance 1 in course:

Shared instance 2 in course:
Instance 2 has been deleted from itslearning.

The delete request URL will be: LearningObjectInstanceId=8512& SafeToDeleteLearningObject=False

The application should delete all the data connected to the learning object instance 8512, but keep the learning object itself (LearningObjectId=2250) as well as remaining learning object instances 8130 and 8255

Some tips on how to implement delete functionality

  • Check the signature in the same way as with add and view instance pages to make sure the delete request comes from itslearning.

  • Do not try to delete everything in synchronous mode. If the delete operation takes a long time (more than several seconds), itslearning will reset the connection and try to send the delete request once more. A good way is to mark the existing learning object and/or learning object instance for deletion and send the "OK" response. The deletion itself can be done asynchronously.

  • Return error responses when you need the delete request to be sent once more (e.g. the application is unable to mark object/instance for deletion). If you receive a request to delete an already deleted learning object/instance, just do nothing and return the "OK" response.