xAPI for Tracking Classroom Attendance and Activities

Featured image with a sage green pastel background and a zigzag pattern, showing the post title "xAPI for Tracking Classroom Attendance and Activities"

xAPI for Tracking Classroom Attendance and Activities

xAPI is a standard for recording learning events as short statements, and it works for classroom attendance and in-class activities as well as online learning. Each statement says who did what to which activity, and a Learning Record Store (LRS) keeps them. This guide maps a classroom session to xAPI and gives three sample statements that follow the spec.

The explainers we reviewed for this topic stop at a generic “learner passed a quiz” example or skip classroom events entirely. A training provider running instructor-led sessions needs something more specific: who registered, who was present, what they did in the room, and identifiers that stay the same across every system.

Key takeaways

  • A statement needs an actor, a verb and an object. Everything else, such as duration, instructor and registration, is optional but is what makes attendance data useful.
  • Reuse verbs from an existing vocabulary. ADL’s list covers registered, attended, answered, exited and completed; it has no verb for absence.
  • Give the course and each session separate activity IRIs, one registration UUID per enrolment, and an opaque account name for each learner.
  • Keep your training system as the system of record and treat the LRS as an event store, not a scheduler.

What is xAPI, and does it work for classroom training?

Yes. xAPI is a specification from ADL, published as IEEE 9274.1.1-2023, that defines a JSON format for learning records and a web API for storing them in an LRS. Nothing in it requires content to be online, so a classroom, workshop or virtual class can send statements too.

The IEEE standard refines the xAPI 1.0.3 specification, and ADL also calls it xAPI 2.0. The structures in this guide follow the published 1.0.3 data specification, so confirm any detail against the version your LRS implements.

The practical difference from SCORM is where data comes from. SCORM reports on content that an LMS launches. An xAPI statement can come from any system that can send a web request, such as a check-in app, a kiosk, a trainer’s tablet or your scheduling platform.

What does an xAPI statement need to record a classroom event?

A statement must contain an actor, a verb and an object. For a classroom event, the actor is the learner or trainer, the verb is what they did, and the object is the session or in-class activity. Optional result, context and timestamp properties carry the details that make attendance data worth keeping.

The table below translates each part into classroom terms and notes the rule the spec sets for it.

Statement part In a classroom Rule in the 1.0.3 spec
actor The learner or the trainer Identified by exactly one of mbox, mbox_sha1sum, openid or account
verb What happened, such as attended The id is an IRI; a display label is recommended
object The session, or an activity inside it An Activity needs a unique id; objectType defaults to Activity
result Time present, completion, a poll answer All properties optional
context Registration, instructor, parent course All properties optional
timestamp When the event happened Must not be in the future; the LRS sets the separate stored time

Which xAPI verbs fit attendance and classroom activities?

Use verbs that already exist in a community vocabulary instead of inventing your own. The spec defines only one verb, voided, and leaves the rest to communities. ADL’s published list includes registered, attended, answered, exited and completed, which together cover most classroom events.

The table maps a typical session to those verbs. Every verb IRI begins with http://adlnet.gov/expapi/verbs/, followed by the verb name. The mapping is our own working design, built from the spec and ADL’s verb list, not an official profile.

Classroom event Verb Object Details to include
Learner enrolled on a session registered The session context.registration, parent course
Learner present attended The session result.duration, context.instructor, check-in method
Learner leaves early exited The session timestamp of departure
Live poll or quiz answer answered The question result.response and result.success
Course requirements met completed The course result.completion
Absent or late None verified Not applicable Derive it, or define your own verb

How do you record absence, lateness and early departure?

We found no absence or lateness verb in the ADL verb list we checked. Treat absence as a missing attended statement, checked against the registered roster. Record lateness as an extension value on the attended statement, and early departure as an exited statement, once you have agreed one rule for each.

Deriving absence from the roster is simple and avoids storing a negative event about a named person. If you do need an explicit record, define your own verb IRI on a domain you control and publish its meaning, as the spec lets communities do. Search the shared registries first.

How should you model a session so xAPI data stays usable?

Give the course and each session separate activity IRIs and link them with the parent context activity. Use one registration UUID per learner’s enrolment on a session, and identify people with an opaque account name. Every statement for one seat then joins up without email addresses sitting in the LRS.

  • Course IRI: stable across all deliveries, for example a URL on a domain you control.
  • Session IRI: unique per delivery, so a cohort on 14 October has a different id from the one on 21 October. The spec says an Activity id must be unique.
  • Registration: a UUID created when the enrolment is created. The spec says a registration can be an attempt, a session or span several activities, so tying it to the enrolment is a design choice, not a rule.
  • Actor: an account object with your system’s home page and an opaque name. The spec says a provider concerned about revealing personal data should use an opaque account name, such as an account number.

Pro tip: Store the registration UUID in your enrolment table. When the LRS and your training system disagree about who attended, the UUID on the enrolment row tells you which statements belong to which seat. You can then reconcile one record at a time instead of matching on names.

What do xAPI statements for a classroom session look like?

Three statements cover a typical classroom journey: registration, attendance and a live poll answer. Each uses an ADL verb, absolute IRIs for activities and one shared registration UUID. The example.com addresses and extension IRIs are placeholders that you replace with ones from a domain you control.

Statement 1: registration. The learner is enrolled on the morning session of a course. The session carries a custom activity type, since we did not find an ADL type for a classroom session, and the course is its parent.

{
  "id": "ff8a617c-f586-4e58-8b5e-4d710ebeb97b",
  "actor": {
    "objectType": "Agent",
    "name": "Learner 48213",
    "account": { "homePage": "https://learn.example.com", "name": "u-48213" }
  },
  "verb": {
    "id": "http://adlnet.gov/expapi/verbs/registered",
    "display": { "en-US": "registered" }
  },
  "object": {
    "objectType": "Activity",
    "id": "https://example.com/sessions/wse-2026-10-14-am",
    "definition": {
      "name": { "en-US": "Workplace Safety Essentials, 14 Oct 2026, morning cohort" },
      "type": "https://example.com/xapi/activity-types/classroom-session"
    }
  },
  "context": {
    "registration": "4be44c79-f113-42f1-b1b3-958acf5a93e5",
    "contextActivities": {
      "parent": [
        {
          "id": "https://example.com/courses/workplace-safety-essentials",
          "definition": {
            "name": { "en-US": "Workplace Safety Essentials" },
            "type": "http://adlnet.gov/expapi/activities/course"
          }
        }
      ]
    }
  },
  "timestamp": "2026-09-29T09:12:00Z"
}

Statement 2: attendance. Sent when the trainer signs off the roster. The timestamp is the sign-off time, the duration is time present, and the check-in method sits in an extension. ADL’s own example for this verb also sets completion to true, so your attendance rule should define what that flag means.

{
  "id": "c428f3bb-5522-4a16-8e52-7275f07460f9",
  "actor": {
    "objectType": "Agent",
    "name": "Learner 48213",
    "account": { "homePage": "https://learn.example.com", "name": "u-48213" }
  },
  "verb": {
    "id": "http://adlnet.gov/expapi/verbs/attended",
    "display": { "en-US": "attended" }
  },
  "object": {
    "objectType": "Activity",
    "id": "https://example.com/sessions/wse-2026-10-14-am"
  },
  "result": { "completion": true, "duration": "PT7H15M" },
  "context": {
    "registration": "4be44c79-f113-42f1-b1b3-958acf5a93e5",
    "instructor": {
      "objectType": "Agent",
      "account": { "homePage": "https://learn.example.com", "name": "i-0207" }
    },
    "contextActivities": {
      "parent": [ { "id": "https://example.com/courses/workplace-safety-essentials" } ]
    },
    "extensions": {
      "https://example.com/xapi/extensions/check-in-method": "qr-scan",
      "https://example.com/xapi/extensions/delivery-mode": "in-person"
    }
  },
  "timestamp": "2026-10-14T16:45:00Z"
}

Statement 3: a live poll answer. The question is an interaction activity. The spec says interaction activities must declare an interaction type, and that choice interactions list their options with distinct ids. The response holds the id the learner picked.

{
  "id": "aed7ba02-5a7f-4358-9bee-244ff0cca84f",
  "actor": {
    "objectType": "Agent",
    "name": "Learner 48213",
    "account": { "homePage": "https://learn.example.com", "name": "u-48213" }
  },
  "verb": {
    "id": "http://adlnet.gov/expapi/verbs/answered",
    "display": { "en-US": "answered" }
  },
  "object": {
    "objectType": "Activity",
    "id": "https://example.com/sessions/wse-2026-10-14-am/poll/3",
    "definition": {
      "name": { "en-US": "Live poll 3: first action at a spill" },
      "type": "http://adlnet.gov/expapi/activities/cmi.interaction",
      "interactionType": "choice",
      "correctResponsesPattern": ["b"],
      "choices": [
        { "id": "a", "description": { "en-US": "Clean it up quickly" } },
        { "id": "b", "description": { "en-US": "Mark the area and report it" } },
        { "id": "c", "description": { "en-US": "Ignore it" } }
      ]
    }
  },
  "result": { "response": "b", "success": true },
  "context": {
    "registration": "4be44c79-f113-42f1-b1b3-958acf5a93e5",
    "contextActivities": {
      "parent": [ { "id": "https://example.com/sessions/wse-2026-10-14-am" } ]
    }
  },
  "timestamp": "2026-10-14T11:20:00Z"
}

We checked the three statements against the required properties, IRI, UUID, timestamp and interaction rules in the 1.0.3 text, but we did not run them through an LRS. Send them to a test LRS before you rely on them.

What does the LRS do, and what stays in your training system?

The LRS receives, stores and returns statements. It does not schedule sessions, assign trainers or take payment. Keep your training management system as the system of record for enrolment and attendance, and use xAPI as an event feed that other tools can query.

Job Training system (TMS or LMS) LRS
Enrolment and capacity Owns it Receives a registered statement
Attendance record Owns the official mark Stores a copy as an attended statement
Payment and invoicing Owns it Not involved
Event history and analysis Sends statements Stores and serves them
Validation of statements Builds them correctly Rejects non-conformant ones

ADL’s paper on choosing an LRS says xAPI is dependent on an LRS to function. It lists conformance testing, security and personal data handling, hosting location, and how easily data can be pushed to or pulled from the LRS as points to check. It also notes that, when it was written, conformance tests checked the LRS and not the statements providers send, so test your own output.

Platforms differ in what they send. SimpliTrain’s homepage says customers can bring content in through SCORM or xAPI and that it integrates with any SCORM or xAPI-compliant system. It does not describe exporting attendance as statements, so ask any vendor to show you the statements its platform actually emits. Mundrisoft’s post on why enterprises move to custom LMS platforms lists connecting an LMS to learning analytics tools as a common gap.

How do you send xAPI statements without duplicates or errors?

Generate a statement id on the sending side and reuse it on every retry. The spec says an LRS must not change its state when it receives a statement id it already holds, so a repeated send is harmless. Correct mistakes by voiding the statement, because statements cannot be edited or deleted.

  • Retries: the spec says providers should include the id, and that an LRS answers a duplicate with 409 Conflict or 204 No Content without modifying anything.
  • Wrong marks: a voiding statement uses the voided verb and a StatementRef object pointing at the original id. Then send a corrected statement under a new id.
  • Verb drift: one app sends “present” and another sends “attended” for the same thing. The spec bars one verb IRI from carrying several meanings, so agree a single IRI per meaning across every tool.
  • Personal data: ADL’s LRS paper flags personal data and hosting location as security points. Have privacy counsel review what you store, especially for events about named people.

Pro tip: Fix device clocks before check-in kiosks. The timestamp must record when the event happened, and the spec forbids future times. Stamp each check-in on the device when it happens, queue it if the connection drops, and sync every kiosk and tablet clock first. The LRS sets its own stored time, so delays stay visible.

What should you do next?

List the events you want to track in one classroom session, then map each to a row in the verb table above. Pick a domain you control for activity types and extensions, and write down the one verb IRI you will use for each meaning before any tool sends data.

Then stand up a test LRS, send the three sample statements with your own identifiers, and see how your reports read them. Ask each platform vendor to show real statements for registration and attendance.

If you run training for clients and are comparing platforms, SimpliTrain’s page for professional training companies describes its multi-tenant client management, branded client portals and e-commerce storefront.

Frequently asked questions

Is xAPI the same as SCORM?

No. SCORM reports on content that an LMS launches, while xAPI statements can come from any system that sends them to an LRS, including check-in apps and scheduling tools. xAPI also has a broader data model, with actors, verbs and objects, so it can describe events that never involve a launched course.

Can xAPI track classroom attendance?

Yes, if a system sends the statements. The spec has no attendance feature of its own, but ADL’s verb list includes attended, and the spec’s own example statement uses it. Your TMS, a check-in app or a trainer’s tablet has to produce the statement and send it to an LRS.

Is xAPI an IEEE standard?

Yes. It was published as IEEE 9274.1.1-2023, titled as a JSON data model and RESTful web service for learner experience data tracking and access. IEEE describes it as refining the xAPI 1.0.3 specification, and ADL also refers to the IEEE version as xAPI 2.0.

Do I need an LRS to use xAPI?

Yes. ADL’s guidance on choosing an LRS states that xAPI is dependent on an LRS to function, because statements are sent to it for storage and retrieval. Some learning platforms include one, and others connect to a separate product, so check which applies to your stack.

How do I record a virtual classroom session in xAPI?

The statements look the same, because the verb and object describe the experience, not the room. What changes is the data source: your virtual classroom’s join and leave records, or your TMS’s attendance record, must be turned into statements. A delivery-mode extension can mark the session as virtual.

How do I show who taught the session?

Use the context instructor property. The spec defines it as the instructor a statement relates to, when that person is not already the actor. Identify the trainer with an account object, as with learners, and include the property on attended statements so reports can group attendance by trainer.