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 Tin Can questions:


Archive for the "Recipes" Category

Learning plans, goals and targets are important. Setting goals for learning allows us to evaluate whether or not we are learning the things that we set out to learn. It’s standard practice for e-learning courses and qualifications to have learning outcomes attached to them, and these are used to measure if our learning has been successful. They are also used by educators and trainers to evaluate whether or not their teaching and training have been effective, and are used to inform interventions, further learning requirements and amendments to learning materials and lesson plans.

Learning Goals with Tin Can

Brian Miller touched on the use of sub-statements in Tin Can to represent future plans. The spec puts it this way: “One interesting use of sub-statements is in creating statements of intention.” and gives the following example:

    "actor": {
        "objectType": "Agent",
    "verb" : {
        "display": {
    "object": {
        "objectType": "SubStatement",
        "actor" : {
            "objectType": "Agent",
        "verb" : {
            "display": {
                "en-US":"will visit"
        "object": {
            "definition": {
                "name" : {
                    "en-US":"Some Awesome Website"


No Comments

Statements come from all kinds of places: content created in authoring tools, mobile apps, learning platforms and business systems. It’s not always immediately obvious which application the statement came from, which might be useful to know. This blog explains how you can tag the statements your tool or product generates and why that information is useful.

We’ve worked hard to make the Tin Can (xAPI) spec as clear as possible and have required Learning Record Stores (LRSs) to validate incoming data to ensure the same data structure is always used. There’s no way for statements to be sent to a conformant LRS unless they follow the prescribed data structure, and you’ll find that the major LRSs are strict with the data they accept.

1 Comment

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 Tin Can 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 Tin Can 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 Tin Can. 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

Updating the Prototypes

Posted by

Categories: Best Practices, Ideas, Recipes, Statements, Tin Can

Posted 14 April 2015


The prototypes have been with us since the beginning. Recently I’ve given them an update from a tracking design perspective.

In the beginning, before Tin Can version 0.9 and before you or I had even heard of Tin Can, there were the prototypes. These example activities helped the world see the kinds of thing that might be possible with Tin Can, and provided a reference point for early adopters and developers to see how statements could be sent and retrieved. I used the Golf example as a reference when building a Tin Can wrapper for Captivate 5.0 swf files a couple of years ago.

Over the years, the prototypes have been updated to be conformant with the latest released version of Tin Can, now 1.0.x. They are now less important in illustrating what’s possible with Tin Can because there’s actual real life products doing exciting things in the real world. They’ve continued to be a good starting point for developers to see the mechanics of how Tin Can works.

The prototypes were never designed to be examples of good practice or to illustrate the best statement structure. They weren’t supposed to tell you exactly what data you should track or which verbs and activity types you should use. In fact, the prototypes were created at a time before we had good practice in Tin Can. Whilst we’ve updated them to be technically conformant with each version of the specification, we’ve not touched the actual data that was sent and events we were tracking.

Until now.

As I’ve been working with various Tin Can adopters, it’s become apparent that many are looking at the prototypes as a design template for what statements to send and the properties to include. Many adopters have looked beyond the prototypes to the various blogs and guides available online, but the prototypes are a significant influence on how people are designing their Tin Can statements.

I’m also dishing out plenty of advice on how to implement Tin Can well, but a lot of the times the prototypes weren’t following that advice. I figured it was time to apply that advice to the prototypes and the data they’re sending.

We have…

  • Updated the index page to make use of Context Registration and issue a ‘launched’ statement. This now serves as a closer example of how we’d expect an LMS to behave when launching content. Registration is now a required property in the config file.
  • Refreshed the verb, activity type and extension IRIs used throughout to include a wider range taken from the Registry (which didn’t exist when the prototypes were first born). Instead of reporting ‘Andrew experienced the Country Music Hall of Fame’ in the locator prototype, we now report ‘Andrew was at the Country Music Hall of Fame’. Much better.
  • Documented all the verbs, activity ids, activity types and extensions used and recorded this in a Registry profile.
  • Added ‘initialized’, ‘terminated’, ‘suspended’ and ‘resumed’ statements and made some other changes so that we do a better job of tracking session and attempt duration. Duration tracking is one of the most common Tin Can related questions we get. We included a couple of additions to TinCanJS’s utility functions to support this. (More on duration tracking in a blog sometime soon!)
  • Improved the way bookmarking data is saved in the Golf example to give an example of storing and amending a JSON object within the State. We included some new functionality in TinCanJS’s setState method to make this possible.
  • Improved the tracking data sent when switching players in the Tetris example.
  • Added a ‘Save & Exit’ button to the Golf example as an example of good practice to avoid losing data when learners close the window.
  • Added two types of “category” Context Activity to record the Recipe being used and the original source of the content (more on this in a blog soon!)

The statements generated by the new prototypes will not be compatible with the old ones, so if you’re using the prototypes for testing, you’ll need to keep this in mind. In fact, one of the reasons we’ve held off updating the prototypes is that we didn’t want to break anyone’s use of them. You’ll need to consider this issue of backwards compatibility as you come to update your own products.

The easiest solution is to get the design right the first time, but that’s not always possible as requirements and best practices develop over time. We work around this issue in the new prototypes by tagging every statement with a Recipe Id as a “category” Context Activity. The next time we update the prototypes, we’ll also update the Recipe and update the Id to point to the new version. Any tools reporting on the prototypes could use that property to see which version of the statement structure is being used and handle the data accordingly, though the reports included with the prototypes don’t yet do this.

There’s still more that could be done to improve the design of the prototypes and take full advantage of Tin Can. These are prototypes, not products, so I recommend you look to other sources (like this blog or my eLearning Guild course) for advice on how to best design your tracking. That said, the prototypes are now providing a better base line for you to build and improve on in your design and development.

Some examples of how the prototypes could be developed further are:

  • Launching activities in the same window as the launcher and returning there at the end of the activity; modifying the UI accordingly.
  • Passing language preference or other learner preferences from the launcher to the activity and displaying localized or personalized content.
  • More thought into the user experience of returning to an attempt within the Golf example, including saving progress within the assessment.
  • Allowing the user to review their quiz answers and the content after an attempt and tracking this using the verb.
  • Server side tracked versions of the prototypes, including statement signing for the Golf assessment.
  • Taking recipe version into account within the reports.
  • More interesting and visual reports and dashboards targeting different stakeholder groups.
  • Move varied use of media including Tin Can tracked video and audio within the Golf example.

We may get onto these in the future, but for now, please consider how you might apply them in your real-world products!

If you’re sending Tin Can statements and would like somebody to review and feedback on your tracking, we’re happy to help; please get in touch.


On Tuesday, March 31st, 2015, we hosted a webinar about nine practical use cases of the Tin Can API (xAPI). As usual, the attendees had more questions than we could answer during the live webinar, so we’ve posted the questions and Andrew Downes’ answers here.


Q: LRS is learning XXX system? quick definition please
Q: what does LRS stand for?
Q: how does an LRS differ from an LMS?

A: Learning Record Store. There’s a great explanation of what an LRS is and how it differs from an LMS here: ../learning-record-store

Q: I’m in the US…and I’m not familiar with the way Andrew is using “bespoke”.
Q: What does “bespoke API” mean?

A: From the Wikipedia definition of bespoke: “altered or tailored to the customs, tastes or usage of an individual”. Many products and systems have an API that’s specific to that individual system. If you want to integrate with that system, you need to tailor-make an integration with that system and you won’t be able to re-use that work with another system. The point of Tin Can is that you can do the integration work once and it will work with any Tin Can conformant system. MORE…

No Comments

Tin Can API Email Updates

* indicates required

Tin Can API Email Updates

Thanks for signing up for the Tin Can API newsletter!

Make sure to follow us on Twitter @ProjectTinCan,
and tweet this page to let others know about the Tin Can API.