Shared foundation, different delivery
The short answer to cmi5 vs xAPI: they are not competitors, and the choice is not about tracking. Both send the same xAPI statements to the same learning record store. The difference is delivery. cmi5 is a package an LMS imports and launches, with a fixed handshake that hands the content its credentials and a rule for what counts as done. Plain xAPI has no package and no handshake — you launch the content however you like, and the content needs its own way to know where the LRS is and how to authenticate.
Put another way: xAPI is the language, cmi5 is an envelope with a delivery address. If you already know what a statement looks like, skip ahead. If not, What is xAPI covers the statement model and What is cmi5 covers the package in detail. This page is only about which of the two to build.
| Plain xAPI | cmi5 | |
|---|---|---|
| Package format | None | Zip with cmi5.xml at the root |
| LMS import | Not possible — there is nothing to import | Standard, like a SCORM zip |
| How it launches | Any URL you choose | LMS appends five parameters to the AU URL |
| LRS address and credentials | You supply them; usually configured or hard-coded | Handed over at launch, one-time fetch token |
| Who decides completion | Whatever reads the LRS | The LMS, against the manifest's moveOn rule |
| Shows in the LMS transcript | No | Yes |
What cmi5 adds
cmi5 adds four things on top of xAPI, and every one of them exists to let an LMS treat statement-based content the way it treats a SCORM package.
- A manifest.
cmi5.xmldeclares one or more assignable units — the launchable pieces — each with a title, a URL, and amoveOnvalue that says what satisfies it:Passed,Completed,CompletedAndPassed,CompletedOrPassed, orNotApplicable. An optionalmasteryScoresets the pass threshold as a scaled value between 0 and 1. - A launch handshake. The LMS appends five query parameters to the unit's URL:
endpoint(the LRS),fetch(a one-time URL that returns an auth token),actor(the learner as an xAPI agent),activityId, andregistration. The content POSTs the fetch URL once, gets a token, and uses it for the session. Nothing is hard-coded. - A state document. The unit GETs
LMS.LaunchDatafrom the LRS and finds themoveOnrule, the mastery score, and a context template carrying the registration — so the content can know the passing bar rather than guessing it. - A defined statement sequence. The unit MUST send
initializedandterminated, and MAY sendcompleted,passed, orfailedin between. The LMS watches those and writes its ownsatisfiedstatement when themoveOnrule is met.
What plain xAPI gives up and gains
Plain xAPI gives up the import, the handshake, and the rollup. There is no zip to hand anyone, no manifest for an LMS to read, and nothing that tells the platform your content exists. In exchange it gives up the constraints too. A statement can be sent from a mobile app, a simulator, a kiosk, a piece of lab equipment, or a script that runs nightly against a database. The verb can be anything you can express as an IRI. There is no fixed session shape, no required initialized, no registration unless you supply one.
That freedom has a cost that shows up later, not at launch: credentials. Something has to tell the content where the LRS is and how to authenticate to it. If that is a key baked into client-side JavaScript, anyone who opens the page has write access to your record store. The usual answers are a server-side proxy that holds the key, or an out-of-band launch mechanism that mints short-lived credentials — which is, in effect, rebuilding the cmi5 handshake by hand.
The second cost is that nothing rolls up. Statements land in the LRS and stay there. Whether a learner is "done" is a question your reporting layer answers, not the LMS. That is fine when the LRS is your reporting layer — see what a learning record store actually does — and a problem when compliance reporting lives in the LMS.
LMS-native completion
This is the fork that decides most projects. With cmi5, the LMS reads the statements, compares them to the manifest's moveOn rule, and marks the unit satisfied in its own records. The learner's transcript, the compliance report, the manager's dashboard — all of it works, because the LMS understands the outcome.
With plain xAPI, none of that happens. The statements are correct, the data is richer, and the LMS transcript is empty. If someone has to certify that 400 people completed a course, an empty transcript is not a technicality — it is the whole deliverable missing.
cmi5, LMS-visible outcome AU → initialized AU → completed AU → passed (result.score.scaled 0.88 ≥ masteryScore 0.80) AU → terminated LMS → satisfied ← the LMS wrote this; the transcript updates plain xAPI, no LMS-visible outcome app → completed app → passed (statements are in the LRS; the LMS was never involved)
The failure mode here looks exactly like the SCORM one described in why courses lose completions: the content ran, the learner finished, and the platform shows nothing. The cause is different — a missing statement contract rather than a missing Commit — but the support ticket is word for word the same.
Running outside an LMS
Plain xAPI wins wherever there is no LMS in the path, and that is a wider set of cases than it first appears: a mobile app that logs practice sessions offline and posts them when it reconnects; a simulator that records every attempt at a procedure; a coaching conversation logged by a human; usage of a real production tool, tracked as evidence of competence.
None of these can be a cmi5 package, because there is nothing to import and no browser session to launch. cmi5 assumes a learner clicks a link in a platform and a browser opens. Break that assumption and the handshake has nowhere to happen.
The practical middle ground is to do both, and it is common: ship the formal, assessed part of a programme as cmi5 so the LMS can report on it, and send everything else — the informal, the offline, the sensor data — as plain xAPI to the same LRS. Statements from both sources share the actor and can share a registration, so they join up in reporting even though only one of them appears on the transcript.
Choosing between them
Three questions settle it, in this order.
- Does the outcome need to appear in an LMS? If a transcript, a compliance report, or an enrolment has to update, you need cmi5. This overrides everything below.
- Does the experience happen in a browser, launched from a platform? If not — offline, embedded, sensor-driven, human-logged — cmi5 cannot carry it and plain xAPI is the only option.
- Does the destination platform actually implement cmi5? Support is far less universal than SCORM support. If the target is an older LMS, verify before you build; the fallback is usually SCORM 2004 rather than plain xAPI, because SCORM at least imports. SCORM vs cmi5 vs xAPI covers that three-way decision.
Note what is not on the list: data richness. Both carry identical statements, so "we need better analytics" is never a reason to choose one over the other. The only thing cmi5 constrains is the small set of statements that govern the session; anything else your content wants to send, it can send, and the LRS will store it.
Where SCORM Central fits
SCORM Central converts files you already have — PDF, PowerPoint, Word, or video — into SCORM 1.2, SCORM 2004, cmi5, or xAPI, and shows you the manifest, the full runtime log, and a conformance report on every build, so you can see exactly what a package will report before an LMS does. See how it works, or start with one file.