This document discusses how the TinCan REST API works, so that other third party apps could use this service.
The flow and api end points are same as described here - https://wiki.exphosted.com/doku.php/oauth_2.0_for_apis
Only client application (LMS) is authenticated. User authentication is not in Tincan app's scope.
API includes the “X-Experience-API-Version” header in every response and it's value is set to 1.0.0
Example: X-Experience-API-Version : 1.0.0
API accepts requests with a version header of “1.0” or “1.0.0” and rejects the requests for any other version.
method type: post
url:
http://<domain_name>/statements/
Parameters (as json input)
| Parameter | Description |
|---|---|
| records_json (parameter passed to the web page) | The json string containing array of records to be stored |
| key | An authentication key for that particular application |
| records | The records array |
Request
The record_json
{
"key" : "dhfwer8952fen20wrnf0rj"
"records": [record_obj_1, record_obj_2, ......, record_obj_n]
}
Where record_obj_1 to record_obj_n are tin can statement each. This API allows the client to aggregate TinCAN statements and pack them into json and insert them all into LRS in one HTTP request.
Responses
* 200 OK / The ids of records {ids: [id1, id2, ......, idn]}
* 401 Unauthorized (if key is invalid)
* 400 Bad Request (due to bad syntax)
Where id1 to idn are id's of records that has been inserted.
When you know exact id(s) of records that need to be fetched , you could use the following API to fetch them
method type: get
url:
http://<domain_name>/statements/fetch?data=<json_string>
Parameters <json_string>
| Parameter | Description |
|---|---|
| key | Authentication key for the application |
| statementid | array of ids of the records that must be fetched from the database |
Request
{ "key": "dnf89w5ne09fgwefrg",
"statementid": ["id1", "id2", "id3",.... "idn"]
}
Responses
* The stored record(s) is given out as plain json text
{"records": [record_obj_1, record_obj_2, ......, record_obj_n]}
* 401 Unauthorized (if key is invalid)
* 400 Bad Request (due to bad syntax)
In the above response record_obj_1 to record_obj_n are TinCAN records https://wiki.exphosted.com/doku.php/tincan_api_rest#an_example_record_tincan_statement
When you know that certain statements need to be modified, you can use this REST API to modify them. The API allows modification of statements in bulk. To modify a statement, you must know its exact id.
method type: put
url:
http://<domain_name>/statements/?data=<json_string>
Parameters
| Parameter | Description |
|---|---|
| key | Authentication key for the application |
| modified_statements | Array of statements that need to be modified, each array contains the following |
| id | The id of the statement we must modify |
| new_statement | The new statement value to be overwritten |
Request
{ "key": "sdfhn23894rewmgn923452",
"modified_statements: [
{ "id": "id1", "new_statement": <a_new_statement>},
{ "id": "id2", "new_statement": <a_new_statement>},
{ "id": "id3", "new_statement": <a_new_statement>}
]
}
Responses
* 200 OK / id's of statements that were modified {[id1, id2, id3 ......, idn]}
* 401 Unauthorized (if key is invalid)
* 400 Bad Request (due to bad syntax)
method type: delete
url:
http://<domain_name>/statements?data=<json_string>
Parameters <json_string>
| Parameter | Description |
|---|---|
| key | Authentication key for the application |
| ids | List of statement ids as a json array |
Request (sample json string)
{ "key": "dnf89w5ne09fgwefrg",
"ids": ["id1", "id2", "id3",.... "idn"]
}
Responses
* 200 OK / Count of statements that has been deleted as plain text * 401 Unauthorized (if key is invalid) * 400 Bad Request (due to bad syntax)
method type: get
url:
http://<domain_name>/statements/search?key=<key_value>&s=<search_term>&activity=<sctivity_id>&verb=<verb_id>&agent=<agent_id>&since=<start_time>&until=<end_time>&limit=<limit_number>&page=<page_no>
Parameters
| Parameter | Description |
|---|---|
| key | Authentication key for the application |
| s | Term that must be searched |
| activity | The id of activity / object that must be present in the statement |
| verb | The id of verb that must be present in the statement |
| agent | The id of object that must be present in the statement |
| since | The minimum timestamp that a statement must have, please use ISO8601 format |
| until | The maximum timestamp that a statement must have, please use ISO8601 format |
| page | The page that has to be returned |
The search functionality is really flexible, you can drop out any parameter and the LRS intelligently searches with the given input. However the LRS won't respond if no parameter is given
Responses
* The stored statement(s) is given out as plain json text
{"statements": [statement_obj_1, statement_obj_2, ......, statement_obj_n]}
* 401 Unauthorized (if key is invalid)
* 400 Bad Request (due to bad syntax)
In the above response, statement_obj1 to statement_obj_n are TinCan statements
This API call returns the default supported verbs plus all the new verbs inserted into TinCAN
method type: get
url:
http://<domain_name>/verbs?key=<api_key>&page=<page_num>&limit=<count_per_page>
Request:
| Parameter | Description |
|---|---|
| key | The API key given by the oAuth |
| page | The page number of the verb needs to be obtained (default its 1) |
| limit | Amount of verbs per page (default its 50) |
Response:
{page: 25, per_page: 50, verbs: [verb_obj_1, ...., verb_obj_n]}
Where verb_obj_x is a json object as shown
{
"id": "http://adlnet.gov/expapi/verbs/experienced",
"display": {"en-US": "experienced"}
}
This API call returns Actors / Agents inserted into TinCAN
method type: get
url:
http://<domain_name>/agents?key=<api_key>&mbox=<mbox_array>&page=<page_num>&limit=<count_per_page>
Request:
| Parameter | Description |
|---|---|
| key | The API key given by the oAuth |
| page | The page number of the agent needs to be obtained (default its 1) |
| limit | Amount of verbs per page (default its 50) |
| mbox | The array of mbox values of records that must be retrieved |
Response:
{page: 25, per_page: 50, verbs: [agent_obj_1, ...., agent_obj_n]}
Where agent_obj_x is a json object as shown
{
"name": "Sally Glider",
"mbox": "mailto:sally@example.com"
}
This API call returns Actors / Agents inserted into TinCAN
method type: get
url:
http://<domain_name>/agents?key=<api_key>&page=<page_num>&limit=<count_per_page>
Request:
| Parameter | Description |
|---|---|
| key | The API key given by the oAuth |
| page | The page number of the agent needs to be obtained (default its 1) |
| limit | Amount of objects per page (default its 50) |
Response:
{page: 25, per_page: 50, verbs: [object_obj_1, ...., object_obj_n]}
Where object_obj_x is a json object as shown
{
"id": "http://example.com/activities/solo-hang-gliding",
"definition": {
"name": { "en-US": "Solo Hang Gliding" }
}
}
{
"id": "f2e552fc-0eda-11e3-9895-f8922604ca97",
"actor": {
"name": "Sally Glider",
"mbox": "mailto:sally@example.com"
},
"verb": {
"id": "http://adlnet.gov/expapi/verbs/experienced",
"display": {"en-US": "experienced"}
},
"object": {
"id": "http://example.com/activities/solo-hang-gliding",
"definition": {
"name": { "en-US": "Solo Hang Gliding" }
},
"timestamp": "2013-08-26T18:44Z"
}
In the statement above, its optional to have id or timestamp. If the id is not present, the system generates one and inserts, if timestamp is not present, the insertion time is taken to be the time when the event has occurred.