xAPI Statement Builder & Validator
Paste an xAPI (Tin Can) statement to check it against the 1.0.x / 2.0 spec — actors, IFIs, verbs, objects, results, context, and attachments — or compose a valid statement below. Everything runs in your browser.
Statement builder
Result (optional)
Context (optional)
{
"actor": {
"objectType": "Agent",
"mbox": "mailto:jane@example.com",
"name": "Jane Doe"
},
"verb": {
"id": "http://adlnet.gov/expapi/verbs/completed",
"display": {
"en-US": "completed"
}
},
"object": {
"objectType": "Activity",
"id": "https://lms.example.com/courses/intro",
"definition": {
"name": {
"en-US": "Introductory Course"
},
"type": "http://adlnet.gov/expapi/activities/course"
}
},
"result": {
"completion": true,
"success": true
},
"context": {
"language": "en-US"
},
"timestamp": "2026-10-25T15:39:24.064Z",
"id": "1c666cf5-99ca-49e1-b398-e722c5d9967e"
}What it checks: required actor/verb/object structure, inverse functional identifiers (mbox, mbox_sha1sum, openid, account), verb and activity IRIs against the ADL registry, score bounds (scaled −1…1, raw within min–max), ISO 8601 timestamps and durations, UUID formats, context rules, SubStatement restrictions, and attachment fields.
This is a structural check — acceptance still depends on your Learning Record Store. Some LRSs reject statements with unknown properties or non-registered verb IRIs; warnings flag those cases.
Frequently asked questions
What is an xAPI statement?
An xAPI (Experience API, aka Tin Can) statement is a JSON record in the form actor–verb–object: "Jane completed the safety course." Learning systems emit statements to a Learning Record Store (LRS), which can track far richer activity than SCORM — simulations, offline learning, videos, job performance.
Which properties are required?
Every statement needs actor, verb, and object. The actor must carry exactly one inverse functional identifier — an mbox (mailto: email), SHA-1 hash of it, an OpenID URI, or an account (name + homePage). IDs, timestamps, results, and context are optional but constrained: UUIDs, ISO 8601 timestamps, and bounded scores.
Can I use my own verb or activity IRIs?
Yes — the spec allows any IRI. Prefer the ADL verb registry (used in the builder's dropdown) so LRSs and analytics tools display a canonical label like "completed" instead of a raw URL. Custom IRIs must still be well-formed URIs, ideally on a domain you control.
What is a SubStatement?
A SubStatement describes something that happened within the object of a parent statement — e.g. "team reported that Jane completed the course." It has the same actor–verb–object shape but cannot contain its own id, timestamp, stored, authority, or version, and it cannot be nested inside another SubStatement. The validator enforces both rules.
Does a valid statement get accepted by every LRS?
Structural validity is necessary but not sufficient. LRSs apply their own profiles — cmi5 and the SCORM-to-xAPI profile add required fields and vocabularies on top of the core spec. Validate here first, then test against your target LRS's statement endpoint.
Is my data sent anywhere?
No. Parsing, validation, and statement generation run entirely in your browser — nothing is uploaded, logged, or stored.
