Menu

Delivery: xAPI (Tin Can)

On this page

xAPI records what a learner does as statements in a learning record store (LRS). It needs an LRS: the LMS’s own, when the LMS launches xAPI packages (“Tin Can” launch), or one the client runs or rents, for a module outside an LMS. Elabora never picks xAPI by itself; a module forces it (course.json delivery.format xapi). For an LMS, cmi5 is xAPI with the rules an LMS needs, and SCORM is what every LMS reads.

Package

elabora build --format xapi writes <id>-<version>-xapi.zip, with tincan.xml at its root instead of imsmanifest.xml, and elabora/lms.js, which connects to the LRS before the player starts:

<tincan xmlns="http://projecttincan.com/tincan.xsd">
  <activities>
    <activity id="urn:elabora:course:<id>" type="http://adlnet.gov/expapi/activities/course">
      <name lang="fr">…</name><description lang="fr">…</description><launch lang="fr">index.html</launch>
    </activity>
  </activities>
</tincan>

The activity id is urn:elabora:course:<id>, or course.json delivery.activityId (an IRI the client owns, which some LRSs ask for).

Where the statements go

  • An LMS that launches xAPI packages gives endpoint, auth, actor, registration and activity_id in the address (the Tin Can launch): the statements go to its LRS, as that learner. Some LMSs (SCORM Cloud) give the actor in xAPI 0.95’s form, its fields as lists and its account as accountServiceHomePage and accountName: elabora/lms.js turns it into an xAPI 1.0.3 agent, which their LRS asks for.
  • Outside an LMS, course.json delivery.lrs.endpoint names the LRS (its xAPI address, https://…/xapi/), and the build takes its key from ELABORA_LRS_KEY and ELABORA_LRS_SECRET (or elabora build --lrs-key <key> --lrs-secret <secret>): never from course.json, which lands in the project’s history. The package then carries the key in elabora/lrs.js (W_XAPI_KEY_IN_PACKAGE): anyone who has the package can send statements with it. Use a key that can only write statements, for this module. The learner is anonymous: an account named at random and kept in the browser.
  • Neither: the player runs alone, as a SCORM package without its LMS.

Runtime behaviour

As in cmi5 (cmi5), without cmi5’s rules: initialized at the start; the place, the suspend data, the status and the score in a State API document (stateId elabora-progress, by registration when there is one); completed once complete, passed or failed with the score; answered for each answer; terminated when the session ends. xAPI 1.0.3, requests in order and never waited for.

Emulator (elabora test)

The emulator’s LRS (packages/node/src/emulator/lrs.ts) plays an LMS that launches Tin Can packages, with the checks of cmi5 that xAPI shares (the key of the launch, X-Experience-API-Version, statements with an actor, a verb and an object, an xAPI 1.0.3 agent), launches with an actor in xAPI 0.95’s form as SCORM Cloud does,, and the scenario of every format.

elabora test examples/diagnostic-reseau --format xapi --profile scorm-cloud

Beyond the emulator

  • An LRS is needed. Without one, nothing is recorded.
  • Financing in France. 360Learning leaves xAPI courses out of the OPCO reports it makes: deliver SCORM to a client whose training an OPCO finances (for cmi5, ask the LMS first: cmi5).
  • Reporting. An LMS that takes xAPI packages may show only completion and score; the statements are in its LRS, which few LMSs let clients read.
  • Keys in the package. A key for a module outside an LMS is in the package: rent or set up a key that only writes.
  • SCORM Cloud (6 Nov 2026, scripts/scorm-cloud-trial.ts): diagnostic-reseau imported as a Tin Can package, launched, closed abruptly, relaunched on the same screen, completed: COMPLETED, PASSED, score 100, no request refused. Its launch gives the actor in xAPI 0.95’s form, which its LRS then refuses (the package turns it into an xAPI 1.0.3 agent; the emulator now launches the same way).