Experience API Tech Overview

What is xAPI?

The Experience API (xAPI) is a web service that allows for statements of experience (typically learning experiences, but they could be anything) to be delivered to and stored securely in a Learning Record Store.

The web service allows clients to read and write experiential data in the form of “statement” objects. In their simplest form, statements take the form of “I did this”, or more generally “actor verb object”. xAPI also provides facilities for more complex statement forms, a built in query API to help filter statement streams, and a state API that allows for a sort of “scratch space” for consuming applications.

Back to top ▲

Why should I care, as a developer?

It’s no exaggeration to say that there is a revolution underway in the e-learning industry. If you already consider yourself to be a part of that industry, it will only be a matter of time before you’ll need to familiarize yourself with xAPI. But, even on broader terms, xAPI is presenting an opportunity to create systems and components that comprehend a novel format for experiential data. The Experience API has also been built to support a distributed architecture, where statement streams can be propagated to many places, and driven by many sources. Hooking into streams of information already being produced by major learning based vendors and applications could offer some interesting mash ups and programming possibilities. Not to mention, the Experience API can offer real value in worlds completely disjointed from e-learning.

Back to top ▲

What is a statement? What does it look like?

Statements are the bread and butter of xAPI. They dictate the format for the specific moments in a stream of activity. They convey an experience which has occurred, or may be occurring, and typically have a good english translation, for instance, “Bob completed ‘Truck Driving Training Level 1’” or “Sally experienced ‘Solo Hang Gliding’”. Let’s convey the latter statement in terms of a xAPI statement object…

Simple xAPI statements take the general form of “[actor] [verb] [object]”. These labels coincide with the field names on a statement object. So, in conveying the information that “Sally experienced ‘Solo Hang Gliding’”, we can quickly spot “Sally” as the actor, “experienced” as the verb, and “Solo Hang Gliding” as the activity. Ignoring the structure of the specific parts, the statement object itself would take this structure in JSON format:

    "actor": "Sally",
    "verb": "experienced",
    "object": "Solo Hang Gliding"

This is at least simply useful, but simple strings can only take us so far. How do we know which Sally we mean? Which ‘Solo Hang Gliding’ activity was it, one that was part of military training, one from a commercial enterprise, or something self directed? Let’s expand these parts and show a valid xAPI statement:

    "actor": {
        "name": "Sally Glider",
        "mbox": "mailto:sally@example.com"
     "verb": {
         "id": "http://adlnet.gov/expapi/verbs/experienced",
         "display": {"en-US": "experienced"}
     "object": {
         "id": "http://example.com/activities/solo-hang-gliding",
         "definition": {
             "name": { "en-US": "Solo Hang Gliding" }

Mostly, we’ve added structure here to ensure we have a way to uniquely identify the component parts. This helps us correlate statements about the same person, activity, or verb. There’s also some structure added to provide information about our objects, like name (other descriptive fields are available, see the Experience API specification for details).

We can also add a lot more to a statement, in the form of statement context (“Sally completed ‘Solo Hang Gliding’ in the context of ‘Army Training Level 1’” or “Bob completed ‘Truck Driving Training Level 1’ on his Android phone, under the instruction of Dan”) or you can attach results to a statement (“Bob passed ‘Truck Driving Training’ with score 90%”). You can even declare custom fields on a statement, in the form of extensions. You can find a much more detailed explanation of statements in our Statements 101 page.

Back to top ▲

How do I make my own statement?

To make things a little easier for you (and to make experimentation a snap,) we’ve created a Statement Generator. Just fill in the fields with your desired actor, verb, object, etc. and the Statement Generator will create a statement for you. You can also use the generator to paste in statements that you’ve created on your own and validate them (or if you’re having problems with your statements, use the validator to find out what’s breaking them.)

We’ve also developed a xAPI bookmarklet. It’s a really quick and easy way to let you see some statement generation in action. It allows you to send a statement that you’ve “experienced” any webpage, just by visiting the page and clicking the bookmarklet. Install the bookmarklet, and you can be generating xAPI statements in just a few minutes.

For a much more in depth look at xAPI statements, check out our Statements 101 page. To start experimenting with sending statements, you’ll want to get your own LRS.

Back to top ▲

What else is there in the API?

You’ve seen how to send statements to the API, but you might be wondering how you can get them back out. To do so, issue a GET on /statements. The stream you’ll receive provides a number of parameters to filter the returned set of statements. This includes filtering on a statement’s actor, verb, and object, but also includes ways to filter based on parts of the statement context, or limit the results with time boundaries. This allows for built in capability to ask things like “Who has completed ‘Solo Hang Gliding’ since yesterday?” or “What’s all the activity happening in the context of ‘Ping Pong’ during last month?”. The full list of available parameters are listed in the Experience API spec.

In addition to the statements API, xAPI also specifies a set of document APIs, which allows applications to save arbitrary key / document pairs in the context of a particular actor, a particular activity, or some combination of actor and activity. Imagine documents like “Bob’s profile information for the Truck Driving Training program” or “Sally’s list of notes from ‘Solo Hang Gliding’” or “All comments for ‘Truck Driving Level 1’ course”. This allows for some applications, particularly those launched across different platforms and devices, to have an easy place to put some useful state. The Experience API also provides a few other calls that assist in the discovery of activity and actor information. See Documents for more details.

Back to top ▲

How do I report on this stuff?

In many ways, the power of the Experience API is realized by providing a loose structure that gives applications some flexibility in how they describe experience data. Reporting is an area of xAPI that, beyond the query API, is technically outside of the scope of the specification. But, it’s an important practical concern, which can partly be addressed with generic tools, and otherwise with custom built reporting.

Some obvious common ground among all statements is dictated by the standard, and some general reporting concepts can be driven by that, such as grouping statements by actor, verb, object, or contextual information. But, there are also a lot of possibilities around creating reports that are specific to the type of experiences you are reporting. To take our Ping Pong example, we could get some interesting facts from generic reports, such as how many matches have been played in total, how many have been played by specific players, and perhaps how many wins and losses happened for a particular player. But, a reporting layer specific to Ping Pong statements might want to feed these wins and losses into a system that can calculate a wide range of statistics and reports, like a board of rankings, Elo scores, and so on.

See Reporting for more details.

Back to top ▲

Is there a best practice for authentication with an LRS?

The LRS will support authentication using at least one of the following methods:

  • OAuth 1.0 (rfc5849), with signature methods of “HMAC-SHA1”, “RSA-SHA1”, and “PLAINTEXT”
  • HTTP Basic Authentication
  • Common Access Cards

Back to top ▲

Are there libraries for xAPI?

There sure are! We put together some xAPI Client Libraries to help you get started with xAPI. The libraries are open source so the hope is that the community remains active in helping maintain, fix and evolve the libraries along with us. You can find the xAPI Client Libraries here.
Back to top ▲

How can I get my hands dirty?

We’ve got a number of resources and tools that you can start digging into today, and we’re actively working on putting together more. You can find them all on our resources pages. Included there are a number of technical documents, including the core xAPI specification.

If you’re looking to get your hands on some code, you can check out some of the open source xAPI prototypes. You might want to see how we’ve implemented some xAPI functionality in a bigger context. For that, we’d recommend digging through the GolfExample_TCAPI project. Another good place to start is the xAPI Lab, which illustrates how to take some essential pieces of information and create a statement from them.

To see the basics of building an LRS, see the “Building a Learning Record Store” page.

See Get started for more details.

Back to top ▲

Please send us your thoughts and questions as you dig into xAPI. We’re happy to provide any answers we can, and we’d love to hear about your progress as you explore the use of xAPI in your own application. If you’d like to stay informed about the latest Experience API news, get email updates from us.