If your LMS still relies on SCORM 1.2 or SCORM 2004 for content delivery, you’re operating against a specification last substantively revised in 2004. That matters now because modern learning architectures, mobile-offline delivery, xAPI data lakes, and multi-system credential exchanges, are actively blocked or degraded by SCORM’s browser-centric, synchronous communication model. cmi5 (published as the ADL/AICC cmi5 specification, version 1.0, released June 2016, with maintenance updates through 2023) resolves these structural gaps. It is not a replacement for xAPI; it is a profile built on top of xAPI 1.0.3 that defines the contract between an LMS and an Assignable Unit (AU), the content object in cmi5 terminology.
This guide focuses on what actually changes operationally when you switch: the launch protocol, the statement vocabulary, the data ownership model, and the failure modes you will encounter during implementation.
cmi5 Architecture: What Actually Changed
The Launch Mechanism
SCORM communication relies on a JavaScript API injected into the browser window (API_1484_11 for SCORM 2004, API for SCORM 1.2). This requires the content to run in the same browsing context as the LMS, a design constraint that makes offline mobile delivery, native app wrappers, and cross-domain launches either impossible or deeply fragile.
cmi5 replaces this with an HTTP-based launch URL. The LMS appends parameters to the AU’s launch URL; the AU then communicates exclusively via the xAPI endpoint. There is no shared window state required. The AU can be a mobile app, a WebGL application hosted on a CDN, or a server-side rendered experience, it only needs to reach the LRS.
cmi5 Launch URL Parameters (required):
https://au.example.com/course?
endpoint=https://lrs.example.com/xapi/ (xAPI endpoint)
fetch=https://lms.example.com/token/abc (one-time token URL)
actor={“objectType”:”Agent”,”account”:{
“homePage”:”https://lms.example.com”,
“name”:”user-12345″}}
registration=<UUID>
activityId=https://lms.example.com/activities/course-001
The Fetch URL and Auth Token Exchange
The fetch URL is a one-time-use endpoint. The AU makes a single POST to retrieve an auth token. This eliminates the need to embed LRS credentials in launch parameters, a common security failure in xAPI implementations that predate cmi5. The token is scoped to the registration, not the user account.
Fetch URL response structure:
{
“auth-token”: “Basic dXNlcjpwYXNz”,
“x-experience-api-version”: “1.0.3”
}
cmi5-Defined xAPI Statements
cmi5 mandates a specific set of xAPI verbs for session lifecycle. These are not optional, an LMS must reject or flag AUs that do not send the defined statements in the correct sequence. The defined verbs and their IRI prefixes are from the ADL vocabulary registry:
| Verb | IRI (ADL Vocabulary) | Required Sequence |
|---|---|---|
| initialized | https://adlnet.gov/expapi/verbs/initialized | First statement in session |
| completed | https://adlnet.gov/expapi/verbs/completed | When completion threshold met |
| passed | https://adlnet.gov/expapi/verbs/passed | When score ≥ masteryScore |
| failed | https://adlnet.gov/expapi/verbs/failed | When score < masteryScore |
| terminated | https://adlnet.gov/expapi/verbs/terminated | Last statement in session |
| abandoned | https://adlnet.gov/expapi/verbs/abandoned | LMS-initiated, session timeout |
| waived | https://adlnet.gov/expapi/verbs/waived | LMS-initiated, prior credit |
Critically, only one of passed or failed may appear per session and completed and passed/failed are independent. An AU can be completed without being passed. The LMS uses moveOn criteria (defined in the course package’s cmi5.xml) to determine when the AU is satisfied, this is a departure from SCORM where completion and success were often conflated.
The cmi5.xml Course Structure
cmi5 packages use a cmi5.xml manifest (not the SCORM imsmanifest.xml) to declare AU metadata, launch URLs, and learning objectives. The schema is defined by ADL at https://github.com/AICC/CMI-5_Spec_Current.
<courseStructure xmlns=”https://w3id.org/xapi/profiles/cmi5″>
<course id=”https://lms.example.com/courses/001″>
<title><langstring lang=”en-US”>Advanced Compliance Training</langstring></title>
<au id=”https://lms.example.com/activities/module-1″
moveOn=”CompletedAndPassed”
masteryScore=”0.8″
launchMethod=”AnyWindow”
url=”https://content.example.com/module1/index.html”>
<title><langstring lang=”en-US”>Module 1: Regulations</langstring></title>
</au>
</course>
</courseStructure>
Standards & LMS Compatibility Matrix
The following table summarises the capability differences between eLearning standards relevant to LMS selection and migration decisions. Capability status reflects the specification design, not vendor-specific implementations.
| Capability | SCORM 1.2 | SCORM 2004 4th Ed. | AICC (HACP) | xAPI 1.0.3 | cmi5 1.0 |
|---|---|---|---|---|---|
| Offline / mobile delivery | ✗ | ✗ | ✗ | ✓ | ✓ |
| Cross-domain launch | ✗ | ✗ | Partial | ✓ | ✓ |
| LRS-native data storage | ✗ | ✗ | ✗ | ✓ | ✓ |
| Standardised completion logic | ✓ | ✓ | ✓ | ✗ | ✓ |
| Separate completion vs. pass | ✗ | ✓ | Partial | ✓ | ✓ |
| Defined session lifecycle verbs | ✗ | ✗ | ✗ | ✗ | ✓ |
| Credential scoping per session | ✗ | ✗ | ✗ | ✗ | ✓ |
| Native app / non-browser AU | ✗ | ✗ | ✗ | ✓ | ✓ |
| LMS-side moveOn logic | ✗ | Partial | ✗ | ✗ | ✓ |
| Multi-block course structure | ✗ | ✓ | ✗ | ✗ | ✓ |
✓ = Supported by spec | ✗ = Not supported | Partial = Limited/non-standard implementation
Major LMS cmi5 Support Status (2026)
| LMS Platform | cmi5 Support | Internal LRS | Notes |
|---|---|---|---|
| Moodle 4.x | ✓ Native | Plugin required | cmi5 player plugin; LRS via Logstore xAPI |
| Docebo | ✓ Native | ✓ Built-in | cmi5 GA from Docebo 8.x |
| Cornerstone OnDemand | Partial | External only | Requires AUv2 module; incomplete verb support |
| SAP Litmos | ✓ Native | ✗ | Requires external LRS (e.g., SCORM Cloud) |
| TalentLMS | Partial | ✗ | xAPI pass-through; not full cmi5 |
| SCORM Cloud | ✓ Native | ✓ Built-in | Reference implementation; use for testing |
| SimpliTrain | ✓ Native | ✓ Built-in | cmi5 1.0 + xAPI 1.0.3 natively supported |
| Absorb LMS | ✓ Native | ✓ Built-in | Full cmi5 since 2023 |
Implementation Steps for cmi5 in a Production LMS
Step 1: Verify LRS Endpoint Configuration
Before importing any cmi5 package, confirm your LRS endpoint supports xAPI 1.0.3. Send a GET to /xapi/about and verify the response includes “version”: [“1.0.3”]. Mixed-version LRS deployments (common in upgraded Moodle environments) will silently downgrade statement handling.
Step 2: Import the cmi5 Package
A cmi5 package is a ZIP containing the cmi5.xml at the root level, alongside any embedded content assets. The LMS must parse cmi5.xml to extract AU definitions, moveOn criteria, and masteryScore values. If your LMS does not expose a cmi5-specific import type (distinct from SCORM), the package will likely fail silently or be treated as a ZIP without content structure.
Step 3: Configure Registration and Launch
Each learner-course pairing generates a registration UUID. This UUID is sent in the launch URL and must be included in every xAPI statement’s context.registration field. Statements missing this field are technically valid xAPI but will cause the LMS to fail to associate them with the correct enrolment, a common source of ‘missing completion’ tickets.
Step 4: Validate Session Lifecycle
After your first test launch, query your LRS for statements with the registration UUID and verify the sequence:
- initialized, first statement, no prior statements for session
- Content interaction statements (optional, AU-defined verbs)
- completed and/or passed/failed, as defined by AU logic and masteryScore
- terminated, final statement; no further statements permitted after this
Use SCORM Cloud’s cmi5 conformance tester (available at cloud.scorm.com) to validate AU behaviour before production deployment. It tests against the full ADL conformance test suite and flags sequencing violations.
Step 5: Configure moveOn Logic
The moveOn attribute in cmi5.xml controls when the LMS marks the AU as satisfied. Valid values per spec:
- Passed, satisfied when passed statement received
- Completed, satisfied when completed statement received
- CompletedAndPassed, both required (default recommended for compliance contexts)
- CompletedOrPassed, either sufficient
- NotApplicable, AU is always satisfied (use for reference content)
TIP, From the Field: Registration vs. Attempt Scoping
In SCORM, each SCORM attempt is scoped by the SCO’s session, and the LMS manages attempt history at the database level.
In cmi5, a new registration UUID should be generated for each attempt if your organisation requires attempt-level granularity. Many LMS platforms reuse the same registration UUID across retakes, which merges statement history in the LRS and breaks attempt-level reporting.
If your LRS (or your downstream analytics platform) needs to distinguish Attempt 1 from Attempt 2, enforce new registration generation in your LMS configuration or custom launch integration, do not rely on the default retake behaviour.
Reference: ADL cmi5 spec §9.3 (Registration) and §10 (Attempt).
Common Issues and Fixes
Issue 1: AU Launches But No Statements Appear in LRS
Root cause: The fetch URL POST is failing (CORS, network policy, or one-time token already consumed). The AU cannot obtain an auth token and silently fails to send statements.
Fix: Open browser DevTools and inspect the POST to the fetch URL. A 401 usually means the token was already consumed (double-launch scenario). A CORS error means your LMS is not returning Access-Control-Allow-Origin on the fetch endpoint. Verify your LMS’s CORS policy explicitly covers the AU’s origin domain, not just *.
Issue 2: Completion Recorded in LRS But Not in LMS Enrolment
Root cause: The xAPI statement’s context.registration UUID does not match the UUID the LMS generated for this enrolment. This happens when content is launched in test/preview mode (which may omit the registration parameter) or when the AU generates its own registration UUID.
Fix: The LMS,not the AU,owns the registration UUID. Ensure the AU reads registration from the launch URL and does not generate its own. Audit launch URL construction in your LMS integration code.
Issue 3: ‘terminated’ Statement Not Sent on Browser Close
Root cause: The AU relies on window.onunload or beforeunload to send the terminated statement, which modern browsers throttle or block for cross-origin XHR during unload. The session is then marked as abandoned by the LMS after its timeout threshold.
Fix: Use the navigator.sendBeacon() API for the terminated statement. Beacon requests are not blocked during page unload. Alternatively, configure your LMS’s abandonAbandonedSessionAfter timeout to a short window (300–600 seconds) so orphaned sessions resolve quickly.
Issue 4: masteryScore Mismatch Between AU and LMS
Root cause: The masteryScore in cmi5.xml (range: 0–1) overrides any score threshold configured in the LMS UI, but some LMS platforms allow administrators to set a separate passing threshold that conflicts with the spec value.
Fix: Per cmi5 spec §9.4, the masteryScore in the course structure file is authoritative. Disable or sync the LMS-side threshold. If you need per-learner thresholds, use LMS enrolment properties that write to the cmi5.xml at package import, not a separate UI field.
Issue 5: ‘passed’ Sent Before ‘completed’ , LMS Rejects Session
Root cause: cmi5 spec §9.3 does not mandate ordering between completed and passed, but several LMS implementations enforce a strict order. Some reject sessions where passed arrives before completed.
Fix: Standardise your AU authoring pipeline to send completed before passed. This is not a spec requirement but is a defensive practice. Reference: cmi5 spec §9.3.4 and SCORM Cloud forum thread on conformance test case AU-0034.
Issue 6: cmi5.xml Imported as SCORM Package
Root cause: The LMS’s import routine defaults to SCORM detection and treats any ZIP with an XML manifest as SCORM. If cmi5.xml is renamed or if the import dialog does not offer a cmi5 content type, the package fails validation or is imported without AU structure.
Fix: Always use the dedicated cmi5 import path in your LMS. Do not rename cmi5.xml. If your LMS lacks a cmi5 import type, verify whether a plugin or version upgrade is required, this is a hard prerequisite, not a configuration option.
FAQ
Q1. Can a cmi5 AU send arbitrary xAPI statements beyond the defined verb set?
Yes. cmi5 only mandates the lifecycle verbs (initialized, completed, passed, failed, terminated, abandoned, waived). AUs are free to send additional xAPI statements using custom or other ADL verbs within the session. These statements must include context.registration and valid actor/object fields. The LMS ignores them for moveOn evaluation, but they are stored in the LRS and available for analytics. This is the mechanism for granular interaction-level tracking that xAPI enables and SCORM cannot replicate.
Q2. Does cmi5 require a separate LRS, or can the LMS serve as the LRS?
cmi5 requires an xAPI-conformant LRS endpoint,it does not mandate that the LRS be external. Many enterprise LMS platforms include an embedded LRS (Docebo, Absorb, SimpliTrain). The practical question is whether that embedded LRS supports cross-system statement federation. If you need to aggregate statements from multiple LMSes, a content provider network, or mobile apps into a single reporting layer, an external LRS (Learning Locker, SCORM Cloud LRS, Watershed) is required regardless of what your LMS offers internall
Q3. Is cmi5 backward-compatible with existing SCORM 1.2 or SCORM 2004 content?
No. SCORM content communicates via the JavaScript API; cmi5 content communicates via xAPI HTTP calls. An LMS that supports cmi5 must also maintain its SCORM runtime if you have existing SCORM packages, they are not interchangeable. Migration requires either repackaging content with a cmi5-conformant authoring tool (Articulate Storyline 360 supports cmi5 export as of version 3.68; Adobe Captivate from 2022 release onward; Lectora from version 21) or wrapping SCORM content in a cmi5 AU shell that bridges the JavaScript API to xAPI,a technique that works but adds a maintenance layer.