Contact Us Support Forum Get Email Updates

Thanks! Someone will be in touch with you shortly.

Rather just email us? Email us here.
Rather speak with someone in person?
Call any time with Experience API questions:


Archive for the "Registry" Category

Semantic Interoperability

Posted by

Categories: Best Practices, Ideas, Recipes, Registry, Standards, xAPI

Posted 24 January 2017




You’re going to hear us talk a lot about semantic interoperability this year. So we might as well present a working definition.

Semantic interoperability is when information—the meaning behind captured data—is 
portable and well understood by any subsequent system requesting and reviewing it.


Why will we be talking about it a lot? Because without semantic interoperability, the Experience API (xAPI) has a limited future.

For us, semantic interoperability in xAPI will be achieved when there is a generally accepted information model. We expect profiles to help with this a great deal. There’s a strong possibility that collaborative work between ADL and IMS could help a great deal.

Then: Too Many Constraints

Consider SCORM, the usage of which remains widespread in LMSs everywhere. The CMI data model leveraged by SCORM is closely linked to its information model. There is a finite set of data that can be recorded about the types of learning experiences common to online training, and summarizing information from that data is a relatively straightforward exercise. So straightforward, in fact, that practitioners have long cared primarily about a big four—score, completion, satisfaction (i.e., pass/fail), and duration. SCORM makes requesting and understanding the big four easy.

Now: Too Much Flexibility

xAPI, on the other hand, is fundamentally a communication protocol applied as a specification for elearning. In xAPI, apart from a few familiar holdovers from SCORM (the big four, native support for interactions), there is no limit to what can be captured about a given learning experience. One could literally choose any verb available in any language. Or one could create a new activity definition to describe any type of experience.

Can you imagine how difficult it would be to report on data with so few constraints? We can. Because we’ve been trying.

Needed: Leadership

Even when there is consensus that a concept has sufficient value to merit a profile, there can be difficulty. Take video, for instance. Not only is there a profile in our Registry, there’s also a Community of Practice still working on a version. If there are multiple working versions of what data to capture, then how is a reporting system attempting to derive meaning about “video” supposed to do so?

We think the answer right now is: leadership. The concept of Registry has utility to semantic interoperability in xAPI, and we have a feature roadmap for it. Still, we recognize the difficulty in a single industry participant to establish credibility and trust.

What would alternatives look like? We think ADL could assert an information model. As a subtle alternative, ADL could host a collaborative process with some authority. This might look like the establishment of a baseline with a community process similar to how the specification itself operates now—managed workflow in GitHub supported by regular calls.

Expect to hear more from us on this topic because we think it’s critical to the future success of xAPI.

No Comments

I’m super excited about the latest recipe we’ve published on the registry! Not only is it a great recipe tackling an important use case, but it was written by adopters who needed it for a real project. It was written incredibly rapidly, going from first draft to ready-to-try in less than two weeks. This blog gives you the details.

Sometimes when I talk to people about recipes, they’re disappointed to hear that there isn’t yet a recipe for the use case they are interested in. “Don’t worry!” I always console them, “You can write your own.” TES took that advice to heart and one of the first things they did after hiring a developer to take xAPI further in their app was to draft up a recipe covering the events they wanted to track. In this case, attendance at events such as meetings, classroom sessions, conferences, etc.

The actual recipe can be found here in the registry. The recipe is split into ‘Simple Attendance’ which uses a single statement to record that a group attended the event, and ‘Detailed Attendance’ which is used to record more events such as scheduling, registering, joining and leaving. It’s envisaged that some recipe adopters will implement only Simple Attendance whilst others will compliment it with the nuances captured by Detailed Attendance statements.

The bulk of the recipe was written by Sean Donaghy of TES. I helped by reviewing each iteration and making a couple of edits where it was faster to make the change directly than write up an explanation. I’m very happy to help anybody who wants help with reviewing a recipe they’re working on.

This first release of the recipe is considered an alpha version. Aside from the TES developers who are busily implementing the recipe in their product, nobody else has tried the recipe yet. There are likely some changes to come as implementers run into challenges we couldn’t predict. If you do implement the recipe, we really appreciate your comments and feedback. You’ll use the recipe ids ( and as a “category” Context Activity so that when you upgrade to the final release version of the recipe you can easily identify which statements used which version.

Recipes are really important to ensure your statements can be understood by other tools. If you’re working on a xAPI project and neither following nor writing a recipe, please do get in touch so I can help you.

You can expect this to be the Year of The Recipe for xAPI. We already had the Open Badges recipe last month and there’s a few more in the works that will pop up as the year progresses. Watch this blog for more news sometime soon!

No Comments

Sharing Documents successfully

So far in this Deep Dive series on the Document API I’ve introduced you to the Document APIs in general and then looked in detail at each Document API in turn. In this final post of the series, we’ll explore two important complexities of the Document APIs that you need to pay particular attention to when multiple Activity Providers or users might be accessing the same Documents.

Sharing keys

As I mentioned in my State and Activity Profile API blog, there is no specific structure or naming convention for Document IDs in any of the Document APIs, but I recommend using IRIs to avoid conflict where two Activity Providers use the same key. This is especially important for the Agent Profile API where it’s more likely for Activity Providers to be accessing the same data. There’s also risk of two Activity Providers storing the same data in different places and missing an opportunity to share (e.g. DOB and dateOfBirth) or using different formats (“27/09/83” vs. “09/27/1983”) and conflicting with one another.

In order to avoid two Activity Providers storing the same data under different structures or using different formats, Communities of Practice will need to define their own Agent Profile Documents IDs and outline the structure and format of Documents they contain. Megan Bowe has done an excellent job of explaining the process of defining a profile within your own community of practice.

Once you’ve defined what data you’re going to store and how you’re going to store it, you should describe it in a Recipe in the Registry. A standard and unique Document ID should be used for each Agent Profile Document. This ensures that Activity Providers using the same Document ID follow the same structure. The Registry doesn’t currently have an area explicitly for registering Document API keys, but you can include them in Recipe descriptions. As Recipes are identified using Activity ids, some Recipes might even encourage APs to store some Documents in the State or Activity Profile APIs at the Recipe Activity id as a mechanism for sharing data between APs implementing that Recipe.

The scope of a community of practice that shares an Agent Profile might vary. A core recipe containing data such as gender might be shared by every Activity Provider implementing xAPI. Other Recipes will be shared by a number of organizations with a shared interest. The draft CMI5 specification, for example, defines a learner preferences document including language and audio preference. Some Recipes may even be specific to a vendor or internal within an organization.

Many Activity Providers using the Agent Profile API will choose to implement multiple Recipes for Agent Profile data. An app and website for parachuting clubs, for example, will make use of gender data from a universal core Recipe, but could follow a parachuting specific Recipe for metrics such as number of jumps, parachute type preference, etc.

ETags and Concurrency

Another risk with multiple Activity Providers or Agents accessing the same Documents is that they could access the Documents at the same time and accidentally overwrite one another’s data. Imagine the following series of events relating to a Document that stores high scores for a mobile learning game:

  • The app on player one’s phone downloads the High Scores Document and inserts his score.
  • Meanwhile, player two completes a game and her phone downloads the High Scores Document and inserts her score
  • Player one’s phone stores the updated High Scores Document with his score.
  • Player two’s phone stores the High Scores Document unaware of the changes made by player one’s phone. His score is lost.

Tin Can makes use of ETags to prevent this happening. Every time a Document is updated, the LRS creates a new ETag for that Document, which it sends to the Activity Provider when they retrieve or store the Document. They then send the ETag back to the LRS when they make changes, telling the LRS which version of the Document they’re trying to modify. The LRS will reject any attempt to store a Document that doesn’t come with the latest ETag. ETags are simply a SHA1 hash of the document and are commonly used in applications across the internet; they’re not unique to xAPI.

In the example above, when player two’s phone tried to store the updated High Scores Document, this would not actually overwrite player one’s score. Instead, the LRS would return an error to player two’s phone to let it know that the Document had changed. The app would then request the latest version of the Document from the LRS and get the latest ETag. It could then choose to try and merge its changes into the latest Document, drop its changes and keep the latest Document or overwrite the latest Document with its own version. You’ll need to choose which option works best in your application.

ETags are required for the Agent Profile and Activity Profile, but Activity Providers can choose whether or not to use them for the State API. I recommend using them anyway to avoid problems. The Tetris Prototype includes an example of using ETags with TinCanJS for the Activity Profile API.

You’ve seen in this post that sharing Documents between Activity Providers requires some effort to get right, but if done properly you should have no problems.

Now that you’ve reached the end of this blog series, you’re ready to start storing and retrieving Documents. All of our code libraries support interacting with the Document APIs. As always, please let us know if you have questions!

Go now, store Documents!

No Comments

For storing (and sharing) state!

Last time we dived into the Document APIs as a whole. This time we dive deeper into the most well known and commonly used of the Document APIs, the State API. As there’s a lot of similarity between the State API and Activity Profile API (and I don’t have a whole blog worth of content on the State API alone) we’ll cover the Activity Profile API too.

The State and Activity Profile APIs provide a place for Activity Providers that have no storage of their own to store Documents. These APIs are no substitute for an Activity Provider’s own storage, and if you can use your own data store instead, you should. They are useful for small tools for which their own database would be overkill, for converted legacy SCORM content (which would previously have stored data with the LMS), and for new SCORM style content. They can also be useful for communication between a Training Delivery System such as an LMS and the Activity Provider.

The State API

Within the State API Documents can be stored on two different levels. First, data can be stored on a per user, per activity basis. Common uses include high scores or bookmarking data. Next, data can be on a per registration, per user, per activity basis. This is used for data specific to a particular launch or attempt. The Activity Provider is responsible for cleaning up after itself and deleting old state documents which are no longer required.

The Activity Profile API

The Activity Profile API is used to store activity wide documents that aren’t specific to an individual learner. This is used in any scenario where interaction between learners is required, for example collaboration activities, social interaction or competition.

Also included in the Activity Profile API is access to the LRS canonical definition of a given Activity. This is retrieved via a Full Activity Object GET request. The Activity Definition can be built up based on the definitions of the Activity given in Statements sent to the Statement API, can be provided in metadata hosted at the location specified by the Activity ID’s IRI or can come from another source used by the LRS. This is a read-only resource and can’t directly be written to by an AP.

It’s recommended that where possible you host a copy of the Activity definition as a JSON document at the Activity Id IRI.  This allows the owner of that IRI to assert their canonical definition of the activity and protects against others issuing statements with a conflicting definition. You can host Activity definition metadata yourself, or register your Activity ids within a Profile on the Registry. The LRS will return the canonical definition of the activity within Statements returned via the Statement API when the requested format is ‘canonical’.

The Tetris Prototype uses the Activity Profile API to store a table of high scores shared across all players.

Getting State and Activity Profile Documents

Every Document in the Document APIs has a unique ID, so you can store multiple Documents in each bucket of data. For the State API, this ID is stored in the “stateId” property; for the Activity Profile (and Agent Profile – more on this next blog) the property is “profileId”. This Document ID can be any string, but I recommend using an IRI to avoid conflict with another Activity Provider using the same ID. This is less important when using the State and Activity Profile APIs and targeting an Activity ID you control, but still good practice.

I like to use IRIs for my State IDs to make absolutely sure of avoiding a conflict, but there’s no requirement to do so and the data is already segregated by Activity ID. The spec simply requires the State ID to be a string.

When accessing the State API, the Activity Provider requests a Document matching an Activity ID, Agent object, State ID and, optionally, registration UUID. When accessing the Activity Profile API, Documents are matched only by Activity ID and Profile ID; only the State API can be segregated by registration.

You’ve now covered the State and Activity Profile APIs! Next time we dive into the Agent Profile API!

Go now, store Documents!

No Comments

The Sauce Behind Recipes

Posted by

Categories: Best Practices, Deep Dive, Recipes, Registry

Posted 17 June 2014


Last week we introduced the concept of a Recipe, a defined way to capture the same experience using the same set of statements across Activity Providers. This post will delve a bit further into how we got to the concept and the technical specifics about implementing them.

The “missing” data model

As thought leaders in a rapidly progressing community, we’ve tasked ourselves with trying to figure out what the next thing is that the community will want, or more importantly need, to effectively work with the Experience API. As the specification approached a 1.0 release, it became apparent that switching the identifiers for Verbs and other Statement parts to URIs was going to leave a gap. Out of that recognition came the Registry. The Registry provides a place for users of the Experience API to catalog the various terms they use to construct Statements.

A year later we realized another gap existed—the Experience API provides a ton of flexibility, but even the early adopters (innovators in their own right) were having issues implementing effective solutions with so much flexibility. They had too much proverbial rope with which to hang themselves.

1 Comment