Skip to content

Repository files navigation

xapi-doctor

tests license node tests runtime deps

Diagnose xAPI statements and LRS connectivity. Three subcommands. Zero runtime dependencies. Built because the most common xAPI failures — a malformed statement, a missing X-Experience-API-Version header, an LRS that 401s for reasons the dashboard doesn't explain — should be findable in seconds, not in an LRS log dive.

npm install -g github:parthdhanani/xapi-doctor   # installs from source (not yet on npm)

xapi-doctor lint  statement.json --profile cmi5
xapi-doctor ping  https://lrs.example.com/data/xAPI/ --auth user:pass
xapi-doctor send  statements.json https://lrs.example.com/data/xAPI/ --auth user:pass

Exit codes: 0 clean, 1 warnings only, 2 errors. Every command supports --json for CI pipelines.

Why this exists

cmi5 and xAPI are the spec stack most enterprise LMS RFPs ask for in 2026. The toolchain around them is thin:

  • The ADL conformance tester exists but is a complete-spec test rig, not a developer's tool.
  • LRS vendors offer "send a statement" debug UIs, but those don't tell you which field of your existing statement is wrong.
  • The first signal that something is broken is usually a 400 from the LRS with a body like {"message":"Invalid request"} and nothing else.

xapi-doctor is the small CLI for the moments when you have a statement file or an LRS endpoint and you need a fast, specific answer. It's the diagnostic counterpart to scorm-kit, which handles SCORM / cmi5 packaging.

Commands

xapi-doctor lint <file.json> [--profile cmi5]

Validates an xAPI statement (or an array of them) against the xAPI 1.0.3 spec. Catches:

  • Missing required fields (actor, verb, object)
  • Non-UUID statement ids and registrations
  • ISO-8601 timestamp and duration violations
  • IRI shape on verb.id, object.id, object.definition.type
  • Actor IFI rules: exactly one of mbox / mbox_sha1sum / openid / account
  • mailto: shape on actor.mbox; full account shape on actor.account
  • Score range: scaled in [-1, 1], raw between min and max
  • Context misuse: revision/platform on Agent objects, non-UUID registration
  • verb.display language map presence and en entry

With --profile cmi5, adds the cmi5-specific constraints:

  • cmi5 reserved verbs (Launched / Initialized / Completed / Passed / Failed / Abandoned / Waived / Terminated / Satisfied) require context.registration
  • Passed / Failed / Completed require the https://w3id.org/xapi/cmi5/context/categories/moveon category activity
  • actor.mbox without actor.account is flagged — cmi5 LMSs always launch with the account IFI, and an mbox-only statement will likely not match the LMS-assigned learner

xapi-doctor ping <lrs-url> [--auth user:pass]

Verifies that an LRS is reachable and behaving like a 1.0.3-compliant LRS:

  • DNS, TCP, TLS reachability of the base URL
  • GET /about returns a version array
  • 1.0.3 is among the advertised versions
  • Access-Control-Allow-Origin is present (browser-based clients fail silently without it)
  • With --auth, performs an authenticated GET /statements?limit=1 and reports 200 / 401 / 403 distinctly
  • LRS echoes X-Experience-API-Version per §6.2 of the spec

xapi-doctor send <file.json> <lrs-url> [--auth user:pass] [--profile cmi5]

Lints the statement(s) locally, then POSTs them to the LRS and reports the result. Refuses to POST a statement that would fail lint (use --no-validate to override). On non-2xx, decodes the most common LRS responses into human-readable explanations — 400 / 401 / 403 / 404 / 409 / 413 / 415 / 5xx.

The --profile cmi5 flag is forwarded to the lint pass.

Pairs with

  • scorm-kit — the SCORM / cmi5 build pipeline. scorm-kit cmi5 convert produces a cmi5 package; once it's launched and statements are flowing, xapi-doctor is what tells you whether the statements are well-formed and whether the LRS is healthy.

What xapi-doctor is not

  • A full LRS conformance suite. The ADL test rig exists for that.
  • A statement generator. It validates and forwards; it does not produce statements.
  • An LRS. For development you want a real one — Veracity, Yet, or Learning Locker — running locally in Docker.

Building from source

git clone https://github.com/parthdhanani/xapi-doctor
cd xapi-doctor
npm test

Zero runtime deps; npm install is not required to run.

Tests

17 tests in test/run.js. The HTTP tests spin up a mock LRS on a random local port and exercise ping / send against it.

npm test

License

MIT. See LICENSE.

Validation rules

26 xAPI 1.0.3 rules + 4 cmi5 profile rules (enabled with --profile cmi5). Each rule maps to a spec section.

xAPI 1.0.3 base rules

# ID Level What it checks Spec ref
1 stmt-actor-missing error statement.actor is required §2.3
2 stmt-verb-missing error statement.verb is required §2.3
3 stmt-object-missing error statement.object is required §2.3
4 stmt-id-not-uuid error statement.id must be a UUID (RFC 4122) §4.1.1
5 stmt-timestamp-bad error statement.timestamp must be ISO-8601 with timezone §4.1.2
6 stmt-stored-bad error statement.stored must be ISO-8601 with timezone §4.1.2
7 stmt-version-bad warning statement.version must look like 1.0.x §4.1.10
8 actor-objectType-bad error actor.objectType, if present, must be Agent or Group §2.4.1
9 actor-no-ifi error Actor needs exactly one IFI: mbox, mbox_sha1sum, openid, or account §2.4.1
10 actor-multiple-ifi error Actor has more than one IFI — exactly one required §2.4.1
11 actor-mbox-bad error actor.mbox must be mailto:user@host.tld §2.4.1
12 actor-account-bad error actor.account requires homePage (IRI) and name (string) §2.4.1
13 actor-openid-bad error actor.openid must be an IRI §2.4.1
14 verb-id-missing error verb.id is required §2.4.2
15 verb-id-not-iri error verb.id must be an IRI §2.4.2
16 verb-display-missing warning verb.display is a strongly-recommended language map §2.4.2
17 verb-display-lang warning verb.display should include an en entry §2.4.2
18 object-id-missing error object.id is required §2.4.4
19 object-id-not-iri error object.id must be an IRI §2.4.4
20 object-objectType-bad warning object.objectType, when set, should be Activity for SCORM-style statements §2.4.4
21 object-def-type-bad error object.definition.type must be an IRI when present §2.4.4
22 result-score-range error result.score.scaled in [-1.0, 1.0]; raw between min and max §2.4.5
23 result-duration-bad error result.duration must be ISO-8601 duration (e.g. PT4M33S) §2.4.5
24 ctx-registration-uuid error context.registration must be a UUID §2.4.6
25 ctx-revision-on-agent error context.revision is only valid when object is an Activity §2.4.6
26 ctx-platform-on-agent error context.platform is only valid when object is an Activity §2.4.6

cmi5 profile rules (--profile cmi5)

# ID Level What it checks Spec ref
27 cmi5-reserved-verb warning cmi5 reserved verbs (Launched / Initialized / Completed / Passed / Failed / Abandoned / Waived / Terminated / Satisfied) used outside the correct lifecycle position cmi5 §9.3
28 cmi5-no-registration error cmi5 statements must carry context.registration (the launch session) cmi5 §10.0
29 cmi5-cat-activity warning Passed / Failed / Completed must include the https://w3id.org/xapi/cmi5/context/categories/moveon category activity cmi5 §10.0
30 cmi5-no-account warning cmi5 LMSs always use actor.account (not mbox) — mbox-only actor may not match the LMS-assigned learner cmi5 §8.1.3

About

CLI tool for diagnosing, linting, and testing xAPI statements

Topics

Resources

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages