API

This document is intended for developers who want to write applications that interact with Unicko. It explains basic concepts of Unicko and of the API itself. It also provides an overview of the different functions that the API supports.

Overview

Unicko provides an API that let you integrate the virtual classes seamlessly into your learning management system or portal.

Features

Single Sign-On (SSO):
Your users only need to log in to your website. They join a virtual class session by clicking a link.
Privacy:
Only the minimal required information, such as the user name and role, is passed on encrypted SSL connection. You can decide, for example, to only share the first letter of the user's last name.
Security:
The API security model is based on HMAC signature. A consumer_key and consumer_secret, are used to securely sign messages exchanged between the two parties.

How it Works

The client request a signed token from your server. Your server respond with a signed request with request_type set to 'room_login'.

Your server redirect the user to a page with a form that includes the signed_request. The form is submitted with javascript to Unicko's API URL.

Unicko's server validates the request and redirects the user to the room.


<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
</head>
<body>
<form action="{api-url}" name="roomForm" id="roomForm" method="POST" enctype="application/x-www-form-urlencoded">
  <input type="hidden" name="signed_request" value="{the-signed-request}"/>
</form>
<script type="text/javascript">
  document.roomForm.submit();
</script>
</body>
</html>
      

Signed Request

A signed request is a base64url encoded JSON object signed with HMAC using a consumer_secret.

The signed request is generated by your server and sent by the user's browser via HTTP POST to the URL of the Unicko server.

Steps to create a signed request:

  1. JSON encode the payload.
  2. Base64 URL encode the json string. Trim the '=' padding from the end of the base64 string and replace '+' with '-' and '/' with '_'.
  3. Create sha256 HMAC signature of the base64 url safe string
  4. Base64 URL encode the signature
  5. Concatenate the encoded signature '.' and the encoded payload

Code samples:


# create and print the room_login token
$signed_request = create_room_login_signed_request();
echo "room_login signed_request:\r\n";
echo $signed_request;

function create_room_login_signed_request() {
$payload = get_info();
$payload["request_type"] = "room_login";
$expire = 60; // 1 minute
return create_request($payload, $expire);
}

function get_info() {
$user_ext_id = "u1";
$user_given_name = "Albert";
$user_family_name = "Einstein";
$course_ext_id = "course1";
$course_name = "Course 1";
$course_role = "teacher";
$room_ext_id = "room1";
$room_name = "Room 1";
$room_lang = "en";
$room_transient = True;
$room_affiliation = "host";

$data = array(
    "user_ext_id" => $user_ext_id,
    "user_given_name" => $user_given_name,
    "user_family_name" => $user_family_name,
    "course_ext_id" => $course_ext_id,
    "course_name" => $course_name,
    "course_role" => $course_role,
    "room_ext_id" => $room_ext_id,
    "room_name" => $room_name,
    "room_lang" => $room_lang,
    "room_transient" => $room_transient,
    "room_affiliation" => $room_affiliation
);
return $data;
}

function create_request($payload, $expire) {
$consumer_secret = "abcd";
$consumer_key = "example.com";
$algorithm = "HMAC-SHA256";
$nonce = generate_nonce();
$issued_at = time();
$expires = $issued_at + $expire;
$payload["version"] = 3;
$payload["consumer_key"] = $consumer_key;
$payload["algorithm"] = $algorithm;
$payload["nonce"] = $nonce;
$payload["issued_at"] = $issued_at;
$payload["expires"] = $expires;
return sign_request($payload, $consumer_secret);
}

function sign_request($payload, $secret) {
$data = base64_url_encode(json_encode($payload));
$signature = base64_url_encode(hash_hmac('sha256', $data, $secret, $raw = true));
return $signature . "." . $data;
}

function base64_url_encode($input) {
return strtr(rtrim(base64_encode($input), '='), '+/', '-_');
}

function generate_nonce() {
$random_string = openssl_random_pseudo_bytes(10);
return base64_encode(md5(time() + $random_string, true));
}
          

import time
import string
import random
import json
import base64
import hmac
import hashlib

def create_room_login_signed_request():
room_id = 5
payload = get_info()
payload['request_type'] = 'room_login'
expire = 60 # 1 mintue
return create_request(payload, expire)

def get_info():
user_ext_id = 'u1'
user_given_name = 'Albert'
user_family_name = 'Einstein'
course_ext_id = 'course1'
course_name = 'Course 1'
course_role = 'teacher'
room_ext_id = 'room1'
room_name = 'Room 1'
room_lang = 'en'
room_transient = True
room_affiliation = 'host'

data = {
  'user_ext_id': user_ext_id,
  'user_given_name':  user_given_name,
  'user_family_name': user_family_name,
  'course_ext_id': course_ext_id,
  'course_name': course_name,
  'course_role': course_role,
  'room_ext_id': room_ext_id,
  'room_name': room_name,
  'room_lang': room_lang,
  'room_transient': room_transient,
  'room_affiliation': room_affiliation
}
return data

def create_request(payload, expire):
version = 3
consumer_secret = "abcd"
consumer_key = "example.com"
algorithm = "HMAC-SHA256"
nonce = generate_nonce()
issued_at = int(time.time())
expires = issued_at + expire
payload['version'] = version;
payload['consumer_key'] = consumer_key;
payload['algorithm'] = algorithm;
payload['nonce'] = nonce;
payload['issued_at'] = issued_at;
payload['expires'] = expires;
return sign_request(payload, secret)

def sign_request(payload, secret):
data = base64.urlsafe_b64encode(json.dumps(payload)).rstrip("=")
signature = base64.urlsafe_b64encode(hmac.new(secret, data, hashlib.sha256).digest()).rstrip("=")
return signature + "." + data

def generate_nonce():
chars = string.ascii_letters + string.digits
random_string = ''.join(random.choice(chars) for _ in range(10))
m = hashlib.md5(str(time.time()) + random_string).digest()
return base64.b64encode(m)

if __name__ == "__main__":
# create and print the room_login signed request
signed_request = create_room_login_signed_request()
print 'room_login signed request:'
print signed_request
          

using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Web.Script.Serialization;

namespace test
{
class MainClass
{
public static void Main (string[] args)
{

string secret = "abcd";
string consumer_key = "example.com";

Int32 issued_at = (Int32)(DateTime.UtcNow.Subtract(new DateTime(1970,1,1))).TotalSeconds;
Int32 expires_at = issued_at + 1 * 60 * 60; // 1 hour
string nonce = GenerateNonce ();

Dictionary request_params = new Dictionary {
  { "request_type", "room_login" },
  { "version", 3 },
  { "consumer_key", consumer_key },
  { "algorithm", "HMAC-SHA256" },
  { "nonce", nonce },
  { "issued_at", issued_at },
  { "expires", expires_at },
  { "user_ext_id", "u1" },
  { "user_given_name", "Albert" },
  { "user_family_name", "Einstein" },
  { "course_ext_id", "course1" },
  { "course_name", "Course 1" },
  { "course_role", "student" },
  { "room_ext_id", "room1" },
  { "room_name:", "Room 1" },
  { "room_lang", "he" },
  { "room_transient", true },
  { "room_affiliation", "member" }
};

JavaScriptSerializer serializer = new JavaScriptSerializer();
string request_json = serializer.Serialize((object)request_params);

string request_base64 = Base64UrlEncode (Encoding.UTF8.GetBytes (request_json));
string signature = Base64UrlEncode(HashHmac(secret, request_base64));
string signed_request = signature + "." + request_base64;
Console.WriteLine ("room_login signed_request");
Console.WriteLine (signed_request);
}

private static string Base64UrlEncode(byte[] input) {
var b64Input = Convert.ToBase64String(input);
var trim = b64Input.TrimEnd('=');
return trim.Replace('+', '-').Replace('/','_');
}

private static byte[] HashHmac(string key, string message)
{
var keyByte = Encoding.UTF8.GetBytes(key);
using (var hmacsha256 = new System.Security.Cryptography.HMACSHA256(keyByte))
{
  return hmacsha256.ComputeHash(Encoding.UTF8.GetBytes(message));  
}
}

private static string GenerateNonce()
{
var rnd = new Random();
var pseudoBytes = new Byte[10];
rnd.NextBytes(pseudoBytes);

using (var md5 = new System.Security.Cryptography.MD5CryptoServiceProvider())
{
  return Convert.ToBase64String(md5.ComputeHash(pseudoBytes));
}
}
}
}
          

Common Fields

The JSON object of the signed request contain the following fields and values:

Name Type Description
version integer The API version, currently 3.
consumer_key string A value used by the Consumer to identify itself to the Service Provider, normally your domain name.
algorithm string The mechanism used to sign the request, normally: HMAC-SHA256.
nonce string A nonce is a random string, uniquely generated for each request. The nonce allows the Service Provider to verify that a request has never been made before.
issued_at integer The Unix timestamp* when the request was signed.
expires integer The Unix timestamp* when the token expires.
request_type string Request type.

* A timestamp is expressed in the number of seconds since January 1, 1970 00:00:00 GMT

Room Login

Name Type Description
request_type string room_login
user_ext_id string The user ID of the current user on your site.
user_given_name string The given name of the current user.
user_family_name string The family name of the current user. If required, the first letter of the family name can be used.
course_ext_id string The course ID on your site.
course_name string The course name on your site.
course_role string The user's role in the course. Supported roles are 'teacher' and 'student'.
room_ext_id string The room ID on your site.
room_name string The room name.
room_lang string The room language. 'en', 'he' and 'ar' are supported.
room_transient boolean A boolean indicating if the room should be deleted after the session.
room_affiliation string The affiliation of the user in the room. Supported affiliations are 'host' and 'member'.

Online Rooms

Name Type Description
request_type string room_online_list
limit integer Limits the number of records in the response. Max limit is 25.
skip integer Number of records to skip.

The JSON response has the following fields:

Name Type Description
total integer Total number of online rooms.
rooms list A list of rooms.
room_id integer The room ID.
room_ext_id string The room ID on your site.
room_name string The room name.
room_lang string The room language. 'en', 'he' and 'ar' are supported.
course_id integer The course ID.
course_ext_id string The course ID on your site.
course_name string The course name.
user_count integer Number of users registered to the room.
online_user_count integer Online users in the room.
started_at integer The Unix timestamp* when the room session started.

* A timestamp is expressed in the number of seconds since January 1, 1970 00:00:00 GMT

Online Users

Name Type Description
request_type string user_online_list
limit integer Limits the number of records in the response. Max limit is 25.
skip integer Number of records to skip.

The JSON response has the following fields:

Name Type Description
total integer Total number of online users.
users list A list of users.
user_id integer The user ID.
user_ext_id string The user ID on your site.
user_given_name string The user's given name.
user_family_name string The user's family name.
room_id integer The room ID.
room_ext_id string The room ID on your site.
room_name string The room name.
room_affiliation string The affiliation of the user in the room. Supported affiliations are 'host' and 'member'.
course_id integer The course ID.
course_ext_id string The course ID on your site.
course_name string The course name.
course_role string The user's role in the course. Supported roles are 'teacher' and 'student'.
user_agent string User Agent.
started_at integer The Unix timestamp* when the user session started.

* A timestamp is expressed in the number of seconds since January 1, 1970 00:00:00 GMT

Room Sessions

Name Type Required Description
request_type string yes room_sessions
limit integer yes Limits the number of records in the response. Max limit is 100.
skip integer yes Number of records to skip.
start integer yes The lower bound of the range as a Unix timestamp*.
end integer yes The upper bound of the range as a Unix timestamp*.
course_id integer optional The course ID.
course_ext_id string optional The course ID on your site.
site_name string optional The site name.
room_id integer optional The room ID.
room_ext_id string optional The room ID on your site.

The JSON response has the following fields:

Name Type Description
total integer Total number of sessions.
sessions list A list of sessions.
session_id integer The session ID.
room_id integer The room ID.
room_ext_id string The room ID on your site.
room_name string The room name.
course_id integer The course ID.
course_ext_id string The course ID on your site.
course_name string The course name.
started_at integer The Unix timestamp* when the session started.
ended_at integer The Unix timestamp* when the session ended.
users integer Number of users in the session.

* A timestamp is expressed in the number of seconds since January 1, 1970 00:00:00 GMT

User Sessions

Doesn't report guest sessions.

Name Type Required Description
request_type string yes user_sessions
limit integer yes Limits the number of records in the response. Max limit is 5000.
skip integer yes Number of records to skip.
room_session_id integer yes The room session ID returned from a room_sessions request.
start integer yes The lower bound of the range as a Unix timestamp*.
end integer yes The upper bound of the range as a Unix timestamp*.
user_id integer optional The user ID.
user_ext_id string optional The user ID on your site.
course_id integer optional The course ID.
course_ext_id string optional The course ID on your site.
course_role string optional The user's role in the course. Supported roles are 'teacher' and 'student'.
room_id integer optional The room ID.
room_ext_id string optional The room ID on your site.
room_affiliation string optional The affiliation of the user in the room. Supported affiliations are 'host' and 'member'.

The JSON response has the following fields:

Name Type Description
total integer Total number of sessions.
sessions list A list of sessions.
room_session_id integer The room session ID.
user_id integer The user ID.
user_ext_id string The user ID on your site.
user_given_name string The user's given name.
user_family_name string The user's family name.
room_id integer The room ID.
room_ext_id string The room ID on your site.
room_name string The room name.
room_affiliation string The affiliation of the user in the room. Supported affiliations are 'host' and 'member'.
course_id integer The course ID.
course_ext_id string The course ID on your site.
course_name string The course name.
course_role string The user's role in the course. Supported roles are 'teacher' and 'student'.
started_at integer The Unix timestamp* when the session started.
ended_at integer The Unix timestamp* when the session ended.

* A timestamp is expressed in the number of seconds since January 1, 1970 00:00:00 GMT

Recordings

Name Type Required Description
request_type string yes recordings
limit integer yes Limits the number of records in the response. Max limit is 50.
skip integer yes Number of records to skip.
start integer optional The lower bound of the range as a Unix timestamp*.
end integer optional The upper bound of the range as a Unix timestamp*.
state string optional The recording state. Can be recording, processing, ready, deleted or all. Default: ready.
course_id integer optional The course ID.
course_ext_id string optional The course ID on your site.
room_id integer optional The room ID.
room_ext_id string optional The room ID on your site.

The JSON response has the following fields:

Name Type Description
total integer Total number of recordings.
recordings list A list of recordings.
recording_id string The user ID on your site.
room_id integer The room ID.
room_ext_id string The room ID on your site.
room_name string The room name.
course_id integer The course ID.
course_ext_id string The course ID on your site.
course_name string The course name.
started_at integer The Unix timestamp* when the recording started.
ended_at integer The Unix timestamp* when the recording ended.
state string The recording state. Can be processing, ready or deleted.
url string The recording URL. The URL expires after 24 hours.

* A timestamp is expressed in the number of seconds since January 1, 1970 00:00:00 GMT

Delete Recording

Name Type Description
request_type string recording_delete
id integer The recording ID.

The JSON response has the following fields:

Name Type Description
sucess Boolean true or false.