7/27/2019 Tin Can API (Tcapi) Spec
1/72
Experience API
Advanced Distributed Learning (ADL) Co-Laboratories
This document was authored by members of the Experience API Working Group (see liston pp. 7-8) in support of the Office of the Deputy Assistant Secretary of Defense
(Readiness) Advanced Distributed Learning (ADL) Initiative. Please send all feedback
and inquiries to [email protected]
Table of Contents
1.0. Revision History
2.0. Role of the Experience API
2.1. ADL's Role in the Experience API
2.2. Contributors2.2.1. Working Group Participants
2.2.2. Requirements Gathering Participants3.0. Definitions
Tin Can API (TCAPI)
4.0. Statement4.1. Statement Properties
4.1.1. ID
4.1.2. Actor4.1.3. Verb
4.1.4. Object
4.1.5. Result4.1.6. Context4.1.7. Timestamp
4.1.8. Stored
4.1.9. Authority4.1.10. Voided
4.1.11. Attachments
4.1.12. Signed Statements4.1.13. Data Constraints
4.2. Retrieval of Statements
5.0. Miscellaneous Types
5.1. Document5.2. Language Map
5.3. Extensions
5.4. Identifier Metadata6.0. Runtime Communication
6.1. Encoding
6.2. API Versioning6.3. Concurrency
mailto:[email protected]://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#revhistoryhttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#roleofxapihttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#adlrolehttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#contributorshttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#wghttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#reqparticipantshttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#defintionshttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#tcapihttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#statementhttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#stmtpropshttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#stmtidhttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#actorhttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#verbhttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#objecthttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#resulthttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#contexthttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#timestamphttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#storedhttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#authorityhttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#voidedhttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#attachmentshttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#signaturehttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#dataconstraintshttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#retstmtshttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#misctypeshttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#miscdocumenthttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#misclangmaphttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#miscexthttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#miscmetahttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#rtcomhttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#encodinghttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#apiversioninghttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#concurrencymailto:[email protected]://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#revhistoryhttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#roleofxapihttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#adlrolehttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#contributorshttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#wghttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#reqparticipantshttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#defintionshttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#tcapihttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#statementhttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#stmtpropshttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#stmtidhttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#actorhttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#verbhttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#objecthttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#resulthttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#contexthttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#timestamphttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#storedhttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#authorityhttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#voidedhttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#attachmentshttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#signaturehttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#dataconstraintshttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#retstmtshttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#misctypeshttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#miscdocumenthttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#misclangmaphttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#miscexthttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#miscmetahttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#rtcomhttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#encodinghttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#apiversioninghttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#concurrency7/27/2019 Tin Can API (Tcapi) Spec
2/72
6.4. Security
6.4.1. Authentication Definitions
6.4.2. OAuth Authorization Scope7.0. Data Transfer (REST)
7.1. Error Codes
7.2. Statement API7.3. Document APIs
7.4. State API
7.5. Activity Profile API7.6. Agent Profile API
7.7. About resource
7.8. Cross Origin Requests
7.9. Validation7.10. HTTP HEAD
Appendix A: Bookmarklet
Appendix B: Creating an "IE Mode" Request
Appendix C: Example definitions for activities of type "cmi.interaction"Appendix D: Example statements
Appendix E: Converting Statements to 1.0.0Appendix F: Example Signed Statement
1.0 Revision History
0.8 (Project Tin Can API Deliverable) to 0.9 (March 31, 2012):
Rustici Software, who delivered the Project Tin Can API, made modifications to the APIprior to the April 2012 Kickoff Meeting. It was voted in this meeting to move those
changes into the current spec and revision to 0.9.
0.90 to 0.95 (August 31, 2012):
"Core" verbs and activity types were removed from the specification. References to these
verbs in results, context, interactions, and activity definitions were also removed. It was
recommended that implementers prefer community defined verbs to creating their ownverbs.
Verbs, activity types, and extension keys are now URIs
Restructured and added language around some of the other implementation details
and scope.
Changed from using a person-centric view of agents to a persona-centric view.
Friend of a Friend (FOAF) agent merging requirement was removed.
Agent objects must now have exactly 1 uniquely identifying property, instead of
at least one.
0.95 to 1.0.0 (April 26, 2013):
Various refinements and clarifications including:
https://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#securityhttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#authdefshttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#oauthscopehttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#datatransferhttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#errorcodeshttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#stmtapihttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#docapishttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#stateapihttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#actprofapihttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#agentprofapihttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#aboutresourcehttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#corshttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#validationhttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#httpheadhttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#AppendixAhttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#AppendixBhttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#AppendixChttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#AppendixDhttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#AppendixEhttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#AppendixFhttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#securityhttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#authdefshttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#oauthscopehttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#datatransferhttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#errorcodeshttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#stmtapihttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#docapishttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#stateapihttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#actprofapihttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#agentprofapihttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#aboutresourcehttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#corshttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#validationhttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#httpheadhttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#AppendixAhttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#AppendixBhttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#AppendixChttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#AppendixDhttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#AppendixEhttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#AppendixF7/27/2019 Tin Can API (Tcapi) Spec
3/72
Adding attachments
Activity metadata is now stored as JSON rather than XML
Changes to voiding statements
Clarification and naming of the Document APIs
Changes to querying the Statement API
Signed statements
2.0 Role of the Experience API
The Experience API is a service that allows for statements of experience to be deliveredto and stored securely in a Learning Record Store (LRS). These statements of experience
are typically learning experiences, but the API can address statements of any kind of
experience. The Experience API is dependent on Learning Activity Providers to create
and track these learning experiences; this specification provides a data model andassociated components on how to accomplish these tasks.
Specifically, the Experience API provides:
The structure and definition of statement, state, learner, activity and objects,
which are the means by which experiences are conveyed by a Learning ActivityProvider.
Data Transfer methods for the storage and retrieval (but not validation) of these
objects to/from a Learning Record Store. Note that the systems storing or
retrieving records need not be Learning Activity Providers. LRSs maycommunicate with other LRSs, or reporting systems.
Security methods allowing for the trusted exchange of information between the
Learning Record Store and trusted sources.
The Experience API is the first of many envisioned technologies that will enable a richerarchitecture of online learning and training. Authentication services, querying services,
visualization services, and personal data services are some examples of additional
technologies for which the Experience API is designed to support. While theimplementation details of these services are not specified here, the Experience API is
designed with this larger architectural vision in mind.
2.1 ADL's Role in the Experience API
ADL has taken a role of steward and facilitator in the development of the Experience
API. The Experience API is seen as one piece of the ADL Training and Learning
Architecture, which facilitates learning anytime and anywhere. ADL views theExperience API as an evolved version of SCORM that can support similar use cases, but
can also support many of the use cases gathered by ADL and submitted by those involved
in distributed learning which SCORM could not enable.
7/27/2019 Tin Can API (Tcapi) Spec
4/72
2.2 Contributors
My thanks to everyone who contributed to the Experience API project. Many of you have
called into the weekly meetings and helped to shape the specification into something that
is useful for the entire distributed learning community. Many of you assisted in releasing
code samples, products, and documentation to aid those who are creating and adoptingthe specification. I'd also like to thank all of those who were involved in supplying useful,
honest information about your organization's use of SCORM and other learning bestpractices. Through the use-cases, shared experiences, and knowledge you have shared,
ADL and the community clearly identified the first step in creating the Training and
Learning Architecture--the Experience API. You are truly the community leaders on
which we depend to make our training and education the very best.
Kristy S. Murray, Ed.D.
Director, ADL Initiative
OSD, Training Readiness & Strategy (TRS)
2.2.1 Working Group Participants
Name: Organization:
Aaron Silvers ADL
Al Bejcek NetDimensions
Ali Shahrazad SaLTBOX
Andrew Downes Epic
Andy Johnson ADL
Andy Whitaker Rustici Software
Anthony Altieri American Red CrossAnto Valan Omnivera Learning Solutions
Avron Barr Aldo Ventures, Inc.
Ben Clark Rustici Software
Bill McDonald Boeing
Brian J. Miller Rustici Software
Chad Udell Float Mobile Learning
Dan Allen Litmos
Dan Kuemmel Sentry Insurance
Dave Mozealous Articulate
David Ells Rustici SoftwareDoug Hagy Twin Lakes Consulting Corporation
Eric Johnson Planning and Learning Technologies, Inc.
Fiona Leteney Feenix e-learning
Greg Tatka Menco Social Learning
Ingo Dahn University Koblenz-Landau
Jason Haag ADL
7/27/2019 Tin Can API (Tcapi) Spec
5/72
Jeff Place Questionmark
Jennifer Cameron Sencia Corporate Web Solutions
Jeremy Brockman
Joe Gorup CourseAvenue
John Kleeman Questionmark
Jonathan Poltrack ADL
Kris Miller edcetra Training
Kris Rockwell Hybrid Learning Systems
Lang Holloman
Lou Wolford ADL
Luke Hickey dominKnow
Marcus Birtwhistle ADL
Mark Davis Exambuilder
Megan Bowe Rustici Software
Melanie VanHorn ADL
Michael Flores Here Everything's Better
Michael Roberts vTrainingRoom
Mike Palmer OnPoint Digital
Mike Rustici Rustici Software
Nik Hruska ADL
Patrick Kedziora Kedzoh
Paul Roberts Questionmark
Rich Chetwynd Litmos
Richard Fouchaux Ontario Human Rights Commission
Richard Lenz Organizational Strategies, Inc.
Rick Raymer Serco
Rob Chadwick ADL
Robert Lowe
Russell Duhon SaLTBOX
Stephen Trevorrow Problem Solutions, LLC.
Steve Baumgartner
Steve Flowers XPConcept
Thomas Ho
Tim Martin Rustici Software
Tom Creighton ADL
Walt Grata ADL
2.2.2 Requirements Gathering Participants
In collection of requirements for the Experience API, there were many people and
organizations that provided invaluable feedback to SCORM, distributed learning efforts,
and learning in general. Project Tin Can User Voice Site, Rustici Software Blog, etc.
7/27/2019 Tin Can API (Tcapi) Spec
6/72
2.3 Reading guidelines for the non-technically inclined.
Since youre reading this document, its probably safe to say that youre interested in
understanding the Experience API (xAPI), informally called the "Tin Can API". The
purpose of this document is to describe how the xAPI is implemented in a large variety of
systems. Its a fairly technical document by nature and you may decide that you dontunderstand much of it. Even so, there are useful things to learn by reading further. Not
only because the tools that you work with are based on the specifications describedbelow; the technical people that you talk to may assume that you have a basic level of
knowledge. For this reason youre advised to read the small sections labeled description
and rationale while skipping the details and examples. Needless to say, many other
sources can be found that explain xAPI very well, but this document is the core of themall.
3.0 Definitions
Activity Authentication
Authorization
Community of Practice
Experience API (xAPI)
Immutable
Inverse Functional Identifier
Learning Activity Provider
Learning Management System (LMS)
Learning Record Store (LRS)"
MUST / SHOULD / MAY
Profile
Registration
Service
State
Statement
Tin Can API (TCAPI)
URI
Activity: A thing with which to be interacted. An activity can be a unit of instruction,
experience, or performance that is to be tracked in meaningful combination with a verb.
Interpretation of Activity is broad, meaning that activities can even be tangible objects.In the statement Anna tried a cake recipe: the recipe constitutes the Activity in terms of
the xAPI statement. Other examples include a book, an e-learning course, a hike or ameeting.
Authentication: The concept of verifying the identity of a user or system. Authentication
allows interactions between the two trusted parties.
https://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#def-activityhttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#def-authenticationhttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#def-authorizationhttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#def-community-of-practicehttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#def-experience-apihttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#def-immutablehttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#def-inverse-functinal-identifierhttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#def-activity-providerhttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#def-learning-management-systemhttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#def-learning-record-storehttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#def-must-should-mayhttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#def-profilehttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#def-registrationhttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#def-servicehttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#def-statehttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#def-statementhttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#tcapihttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#def-urihttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#def-activityhttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#def-authenticationhttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#def-authorizationhttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#def-community-of-practicehttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#def-experience-apihttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#def-immutablehttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#def-inverse-functinal-identifierhttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#def-activity-providerhttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#def-learning-management-systemhttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#def-learning-record-storehttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#def-must-should-mayhttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#def-profilehttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#def-registrationhttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#def-servicehttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#def-statehttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#def-statementhttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#tcapihttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#def-uri7/27/2019 Tin Can API (Tcapi) Spec
7/72
Authorization: The affordance of permissions based on a user or system's role; the
process of making one user or system "trusted" by another.
Community of Practice: A group, usually connected by a common cause, role orpurpose, which operates in a common modality.
Experience API (xAPI): The API defined in this document, the product of "Project Tin
Can". A simple, lightweight way for any permitted actor to store and retrieve extensible
learning records, learner and learning experience profiles, regardless of the platform used.
Immutable: Adjective used describe things which cannot be changed. With someexceptions, statements in the xAPI are immutable. This ensures that when statements are
shared between LRSs, multiple copies of the statement remain the same.
Inverse Functional Identifier: An identifier which is unique to a particular persona or
group. Used to identify Agents and Groups. See section 4.1.2
Learning Activity Provider (AP): The software object that is communicating with the
LRS to record information about a learning experience. May be similar to a SCORM
package in that it is possible to bundle learning assets with the software object thatperforms this communication, but an Activity Provider may also be separate from the
experience it is reporting about.
Learning Management System (LMS): Provides the tracking functionality of an LRS,
but provides additional administrative and reporting functionality. In this document theterm will be used when talking about existing systems that implement learning standards.
The xAPI can work independently of an LMS, but is built with knowledge of the suite of
services an LMS typically provides.
Learning Record Store (LRS): A system that stores learning information. Prior to thexAPI most LRSs were Learning Management Systems (LMSs), however this document
uses the term LRS to be clear that a full LMS is not necessary to implement the xAPI.
The xAPI is dependent on an LRS to function.
MUST / SHOULD / MAY: Three levels of obligation with regards to conformance tothe xAPI specification. A system that fails to implement a MUST (or a MUST NOT)
requirement is non-conformant. Failing to meet a SHOULD requirement is not a
violation of conformity, but goes against best practices. MAY indicates an option, to be
decided by the developer with no consequences for conformity.
Profile: A construct where information about the learner or activity is kept, typically in
name/document pairs that have meaning to an instructional system component.
Registration: When an LRS is an integral part of an LMS, the LMS likely supports the
concept of registration, an instance of a learner experiencing a particular learning activity.See section 4.1.6.
https://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#contexthttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#context7/27/2019 Tin Can API (Tcapi) Spec
8/72
Service: A software component responsible for one or more aspects of the distributed
learning process. An LMS typically combines many services to design a complete
learning experience.
State: Similar to SCORM suspend data, State allows storage of arbitrary key/document
pairs. The LRS does not have to retain state once the learning experience is considered"done" (the LRS has closed its "registration").
Statement: A simple statement consisting of,
with , in to track an aspect of a learning experience. A set of several
statements may be used to track complete details about a learning experience.
Tin Can API (TCAPI): The previous name of the API defined in this document, often
used in informal references to teh xAPI.
URI: Uniform Resource Identifier. A unique identifier which may be a URL. In the
xAPI, all URIs should be a full absolute URI including a scheme. Relative URIs shouldnot be used. URLs should be defined within a domain controlled by the person creating
the URL.
4.0 Statement
The statement is the core of the xAPI. All learning events are stored as statements. A
statement is akin to a sentence of the form "I did this".
4.1 Statement Properties:
Actor, verb, and object are required, all other properties are optional. Properties can occurin any order, but are limited to one use each. Each property is discussed below.
Property Type Default Description
id UUIDUUID assigned by LRS if not set by the Learning
Activity Provider.
actor ObjectWho the statement is about, as an Agent orGroupobject. Represents the "I" in "I Did This".
verb ObjectAction of the Learner or Team object. Represents the
"Did" in "I Did This".
object Object
Activity, agent, or another statement that is the objectof the statement. Represents the "This" in "I Did
This". Note that objects which are provided as a value
for this field should include a "objectType" field. Ifnot specified, the object is assumed to be an activity.
result ObjectResult object, further details representing a measured
outcome relevant to the specified verb.
context Object Context that gives the statement more meaning.
https://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#actorhttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#agenthttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#grouphttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#grouphttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#grouphttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#verbhttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#objecthttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#resulthttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#contexthttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#actorhttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#agenthttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#grouphttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#verbhttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#objecthttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#resulthttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#context7/27/2019 Tin Can API (Tcapi) Spec
9/72
Examples: a team the actor is working with, altitude at
which a scenario was attempted in a flight simulator.
timestamp Date/Time
Timestamp (Formatted according to ISO 8601) ofwhen what this statement describes happened. If not
provided, LRS should set this to the value of "stored"
time.
stored Date/TimeTimestamp (Formatted according to ISO 8601) of
when this statement was recorded. Set by LRS.
authority Object
Agent who is asserting this statement is true. Verified
by the LRS based on authentication, and set by LRS ifleft blank.
version String "1.0.0" xAPI version the statement conforms to. Set by LRS.
attachmentsArray ofattachment
objects
false Headers for attachments to the statement
Aside from (potential or required) assignments of properties during initial processing("id", "authority", "stored", "timestamp") statements are immutable. Note that the content
of activities that are referenced in statements is not considered part of the statement itself.So while the statement is immutable, the activities referenced by that statement are not.
This means a deep serialization of a statement into JSON will change if the referenced
activities change (see the Statement API's 'format' parameter for details).
An example of the simplest possible statement using all properties that MUST or
SHOULD be used:
{
"id": "12345678-1234-5678-1234-567812345678","actor":{
"mbox":"mailto:[email protected]"},"verb":{
"id":"http://adlnet.gov/expapi/verbs/created","display":{
"en-US":"created"}
},"object":{
"id":"http://example.adlnet.gov/xapi/example/activity"}
}
See Appendix D: Example statements for more examples.
4.1.1 ID:
Description:
https://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#timestamphttps://en.wikipedia.org/wiki/ISO_8601#Durationshttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#storedhttps://en.wikipedia.org/wiki/ISO_8601#Durationshttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#authorityhttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#versionhttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#attachmentshttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#stmtapihttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#AppendixDhttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#timestamphttps://en.wikipedia.org/wiki/ISO_8601#Durationshttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#storedhttps://en.wikipedia.org/wiki/ISO_8601#Durationshttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#authorityhttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#versionhttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#attachmentshttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#stmtapihttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#AppendixD7/27/2019 Tin Can API (Tcapi) Spec
10/72
A UUID (see RFC 4122 for requirements, and the UUID must be in standard string
form).
Details:
SHOULD be generated by the Learning Activity Provider.
MUST be generated by the LRS if a statement is received without an ID.
4.1.2 Actor:
Description:
A mandatory Agent or Group object.
4.1.2.1 Agent
Description:
An Agent (an individual) is a persona or system that can be involved in an action.
Details:
An agent...
MUST be identified by one (1) of the four types of inverse functional identifiers
(see 4.1.2.3 Inverse functional Identifier).
MUST NOT include more than one (1) inverse functional identifier;
SHOULD NOT use inverse functional identifiers that are also used for any
Groups;
is an important concept in relation to OAuth, see the section on OAuth for details.
The table below lists the properties of Agent objects, other than the inverse functional
identifiers (see 4.1.2.3 Inverse functional Identifier).
Property Type Description
objectType string"Agent". This property is optional except when the Agent is used as astatement's Object.
name string Full name of the Agent. This property is optional.
4.1.2.2 Group
Description:
A Group...
represents collections of Agents;
can be used most places an Agent can;
http://www.ietf.org/rfc/rfc4122.txthttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#inversefunctionalhttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#inversefunctionalhttp://www.ietf.org/rfc/rfc4122.txthttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#inversefunctionalhttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#inversefunctional7/27/2019 Tin Can API (Tcapi) Spec
11/72
can either be anonymous or identified.
Details
An anonymous group...
MAY be used to describe a cluster of people where there is no ready identifier for
this cluster, e.g. an ad hoc team;
MUST include a 'member' property listing constituent Agents;
MUST NOT contain Group objects in the 'member' property.
MUST NOT include any inverse functional identifiers
The table below lists all properties of an anonymous Group.
Property Type Description
objectType String "Group". This property is required.
name String Name of the group. Optional.
member Array of Agent objectsThe members of this Group.
An identified group...
MUST include exactly one (1) inverse functional identifier;
MAY include a 'member' property listing constituent Agents;
MUST NOT contain Group objects in the 'member' property.
SHOULD NOT use inverse functional identifiers that are also used for any
Agents.
The table below lists all properties of an identified Group, other than the inversefunctional identifiers (see4.1.2.3 Inverse functional Identifier).
Property Type Description
objectType String "Group". This property is required.
name String Name of the group. Optional.
member Array of Agent objectsThe members of this Group.
A system consuming Statements...
MUST consider each anonymous Group distinct even if it has an identical set of
members;
MUST NOT assume that Agents in the 'member' property comprise an exact list
of agents in a given anonymous or identified Group.
4.1.2.3 Inverse Functional Identifier
https://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#agenthttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#inversefunctionalhttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#inversefunctionalhttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#agenthttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#agenthttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#inversefunctionalhttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#agent7/27/2019 Tin Can API (Tcapi) Spec
12/72
Details:
An "inverse functional identifier" is a value of agents or identified groups that isguaranteed to only ever refer to that agent or identified group.
Rationale:
Learning experiences become meaningless if they cannot be attributed to identifiable
individuals and/or groups. In an xAPI statement this is accomplished with a set of inversefunctional identifiers loosely inspired on the widely accepted FOAF principle (see:
Friend Of A Friend).
Property Type Description
mboxmailto
URI
The required format is "mailto:email address".
The local part of the email address must be URI encoded.
Only emails that have only ever been and will ever be assigned
to this Agent, but no others, should be used for this propertyand mbox_sha1sum.
mbox_sha1sum string
The SHA1 hash of a mailto URI (i.e. the value of an mbox
property). An LRS MAY include Agents with a matching hash
when a request is based on an mbox.
openID URI An openID that uniquely identifies the Agent.
accountaccount
objectA user account on an existing system e.g. an LMS or intranet.
Account object
Description:
A user account on an existing system, such as a private system (LMS or intranet) or a
public system (social networking site).
Details:
If the system that provides the "account" uses OpenID, the Learning Activity
Provider SHOULD use the openID property instead of account.
If the Learning Activity Provider is concerned about revealing personally
identifiable information about an Agent or Group, it SHOULD use an opaque
account name (for example an account number) to identify all statements about aperson while maintaining anonimity.
The table below lists all properties of Account objects.
Property Type Description
homepage URL The canonical home page for the system the account is on. This is based
http://xmlns.com/foaf/spec/#term_Agenthttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#agentaccounthttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#agentaccounthttp://xmlns.com/foaf/spec/#term_Agenthttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#agentaccounthttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#agentaccount7/27/2019 Tin Can API (Tcapi) Spec
13/72
on FOAF's accountServiceHomePage.
name stringThe unique ID or name used to log in to this account. This is based onFOAF's accountName.
Example:
This example shows an agent identified by an opaque account:
{"objectType": "Agent","account": {
"homePage": "http://www.example.com","name": "1625378"
}}
4.1.3 Verb:
Description
The verb defines the action between actor and activity. It asserts what is done by the actor
in relation to the activity. Verbs appear in statements as objects consisting of a URI and aset of display names.
Rationale
The verb in an xAPI statement describes the learning experience. The xAPI does notspecify any particular verbs. (With one exception, namely the reserved verb
'http://adlnet.gov/expapi/verbs/voided'). Instead, it defines how to create verbs so that
communities of practice can coin their own meaningful verbs and make them availablefor use by anyone. A predefined list of verbs would be limited by definition and they
might not be able to effectively capture all possible future learning experiences.
Details
Semantics
The Verb URI identifies the particular semantics of a word, not the word itself.
For example, the English word "fired" could mean different things depending on context,
such as "fired a weapon", "fired a kiln", or "fired an employee". In this case, a URIMUST identify one of these specific meanings, not the word "fired".
Language
A verb in the Experience API is a URI, and denotes a specific meaning not tied to anyparticular language.
https://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#voidedhttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#voidedhttp://adlnet.gov/expapi/verbs/voidedhttp://adlnet.gov/expapi/verbs/voidedhttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#voidedhttp://adlnet.gov/expapi/verbs/voided7/27/2019 Tin Can API (Tcapi) Spec
14/72
7/27/2019 Tin Can API (Tcapi) Spec
15/72
A system reading a statement:
MUST use the verb URI to infer meaning;
MUST NOT use the display property to infer any meaning from the statement;
MUST NOT use the display property for any purpose other than display to a
human. For example, the display property MUST NOT be used for aggregation orcategorization of statements.
The table below lists all properties of the Verb object.
Propert
yType Description Example
id URI
Corresponds to a
verb definition.
Each verbdefinition
corresponds to themeaning of a verb,not the word. The
URI should be
human-readable
and contain theverb meaning.
id :"http://www.adlnet.gov/XAPIprofile/ran(travelled_a_distance)"
displayLangua
ge Map
The human
readablerepresentation of
the verb in one or
more languages.This does not have
any impact on the
meaning of the
statement, butserves to give a
human-readable
display of themeaning
already determine
d by the chosen
verb.
display : { "en-US" : "ran"}
display : { "en-US" : "ran", "es" : "corri" }
The verb in the table above is included for illustrative purposes only. This is not intended
to imply that a verb with this meaning has been defined with this id. This applies to all
example verbs given in this specification document, with the exception of the reservedverb 'http://adlnet.gov/expapi/verbs/voided'.
4.1.4 Object
http://www.adlnet.gov/XAPIprofile/ran(travelled_a_distance)http://www.adlnet.gov/XAPIprofile/ran(travelled_a_distance)https://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#misclangmaphttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#misclangmaphttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#voidedhttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#voidedhttp://adlnet.gov/expapi/verbs/voidedhttp://www.adlnet.gov/XAPIprofile/ran(travelled_a_distance)http://www.adlnet.gov/XAPIprofile/ran(travelled_a_distance)https://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#misclangmaphttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#misclangmaphttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#voidedhttp://adlnet.gov/expapi/verbs/voided7/27/2019 Tin Can API (Tcapi) Spec
16/72
Definition
The object of a statement is the Activity, Agent, or Statement that is the object of thestatement. It is the "this" part of the statement, cf. "I did this".
NOTE:
Objects which are provided as a value for this field SHOULD include an "objectType"
field. If not specified, the object is assumed to be an Activity. Other valid values are:Agent,Statement orStatementRef.
Rationale
Objects in a statement may be either an Activity, an Agent or another statement. Someexamples:
The object is an Activity: "Jeff wrote an essay about hiking."
The Object is an Agent: "Nellie interviewed Jeff." The Object is a Statement: "Nellie commented on 'Jeff wrote an essay about
hiking.'"
Statements as objects are typically, but not exclusively, used in scenarios where some
existing activity is graded, reviewed or commented on.
4.1.4.1 When the "Object" is an Activity
A statement may represent an Activity as the object of the statement. An activity is anything which is interacted with. See section 3.0 Definitions.
Property Type Description
objectType String MUST be "Activity" when present. Optional in all cases.
id URIMAY be a URL, which points to the logical definition of theactivity. This MAY point to metadata or the URL for the
activity
definition
Activity
DefinitionObject
Metadata, See below
Activity ID
An activity ID must always refer to a single unique activity. There may be corrections tothat activity's definition. Spelling fixes would be appropriate, for example, but changing
correct responses would not.
The activity ID is unique, and any reference to it always refers to the same activity.
Activity Providers must ensure this is true and the LRS may not attempt to treat multiplereferences to the same ID as references to different activities, regardless of any
https://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#agentasobjhttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#substmthttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#substmthttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#stmtrefhttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#30-definitionshttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#acturihttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#actdefhttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#actdefhttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#agentasobjhttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#substmthttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#stmtrefhttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#30-definitionshttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#acturihttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#actdefhttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#actdef7/27/2019 Tin Can API (Tcapi) Spec
17/72
information which indicates two authors or organizations may have used the same
activity ID.
When defining an activity ID, care must be taken to make sure it will not be re-used. Itshould use a domain the creator controls or has been authorized to use for this purpose,
according to a scheme the domain owner has adopted to make sure activity IDs withinthat domain remain unique.
Any state or statements stored against an activity ID must be compatible and consistentwith any other state or statements that are stored against the same activity ID, even if
those statements were stored in the context of a new revision or platform.
NOTE:
The prohibition against an LRS treating references to the same activity ID as twodifferent activities, even if the LRS can positively determine that was the intent, is crucial
to prevent activity ID creators from creating IDs that could be easily duplicated, as intent
would be indeterminable should a conflict with another system arise.
Activity Definition
Property Type Description
nameLanguageMap
The human readable/visual name of theactivity
descriptionLanguage
MapA description of the activity
type URI
the type of activity. Note, URI fragments(sometimes called relative URLs) are not
valid URIs.As with verbs, we recommendthat Learning Activity Providers look forand use established, widely adopted, activity
types.
url URL
An optional url which SHOULD resolve toa document human-readable information
about the activity, which MAY inclue a way
to 'launch' the activity.
interactionType |correctResponsesPattern |
choices | scale | source | target |
steps
See "Interaction Activities"
extensionsExtensions
Object
A map of other properties as needed (see:
Extensions)
An LRS should update its internal representation of an activity's definition upon
receiving a statement with a different definition of the activity from the one stored, but
only if it considers the Learning Activity Provider to have the authority to do so.
https://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#misclangmaphttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#misclangmaphttps://github.com/adlnet/xAPI-Spec/blob/master/misclangmaphttps://github.com/adlnet/xAPI-Spec/blob/master/misclangmaphttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#verb-lists-and-repositorieshttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#verb-lists-and-repositorieshttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#interactionactshttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#miscexthttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#misclangmaphttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#misclangmaphttps://github.com/adlnet/xAPI-Spec/blob/master/misclangmaphttps://github.com/adlnet/xAPI-Spec/blob/master/misclangmaphttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#verb-lists-and-repositorieshttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#interactionactshttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#miscext7/27/2019 Tin Can API (Tcapi) Spec
18/72
Activity Metadata
Activities with URL identifiers MAY may host metadata using the activity
definition JSON format which is used in statements, with a Content-Type of
"application/json"
If the activity URI is a URL, LRS's SHOULD attempt to GET that URL, and
include in HTTP headers: "Accept: application/json, /". This SHOULD be done assoon as practical after the LRS first encounters the activity id.
If the LRS loads JSON which is a valid activity definition from a URL used as an
activity id, the LRS SHOULD incorporate the loaded definition into its internaldefinition for that activity, while preserving names or definitions not included in
the loaded definition.
If the LRS loads any document from which the LRS can parse an activity
definition from a URL used as an activity id, then the LRS MAY consider thisdefinition when determining its internal representation of that activity's definition.
Interaction Activities
Traditional e-learning has included structures for interactions or assessments. As a way to
allow these practices and structures to extend Experience API's utility, this specificationinclude built in definitions for interactions which borrows from the CMI data model.
These definitions are intended to provide a simple and familiar utility for recording
interaction data. These definitions are simple to use, and consequently limited. It isexpected that communities of practice requiring richer interactions definitions will do so
through the use of extensions to an activity's type and definition.
When defining interaction activities, the activity type:
"http://adlnet.gov/expapi/activities/cmi.interaction" SHOULDbe used, and a valid
interactionType MUST be specified. If interactionType is specified, an LRS processingMAY validate the remaining properties as specified in the table below, and return HTTP
400 "Bad Request" if the remaining properties are not valid for the interaction type.
Property Type Description
interactionType StringAs in "cmi.interactions.n.type" as defined in the
SCORM 2004 4th edition Runtime Environment.
correctResponsesPatternAn array of
strings
Corresponds to"cmi.interactions.n.correct_responses.n.pattern" as
defined in the SCORM 2004 4th edition Runtime
Environment, where the final n is the index of the
array.
choices | scale | source |
target | steps
Array of
interaction
components
Specific to the given interactionType (see below).
Interaction Components
Interaction components are defined as follows:
https://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#actdefhttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#actdefhttp://adlnet.gov/expapi/activities/cmi.interaction%22%C2%A0SHOULDhttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#interactionTypehttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#actdefhttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#actdefhttp://adlnet.gov/expapi/activities/cmi.interaction%22%C2%A0SHOULDhttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#interactionType7/27/2019 Tin Can API (Tcapi) Spec
19/72
Property Type Description
id StringAs in "cmi.interactions.n.id" as defined in the SCORM 2004 4th
edition Runtime Environment
descriptionLanguage
Map
a description of the interaction component (for example, the text
for a given choice in a multiple-choice interaction)
The following table shows the supported lists of CMI interaction components for an
interaction activity with the given interactionType.
interactionType supported component list(s)
choice, sequencing choices
likert scale
matching source, target
performance steps
true-false, fill-in, numeric, other [No component lists defined]
See Appendix C for examples of activity definitions for each of the cmi.interaction types.
4.1.4.2 When the "Object" is an Agent or a Group
Statements that specify an Agent or Group as an Object...
MUST specify an 'objectType' property.
See section 4.1.2 for details regarding Agents.
4.1.4.3 When the "Object" is a Statement
Rationale
A statement that is the object in another statement can either be existing or new. Forexample, when grading or commented on an experience that is tracked as an independant
event, the existing statement about that experience will be the object of the statement.
Also, in the special case ofvoiding, the object is an already existing statement. In thesesituations, a Statement Reference is used.
When the object is an experience that would be misleading as an independent statement,
that experience can be tracked as a statement within a statement. These are called Sub-Statements. An example is given further below.
Statement References
A statement reference is a pointer to another pre-existing statement.
The table below lists all properties of a Statement Reference object:
https://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#misclangmaphttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#misclangmaphttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#AppendixChttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#actorhttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#voidedhttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#voidedhttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#voidedhttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#misclangmaphttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#misclangmaphttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#AppendixChttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#actorhttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#voided7/27/2019 Tin Can API (Tcapi) Spec
20/72
Property Type Description
objectType string MUST be "StatementRef".
id UUIDMUST be set to the UUID of a statement which is present on the
system.
Statement References - Example
Assuming that some statement has already been stored with the ID 8f87ccde-bb56-4c2e-ab83-44982ef22df0, the following example shows how a comment could be issued on the
original statement, using a new statement:
{"actor" : {
"objectType": "Agent","mbox":"mailto:[email protected]"
},"verb" : {
"id":"http://example.com/commented","display": {
"en-US":"commented"}
},"object" : {
"objectType":"StatementRef","id":"8f87ccde-bb56-4c2e-ab83-44982ef22df0"
},"result" : {
"response" : "Wow, nice work!"}
}
Sub-Statements
A Sub-Statement is a new statement included as part of a parent statement.
Requirements
A Sub-Statement...
MUST specify an "objectType" property with the value "SubStatement";
MUST NOT have the "id", "stored", or "authority" properties;
MUST NOT contain a sub-statement of their own i.e. cannot be nested.
Implementations MUST validate the sub-statement as they would other statements, with
the addition of these rules.
Sub-statements - Example
One interesting use of sub-statements is in creating statements of intention. For example,
using sub-statements we can create statements of the form " (
7/27/2019 Tin Can API (Tcapi) Spec
21/72
)" to indicate that we've planned to take some action. The concrete
example that follows logically states that "I planned to visit 'Some Awesome Website'".
{"actor": {
"objectType": "Agent",
"mbox":"mailto:[email protected]"},"verb" : {
"id":"http://example.com/planned","display":{
"en-US":"planned"}
},"object": {
"objectType": "SubStatement","actor" : {
"objectType": "Agent","mbox":"mailto:[email protected]"
},"verb" : {"id":"http://example.com/visited","display":{
"en-US":"will visit"}
},"object": {
"id":"http://example.com/website","definition": {
"name" : {"en-US":"Some Awesome Website"
}}
}}
}
NOTE:
Whilst the verb display MAY take the future tense, the verb id SHOULD remain past
tense. Later, when 'I' actually visit 'Some Awesome Website', reporting tools can therebymatch the verb ids.
4.1.5 Result:
Description:
An optional field that represents a measured outcome related to the statement in which itis included.
Details
7/27/2019 Tin Can API (Tcapi) Spec
22/72
A result can be completion, success, score, etc. The 'Result' field may also contain
arbitrary measurements if needed by the Learning Activity Provider.
property type description
score Score object
The score of the agent in relation to the
success or quality of the experience.
success Boolean Was the learning activity successful?
completion Boolean Was the learning activity completed?
response StringA response appropriately formatted forthe given activity.
durationFormatted according toISO 8601
with a precision of 0.01 seconds
Period of time over which the statement
occurred.
Extensions Extensions object A map of other properties as needed.
4.1.5.1 Score property
Description
An optional numeric field that represents the outcome of a graded activity achieved by an
agent.
The table below defines the score object.
Property Type Description
scaled Decimal number between -1 and 1, inclusiveCf. 'cmi.score.scaled' in SCORM
2004 4th Edition
rawDecimal number between min and max (if
present, otherwise unrestricted), inclusiveCf. 'cmi.score.raw'
min Decimal number less than max (if present) Cf. 'cmi.score.min'
max Decimal number greater than min (if present) Cf. 'cmi.score.max'
Details
The Score property...
SHOULD include 'scaled' if a logical percent based score is known; SHOULD NOT be used for scores relating to progress or completion. Consider
using an extension from an extension profile instead.
4.1.6 Context
Description:
https://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#Scorehttps://en.wikipedia.org/wiki/ISO_8601%22%20%5Cl%20%22Durationshttps://en.wikipedia.org/wiki/ISO_8601%22%20%5Cl%20%22Durationshttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#miscexthttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#Scorehttps://en.wikipedia.org/wiki/ISO_8601%22%20%5Cl%20%22Durationshttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#miscext7/27/2019 Tin Can API (Tcapi) Spec
23/72
An optional field that provides a place to add contextual information to a statement. All
its field properties are optional.
Rationale:
The "context" field provides a place to add some contextual information to a statement. It
can store information such as the instructor for an experience, if this experience happened
as part of a team activity, or how an experience fits into some broader activity.
property type description
registration UUIDThe registration that the statement is associated
with. See 4.1.6.1
instructorAgent (may be a
group)
Instructor that the statement relates to, if not
included as the Actor of the statement.
team GroupTeam that this statement relates to, if not included
as the Actor of the statement.
contextActivitiescontextActivitiesobject
A map of the types of learning activity context that
this statement is related to. Valid context typesare: "parent", "grouping", "category", "other". See
4.1.6.2
revision String
Revision of the learning activity associated with
this statement. Format is free.- SHOULD be used to track fixes of minor issues
(like a spelling error),
- SHOULD NOT be used if there is a major
change in learning objectives, pedagogy, or assets
of an activity. (Use a new activity ID instead).- MUST NOT be used if the statement's object is a
Person.
platform String
Platform used in the experience of this learning
activity.- MUST NOT be used if the statement's object is a
Person.
Defined vocabulary, TBD.
language
String (as defined in
RFC 5646)
Code representing the language in which the
experience being recorded in this statement
(mainly) occurred in, if applicable and known.- MUST NOT be used if not applicable or
unknown.
statementStatement byreference or by
object
Another statement (either existing or new), which
should be considered as context for this statement.See section 4.1.4.3 for details about including
statements within other statements.
https://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#Registrationhttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#contextActivitieshttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#contextActivitieshttp://tools.ietf.org/html/rfc5646https://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#stmtasobjhttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#Registrationhttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#contextActivitieshttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#contextActivitieshttp://tools.ietf.org/html/rfc5646https://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#stmtasobj7/27/2019 Tin Can API (Tcapi) Spec
24/72
extensions Extensions object
A map of any other domain-specific contextrelevant to this statement. For example, in a flight
simulator altitude, airspeed, wind, attitude, GPS
coordinates might all be relevant (See section 5.3)
4.1.6.1 Registration property
Description:
An instance of a learner undertaking a particular learning activity.
Details:
When an LRS is an integral part of an LMS, the LMS likely supports the concept ofregistration. For example all the statements about one time a person took a test might
have one registration. If the learner takes the test again, the statements from this second
occasion would have a different registration from the first occasion.
The LMS may also close the registration at some point when it considers the learningexperience complete. For Experience API purposes, a registration may be applied more
broadly; an LMS could assign a group of students to a group of activities and track all
related statements in one registration.
4.1.6.2 contextActivities property
Description:
A map of the types of learning activity context that this statement is related to.
Rationale:
Many statements do not just involve one object activity that is the focus, but relate to
other contextually relevant activities. "Context activities" allow for these related activities
to be represented in a structured manner.
Requirements
every key in the contextActivities object MUST be one of parent, grouping,
category, or other.
every value in the contextActivities object MUST be either a single Activity
object or an array of Activity objects.
Requirements for the client
every value in the contextActivities object SHOULD be an array of Activity
objects instead of a single Activity object.
Requirements for the LRS
https://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#miscexthttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#miscext7/27/2019 Tin Can API (Tcapi) Spec
25/72
every value in the contextActivities object MUST be returned as an array, even if
it arrived as a single Activity object (in which case it MUST be returned as an
array of length one containing the same Activity).
Details:
There are four valid context types. All, any or none of these MAY be used in a given
statement:
1. Parent : an activity with a direct relation to the activity which is the object of the
statement. In almost all cases there is only one sensible parent or none, not
multiple. For example: a statement about a quiz question would have the quiz as
its parent activity.2. Grouping : an activity with an indirect relation to the activity which is the object
of the statement. For example: a course that is part of a qualification. The course
has several classes. The course relates to a class as the parent, the qualificationrelates to the class as the grouping.
3. Category : an activity used to categorize the statement. "Tags" would be a
synonym. Category SHOULD be used to indicate a "profile" of xAPI behaviors,
as well as other categorizations. For example: Anna attempts a biology exam, andthe statement is tracked using the CMI-5 profile. The statement's activity refers to
the exam, and the category is the CMI-5 profile.
4. Other : a context activity that doesn't fit one of the other fields. For example:
Anna studies a textbook for a biology exam. The statement's activity refers to thetextbook, and the exam is a context activity of type "other".
Single Activity objects are allowed as values so that 0.95 statements will be compatiblewith 1.0.0.
The values in this section are not for expressing all the relationships the statement objecthas. Instead, they are for expressing relationships appropriate for the specific statement
(though the nature of the object will often be important in determining that). For instance,
it is appropriate in a statement about a test to include the course the test is part of asparent, but not to include every possible degree program the course could be part of in the
grouping value.
Example I:
{"other" : [{"id" : "http://example.adlnet.gov/xapi/example/test"}]
}
Example II:
7/27/2019 Tin Can API (Tcapi) Spec
26/72
Consider the following hierarchical structure: "Questions 1 to 6" are part of "Test 1"
which in turn belongs to the course "Algebra 1". The six questions are registered as part
of the test by declaring "Test 1" as their parent. Also they are grouped with otherstatements about "Algebra 1" to fully mirror the hierarchy. This is particularly useful
when the object of the statement is an agent, not an activity. "Andrew mentored Ben with
context Algebra I".
{"parent" : [{"id" : "http://example.adlnet.gov/xapi/example/test 1"}],"grouping" : [{"id" : "http://example.adlnet.gov/xapi/example/Algebra1"}]
}
4.1.7 Timestamp:
Definition
The time at which a statement about an experience took place.
Requirements
A timestamp:
MUST be formatted according to ISO 8601;
MAY be truncated or rounded to a precision of at least 3 decimal digits for
seconds (millisecond precision MUST be preserved)
SHOULD include the timezone;
MAY be a moment in the future, to denote a deadline for planned learning,
provided it is included inside a SubStatement;
SHOULD be the current or a past time when it is outside of a SubStatement.
A reporting tool:
MAY consider timestamps from different timezones that represent the same
logical time to be equivalent.
Details
A timestamp in a statement related to learning that occurs outside of the system can differfrom 4.1.8. Stored (the system time of the event). Namely, there can be delays betweenthe occurrence of the experience and the reception of the corresponding statement by the
LRS. Another cause is when statements are propagated to other systems.
4.1.8 Stored:
Definition:
https://en.wikipedia.org/wiki/ISO_8601#Combined_date_and_time_representationshttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#storedhttps://en.wikipedia.org/wiki/ISO_8601#Combined_date_and_time_representationshttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#stored7/27/2019 Tin Can API (Tcapi) Spec
27/72
The time at which a statement is stored by the LRS.
Requirements
Stored time:
MUST be formatted according to ISO 8601;
MAY be truncated or rounded to a precision of at least 3 decimal digits for
seconds (millisecond precision MUST be preserved)
SHOULD include the timezone;
SHOULD be the current or a past time
A reporting tool:
MAY consider stored time from different timezones that represent the same
logical time to be equivalent.
4.1.9 Authority:
The authority property provides information about who or what has asserted that thisstatement is true. Consequently, the asserting authority may be anAgent (representing the
authenticating user or some system or application), or in the case of 3-legged OAuth
workflows, a Groupof two Agents representing an application and user together. Unlessused in the aforementioned 3-legged OAuth workflow, a Group MUST NOT be used to
assert authority.
LRS Requirements:
The LRS SHOULD overwrite the authority on all stored recieved statements,based on the credentials used to send those statements.
The LRS MAY leave the submitted authority unchanged but SHOULD do so only
where a strong trust relationship has been established, and with extreme caution.
The LRS MUST ensure that all statements stored have an authority.
If a statement is stored using a validated OAuth connection, and the LRS creates ormodifies the authority property of the statement, the authority MUST contain an agent
object that represents the OAuth consumer, either by itself, or as part of a group in the
case of 3-legged OAuth. This agent MUST be identified by account, and MUST use theconsumer key as the account name field. If the OAuth consumer is a registered
application,then the token request endpoint MUST be used as the account homePage,otherwise the temporary credentials endpoint must be used as the account homePage.
Except as specified in the paragraph above, agent objects MUST NOT use any OAuthendpoint as an account homePage.
The behavior of an LRS SHOULD NOT rely on Agents with an account using the
temporary credentials endpoint as the homePage and with matching account names
https://en.wikipedia.org/wiki/ISO_8601#Combined_date_and_time_representationshttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#agenthttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#agenthttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#grouphttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#grouphttps://en.wikipedia.org/wiki/ISO_8601#Combined_date_and_time_representationshttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#agenthttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#group7/27/2019 Tin Can API (Tcapi) Spec
28/72
coming from the same source, as there is no way to verify that, since multiple
unregistered applications could choose the same consumer key. Each unregistered
consumer SHOULD pick a unique consumer key.
If a user connects directly (using HTTP Basic Authentication) or is included as part of a
3-legged OAuth workflow, the LRS MUST include the user as an Agent in the authority,and MAY identify the user with any of the legal identifying properties.
OAuth Authorities
In a 3-legged OAuth workflow, authentication involves both an OAuth consumer and a
user of the OAuth service provider. For instance, requests made by an authorized Twitter
plugin on your Facebook account will include credentials that are specific not only toTwitter as a client application, or you as a user, but the unique combination of both.
To support this concept, an LRS preparing the authority of a statement received via 3-
legged OAuth MUST use a pairing of an application and a user. Below is a concrete
example which represents a pairing of an OAuth consumer and a user.
"authority": {"objectType" : "group","member": [
{"account": {
"homePage":"http://example.com/xAPI/OAuth/Token","name":"oauth_consumer_x75db"
}},{
"mbox":"mailto:[email protected]"
}]
}
4.1.10 Voided:
Rationale
The certainty that an LRS has an accurate and complete collection of data is guaranteed
by the fact that statements cannot be logically changed or deleted. This immutability ofstatements is a key factor in enabling the distributed nature of Experience API. However,
not all statements are perpetually valid once they have been issued. Mistakes or other
factors could require that a previously made statement is marked as invalid. This is calledvoiding a statement and the reserved verb http://adlnet.gov/expapi/voided is used for
this purpose.
Requirements
When issuing a statement that voids another, the object of that voiding statement...
http://adlnet.gov/expapi/voided%E2%80%9Dhttp://adlnet.gov/expapi/voided%E2%80%9D7/27/2019 Tin Can API (Tcapi) Spec
29/72
MUST have the objectType field set to StatementRef;
MUST specify the ID of the statement-to-be-voided by its id field.
Upon receiving a statement that voids another, the LRS...
MAY roll back any changes to activity or agent definitions which were introducedby the statement that was just voided;
SHOULD return a descriptive error if the target statement cannot be found;
MUST NOT report the voided statement when queried, but MUST report the
voiding statement (see StatementRefin 7.2 Statement API).
Example
{"actor" : {
"objectType": "Agent","name" : "Example Admin","mbox" : "mailto:[email protected]"
},"verb" : {
"id":"http://adlnet.gov/expapi/verbs/voided","display":{
"en-US":"voided"}
},"object" : {
"objectType":"StatementRef","id" : "e05aa883-acaf-40ad-bf54-02c8ce485fb0"
}}
This example statement voids a previous statement which it identifies with the statementID "e05aa883-acaf-40ad-bf54-02c8ce485fb0".
Details
Any statement that voids another cannot itself be voided. An activity provider that wants
to unvoid a previously voided statement...
SHOULD issue that statement again under a new ID
A reporting system...
SHOULD NOT show voided or voiding statements by default.
See "Statement References" in section 4.1.4.3 for details about making references to
other statements.
4.1.11 Attachments
https://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#queryStatementRefhttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#queryStatementRefhttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#stmtrefhttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#stmtasobjhttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#queryStatementRefhttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#stmtrefhttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#stmtasobj7/27/2019 Tin Can API (Tcapi) Spec
30/72
Description:
A digital artefact providing evidence of a learning experience.
Rationale:
In some cases an attachment may logically be an important part of a learning record.Think of a simulated communication with ATC, an essay, a video, etc. Another example
of such an attachment is (the image of) a certificate that was granted as a result of anexperience. It is useful to have a way to store these attachments in and retrieve them from
an LRS.
Details:
The table below lists all properties of the Attachment object.
Property Type Description Required
usageType URI
Identifies the usage of this attachment. For example:one expected use case for attachments is to include a"completion certificate". A type URI corresponding
to this usage should be coined, and used with
completion certificate attachments.
yes
displayLanguage
MapDisplay name (title) of this attachment. yes
descriptionLanguage
MapA description of the attachment no
contentType
Internet
Media
Type
The content type of the attachment. yes
length integer The length of the attachment data in octets yes
sha2 base64The SHA-2 hash of the attachment data. A minimum
key size of 256 bits is recommended.yes
fileUrl URLA URL at which the attachment data may beretrieved, or from which it used to be retrievable.
no
Procedure for the exchange of attachments
Since these attachments may lead to very large statements, it should be possible for a
client to filter out attachments when retrieving statements, by following this procedure:
1. A statement including an attachment is construed according to the Transmission
Format described below.
2. The statement is sent to the receiving system using a content-Type of
"multipart/mixed". The attachments are placed at the end of such transmissions.3. The receiving system decides whether to accept or reject the statement based on
the information in the first part.
https://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#misclangmaphttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#misclangmaphttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#misclangmaphttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#misclangmaphttps://www.ietf.org/rfc/rfc2046.txt?number=2046https://www.ietf.org/rfc/rfc2046.txt?number=2046https://www.ietf.org/rfc/rfc2046.txt?number=2046https://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#misclangmaphttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#misclangmaphttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#misclangmaphttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#misclangmaphttps://www.ietf.org/rfc/rfc2046.txt?number=2046https://www.ietf.org/rfc/rfc2046.txt?number=2046https://www.ietf.org/rfc/rfc2046.txt?number=20467/27/2019 Tin Can API (Tcapi) Spec
31/72
4. If it accepts the attachment, it can match the raw data of an attachment with the
attachment header in a statement by comparing the SHA-2 of the raw data to the
SHA-2 declared in the header.
Requirements for statement streams that include attachments
A statement stream that includes attachments:
MUST be of type "multipart/mixed" rather than "application/json";
o The first part of the multipart document MUST contain the statements
themselves, with type "applicaton/json";
o Each additional part contains the raw data for an attachment and forms a
logical part of the statement. This capability will be available when issuing
PUT or POST against the statement resource.
SHOULD only include one copy of an attachment when the same attachment is
used in multiple statements that are sent in one message;
MUST conform to the definition of multipart/mixed in RFC 1341;
SHOULD include a Content-type field in each part's header, for the first part this
MUST be "application/json";
MUST include a X-Experience-API-Hash field in each part's header after the first
(statements) part;
o This field MUST be set to match the "sha2" property of the attachment
declaration corresponding to the attachment included in this part.
MUST include a Content-Transfer-Encoding field with a value of "binary" in
each part's header after the first (statements) part;
Requirements for the LRS:
MUST accept statements via the statements resource PUT or POST that containattachments in the Transmission Format described above;
MUST reject statements having attachments that neither contain a fileUrl nor
match a received attachment part based on their hash;
MUST include attachments in the Transmission Format described above when
requested by the client (see section7.2 "Statement API");
MUST NOT pull statements from another LRS without requesting attachments;
MUST NOT push statements into another LRS without including attachments;
MAY reject (batches of) statements that are larger than the LRS is configured to
allow;
SHOULD accept statements in the above format that don't declare any
attachments. SHOULD assume a Content-Transfer-Encoding of binary for attachment parts
Requirements for the client:
MAY send statements with attachments as described above;
MAY send multiple statements where some or all have attachments if using
"POST".
https://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#stmtapihttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#stmtapihttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#stmtapi7/27/2019 Tin Can API (Tcapi) Spec
32/72
Example:
Below is an example of a very simple statement with an attachment. Please note thefollowing:
The boundary in the sample was chosen to demonstrate valid character classes;
The selected boundary does not appear in any of the parts;
For readability the sample attachment is text/plain. Even if it had been a 'binary'
type like 'image/jpeg' no encoding would be done, the raw octets would be
included;
Per RFC 1341, the boundary is followed by -- followed by the boundary string
declared in the header.
Don't forget the when building or parsing these messages.
Headers:
Content-Type: multipart/mixed; boundary=abcABC0123'()+_,-./:=?X-Experience-API-Version:1.0.0
Content:
--abcABC0123'()+_,-./:=?Content-Type:application/json
{"actor": {
"mbox": "mailto:[email protected]",
"name": "Sample Agent","objectType": "Agent"},"verb": {
"id": "http://adlnet.gov/expapi/verbs/answered","display": {
"en-US": "answered"}
},"object": {
"id": "http://www.example.com/tincan/activities/multipart","objectType": "Activity","definition": {
"name": {
"en-US": "Multi Part Activity"},"description": {
"en-US": "Multi Part Activity Description"}
}},"attachments": [
{
7/27/2019 Tin Can API (Tcapi) Spec
33/72
7/27/2019 Tin Can API (Tcapi) Spec
34/72
The JWS signature SHOULD have been created based on the private key
associated with an X.509 certificate.
If X.509 was used to sign, the JWS header SHOULD include the "x5c" property
containing the associated certificate chain.
LRS requirements when receiving a signed statement:
The LRS MUST reject requests to store statements that contain malformed
signatures, with HTTP 400 and SHOULD include a message describing theproblem in the response. In order to verify signatures are well formed, the LRS
MUST do the following:
o Decode the JWS signature, and load the signed serialization of the
statement from the JWS signature payload.
o Validate that the "original" statement is logically equivalent to the
received statement.
o If the JWS header includes an X.509 certificate, validate the signature
against that certificate as defined in JWS.
Note: The step of validating against the included X.509 certificate is intended as a way to
catch mistakes in the signature, not as a security measure. Clients MUST NOT assume asignature is valid simply because an LRS has accepted it. The steps to authenticate a
signed statement will vary based on the degree of certainty required and are outside the
scope of this specification.
See Appendix F: Example Signed Statement for an example.
4.1.13 Data Constraints
All the properties used in statements are restricted to certain types, and those types
constrain the behavior of systems processing statements. For clarity, certain key
requirements are documented here, emphasizing where compliant systems have a
responsibility to act in certain ways.
Client Requirements:
The following requirements reiterate especially important requirements already included
elsewhere, to emphasize, clarify, and provide implementation guidance.
Values requiring IRIs MUST be sent with valid IRIs. Please use a library to
construct them instead of string concatenation. Complete IRI validation is
extremely difficult, so much of the burden for ensuring data portability is on the
client.
For similar reasons, keys of language maps MUST be sent with valid RFC 5646
language tags.
LRS Requirements:
https://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#AppendixFhttps://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#AppendixF7/27/2019 Tin Can API (Tcapi) Spec
35/72
MUST reject statements
o with any null values (except inside extensions).
o with strings where numbers are required, even if those strings contain
numbers.
o with strings where booleans are required, even if those strings contain
booleans.o with any non-format-following key or value, including the empty string,
where a. string with a particular format (such as mailto URI, UUID, orIRI) is required.
o where the case of a key does not match the case specified in the standard.
o where the case of a value restricted to enumerated values does not match
an enumerated value given in the standard exactly.
MAY use best-effort validation for URL, URI, and IRI formats to satisfy the non-
format-following rejection requirement.
MUST reject statements containing URL, URI, or IRI values without a scheme.
MAY use best-effort validation for language map keys to satisfy the non-format-
following rejection requirement. MUST at least validate that the sequence of token lengths for language map keys
matches the RFC 5646 standard.
MUST process and store numbers with at least the precision of IEEE 754 32-bit
floating point numbers.
MUST validate parameter values to the same standards required for values of the
same types in statements. Note: string parameter values are not quoted as they arein JSON.
4.2 Retrieval of Statements:
A collection of statements can be retrieved by performing a query on the "statements"endpoint, see section 7.2 "Statement API" for details.
Property Type Description
statementsArray of
Statements
List of statements. If the list returned has been limited (due topagination), and there are more results, they will be located at the
"statements" property within the container located at the URL
provided by the "more" element of this statement result object.
more URL
Relative URL that may be used to fetch more results, includingthe full path and optionally a query string but excluding scheme,
host, and port. Empty string if there are no more results to fetch.
This URL must be usable for at least 24 hours after it is returned
by the LRS. In order to avoid the need to store these URLs and
associated query data, an LRS may include all necessaryinformation within the URL to continue the query, but should
avoid generating extremely long URLs. The consumer should not
attempt to interpret any meaning from the URL returned.
http://tools.ietf.org/html/rfc5646https://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#stmtapihttp://tools.ietf.org/html/rfc5646https://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#stmtapi7/27/2019 Tin Can API (Tcapi) Spec
36/72
5.0 Miscellaneous Types
5.1 Document:
The Experience API provides a facility for Activity Providers to save arbitrary data in the
form of documents, which may be related to an Activity, Agent, or combination of both.
Property Type Description
id String Set by AP, unique within state scope (learner, activity).
updated Timestamp When the document was most recently modified.
contents Arbitrary binary data The contents of the document
Note that in the REST binding, State is a document not an object. ID is stored in theURL, updated is HTTP header information, and contents is the HTTP document itself.
5.2 Language Map
A language map is a dictionary where the key is a RFC 5646 Language Tag, and thevalue is a string in the language specified in the tag. This map should be populated as
fully as possible based on the knowledge of the string in question in different languages.
5.3 Extensions
Extensions are defined by a map. The keys of that map MUST be URLs, and the values
MAY be any JSON value or data structure. The meaning and structure of extensionvalues under a URL key are defined by the person who coined the URL, who SHOULD
be the owner of the URL, or have permission from the owner. The owner of the URLSHOULD make a human-readable description of the intended meaning of the extension
supported by the URL accessible at the URL. A learning record store MUST NOT rejectan Experience API statement based on the values of the extensions map.
Extensions are available as part of activity definitions, as part of statement context, or as
part of some statement result. In each case, theyre intended to provide a natural way to
extend those elements for some specialized use. The contents of these extensions mightbe something valuable to just one application, or it might be a convention used by an
entire community of practice.
Extensions should logically relate to the part of the statement where they are present.Extensions in statement context should provide context to the core experience, while
those in the result should provide elements related to some outcome. For activities, they
should provide additional information that helps define an activity within some custom
application or community.
Note:
http://tools.ietf.org/html/rfc5646http://tools.ietf.org/html/rfc56467/27/2019 Tin Can API (Tcapi) Spec
37/72
7/27/2019 Tin Can API (Tcapi) Spec
38/72
Sections 6 and 7 detail the more technical