This document discusses how the TinCan REST API works, so that other third party apps could use this service. ==== Registering to oAuth 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. ==== Versioning ==== 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. ==== Inserting Statements into LRS ==== **method type:** post **url:** http:///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. ==== Getting Statements with Id's ==== 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:///statements/fetch?data= **Parameters ** ^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 ==== Modifying Statements ==== 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:///statements/?data= **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": }, { "id": "id2", "new_statement": }, { "id": "id3", "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) ==== Deleting Statements ==== **method type:** delete **url:** http:///statements?data= **Parameters ** ^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) ==== Searching Statements ==== **method type:** get **url:** http:///statements/search?key=&s=&activity=&verb=&agent=&since=&until=&limit=&page= **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 [[https://wiki.exphosted.com/doku.php/tincan_api_rest#an_example_statement_tincan_statement| TinCan statements]] ==== Getting the Verbs pushed into LRS ==== This API call returns the default supported verbs plus all the new verbs inserted into TinCAN **method type:** get **url:** http:///verbs?key=&page=&limit= **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"} } ==== Getting the Agents / Actors pushed into LRS ==== This API call returns Actors / Agents inserted into TinCAN **method type:** get **url:** http:///agents?key=&mbox=&page=&limit= **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" } ==== Getting the Objects pushed into LRS ==== This API call returns Actors / Agents inserted into TinCAN **method type:** get **url:** http:///agents?key=&page=&limit= **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" } } } ==== An Example Record / TinCAN Statement ==== { "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. * If the id is present, it must be in UUID format http://en.wikipedia.org/wiki/UUID * If the timestamp is present it must be in ISO8601 format http://en.wikipedia.org/wiki/Iso8601