Webinar Q&A Follow Up: Anatomy of a xAPI Statement


A little over a month ago I presented the “Anatomy of a xAPI Statement” webinar as follow up to our continuing Deep Dive series of blog posts. Despite some Q&A time at the end, I didn’t have a chance to answer all the questions, here is the Q&A for that webinar.

Q: Will you be sharing the slide deck?

Q: Will a recording of this webinar be available?

A: Slides are available on slideshare, recording is available at here.


Q: Why was JSON chosen for the xAPI?

A: Several reasons led to its adoption most of which build on the others. At its core JSON is essentially “executable” (technically “evaluatable”) in JavaScript which has led to it being the primary choice for AJAX (or remote requests) in browsers as JavaScript is the single choice for direct browser script execution. The support in browsers has then led to a need on the server side to have good, well established library support in lots of development languages. Because of the common use as a transfer format its minimalist nature was also an important consideration. Finally, it is fairly human readable, certainly relative to XML, but still provides the ability to arbitrarily nest data objects. (See slide #4)


Q: Can xAPI work with XML?

A: Early in adoption there were several parties working on XML support, but ultimately the specification only provides for JSON support. Since both are designed to represent arbitrary data objects the JSON structures could theoretically be translated into XML, but given JSON’s popularity and various popular APIs deciding to drop XML support it is unlikely to be supported by LRSs and so would really be a non-starter.

XML is used by the xAPI launch guidelines, specifically the tincan.xml, that provides a recommendation of how to launch xAPI courses from an LMS. More formal work on that topic is being undertaken by the CMI-5 working group and they may decide to adopt XML for that purpose.


Q: How do you create an actor? Is it just using a unique email address for the mbox?

A: An ‘actor’ is a property that contains an Agent or Group, an Agent can be identified in one of four ways with an ‘mbox’ associated to a unique email address as one of those ways. For much more on how to properly identify Agents and Groups have a look at the “Deep Dive: actor/Agent” post.


Q: As Groups are Agents, isn’t it inconsistent to prevent members from being groups?

A: Groups was a complex enough feature as it was, we (the spec group) cut it off to limit the complexity. It could be changed in a future version if the use cases are compelling. (To get involved with the specification group visit:


Q: How do you choose an Activity id?

A: “Carefully?” :-) This is a very common question, and hearing this question so often is what initially led to the existence of the “Deep Dive” blog post series. Rather than go into it all here, I’ll point to the “Deep Dive: Activity” blog post for all the details.


Q: Can other properties be added to Score? Standard values were scale, raw, min, max… could you include Complete or passed or failed?

A: Completion status and success status are defined in the Result object which contains the Score itself, so they should be captured as part of Result. Other information that might be needed as part of the Result can go in its “extensions” property.


Q: Is the ID used only one time per statement or will it ever be reused?  Where is the UUID generated?

Q: Is it always a GUID?

A: The ID will never be reused as the ID for a different statement. It’s either generated randomly by the creator of the statement, otherwise it’s randomly generated by the LRS. The generation algorithm provides reasonable certainty that there will be no collisions. The ID is used for creating Statement References which can be used in other statements as an object or piece of context.

A: Statement IDs are always a GUID. This is to allow statements to be globally identifiable.


Q: On one of the slides, the context was used to provide info about the presentation (parent) on which the slide (object) was viewed. Could that have been done the other way around (slide as child within context and object as parent)? If so, are there best practices for which should be used?

A: It’s possible to do that (there isn’t any way to stop this since there isn’t a defined content structure the LRS has access to validate the “parent” relationship), though it’s not a best practice to do that. The “parent” is intended to be a logical parent. There are other context properties that could be used for other relationships. If one wanted to make a statement about a presentation, but call out particular relevance of a given slide then the “other” property within context activities might be appropriate.


Q: Can the attachment be a URL to, say, a content management system function to retrieve a document?

Q: Can you discuss attachment URIs in a little more depth?  Is this typically a reference to a file on a server?

Q: Well.. whether it is actually an embedded file or a reference to a file.

There is a forthcoming Deep Dive post on attachments, but for now:

A: It could be using the ‘fileUrl’ property, but it would have to be stable as the hash of the document is included in the statement.

A: The content where the ‘fileUrl’ resolves must match the SHA2 hash as provided in the statement, the implementation behind that URL to produce the content is entirely up to the implementer. It could be a static file on a server, it could be in a database, it could be generated dynamically, proxied, etc.

A: Both options are supported by the attachment objects, in both cases a hash of the file must be included. A ‘fileUrl’ property or the file itself must be included otherwise the statement will have no way to reference the content, and both can be included.


Q: How are JSON statements organized when received by the LRS?

A: The mechanics of statement storage is left entirely up to the LRS implementer. Details will be largely dependent on the development platform, intended use case and performance requirements, database system (if used), etc. The key for LRS implementers is that they need to support the range of query options and return formats afforded by the statements query API.


Q: Are these statement hand/hard coded? Or will some automated system generate them based on the correct anatomy of statement?

A: Statements can certainly be hand coded, right down to the JSON itself, but I’d advise against it. At minimum a developer should use a JSON library appropriate for their language/platform, I’m not aware of any that don’t already have a reputable one (though one might exist). Where possible a library specifically implementing the xAPI specification should be leveraged, it will generally handle making sure data structures are created correctly, may provide validation, and will often smooth the differences between the versions of the specification. We have a list of libraries on the website. Additional languages will garner support over time, and Rustici Software is open to developing and maintaining libraries backed by clients for specific platforms.


Q: This may be a novice question, but if you are generating statements, will they be linked to the end of the course? Or how are they dispatched?

Q: I understand the properties of a statement but how would you connected it to an activity such as a 5 min video training on a Web site?

A: That’s the simplest case, but it’s really up to the Activity Provider, in other words the content which is sending the statements. They could be sent at the start or for each piece of content, i.e. slide or page; they could be sent for each question or interaction, or periodically on a timed basis. Some use cases may mean that multiple statements get sent for a single action of an experience, for instance the end of a game could generate three statements, one for the game completing and one indicating each of the winner and loser.


Q: Are there any scripts available to create a POC inhouse SQL LRS?

A: ADL has an open source LRS that will populate a Postgres database and may support others, though it is not considered production ready. If you just want to try out a hosted LRS you can sign up for a free trial account on SCORM Cloud and check out the LRS tab. It can be a pretty daunting task, have a look at just some of the headaches to overcome on “Building a Learning Record Store.”


Q: Does the registry expose machine readable data? An API?

A: The Registry does expose machine readable definitions for identifiers. It is architected such that the UI is completely supported through an API which is intended to be exposed. It has undergone some churn recently, but we are moving towards a stable API followed by documentation. No significant changes are foreseen at this point, using the site while running developer tools should provide significant information to implement against it until proper documentation materializes.


Q: Can you explain a little about the others apis (agentprofile, activityprofile etc)?

A: This is really beyond the scope of this post and outside the “Anatomy of a Statement” subject matter, but we do plan future Deep Dive posts on these subjects, stay tuned!


Q: Is there any work to integrate this with Open Badges (as in “Brian earned Padawan Hacker”)?

A: There is work going on to integrate with open badges, you may be interested in joining the Google Group set up by ADL.


Q: I don’t want to give up IMS LD, can I still use xAPI?

A: There are certain parts of the two technologies that will fit well together and IMS’ Caliper Learning Analytics Framework whitepaper mentions how xAPI might fit in with the direction they are heading. For more specific questions on the two technologies please contact us at

Was this article helpful?
0 out of 0 found this helpful
Have more questions? Submit a request
Powered by Zendesk