Creating Custom xAPI Statements: A Step-by-Step Developer Guide

The Experience API (xAPI) is revolutionizing how learning is tracked, offering granular insights beyond the traditional SCORM model. While most Learning Record Providers (LRPs) send predefined statements, the real power of xAPI lies in creating custom xAPI statements that capture unique, meaningful learner actions.

In this guide, we’ll walk you through the anatomy, creation, and best practices of custom xAPI statements—so you can start tracking what truly matters in your eLearning experience.



๐Ÿ” What is a Custom xAPI Statement?

An xAPI statement is a JSON object that follows the format:
[Actor] [Verb] [Object], with optional context, result, and attachments.

A custom statement is one you define (instead of using preset ones from authoring tools) to track learning experiences like:

  • Clicking a specific button
  • Interacting with a simulation
  • Posting in a forum
  • Viewing a knowledge base article
  • Completing a real-world task

๐Ÿงฑ Anatomy of an xAPI Statement

Here’s a basic structure:

{
  "actor": {
    "name": "Jane Doe",
    "mbox": "mailto:jane@example.com"
  },
  "verb": {
    "id": "http://adlnet.gov/expapi/verbs/interacted",
    "display": {"en-US": "interacted"}
  },
  "object": {
    "id": "http://example.com/interactive-simulation",
    "definition": {
      "name": {"en-US": "Interactive Simulation"},
      "description": {"en-US": "A complex drag-and-drop chemistry lab simulation"}
    },
    "objectType": "Activity"
  },
  "timestamp": "2025-07-01T13:20:30Z"
}

๐Ÿง‘‍๐Ÿ’ป Step 1: Define the Actor

"actor": {
  "name": "John Smith",
  "mbox": "mailto:john@example.com"
}

Or use account-based identifiers:

"actor": {
  "account": {
    "homePage": "https://yourlms.com",
    "name": "user_12345"
  }
}

๐Ÿƒ Step 2: Choose or Define a Verb

Standard verbs from the xAPI Verb Registry include:

  • experienced
  • interacted
  • completed
  • answered
  • attempted

To define your own:

"verb": {
  "id": "https://xapiverse.com/verbs/flagged-content",
  "display": { "en-US": "flagged" }
}

๐ŸŽฏ Step 3: Define the Object

"object": {
  "id": "https://yourapp.com/lessons/simulation-chem-lab",
  "definition": {
    "name": { "en-US": "Chemistry Lab Simulation" },
    "description": {
      "en-US": "Drag and drop simulation for learning chemical reactions"
    }
  },
  "objectType": "Activity"
}

๐Ÿงช Step 4: Add Result (Optional but Powerful)

"result": {
  "score": {
    "raw": 85,
    "min": 0,
    "max": 100,
    "scaled": 0.85
  },
  "success": true,
  "completion": true,
  "response": "Selected H2 + O2",
  "duration": "PT5M10S"
}

๐ŸŒ Step 5: Add Context (Optional)

"context": {
  "contextActivities": {
    "parent": [{
      "id": "https://yourlms.com/course/chemical-reactions"
    }]
  },
  "platform": "xAPILMS",
  "language": "en-US"
}

๐Ÿงต Step 6: Add Timestamp

"timestamp": "2025-07-01T13:20:30Z"

๐Ÿš€ Step 7: Send the Statement to Your LRS

Sending a statement to LRS using sing fetch() in JavaScript:

fetch("https://yourlrs.com/xAPI/statements", {
  method: "POST",
  headers: {
    "Authorization": "Basic " + btoa("key:secret"),
    "Content-Type": "application/json"
  },
  body: JSON.stringify(yourStatementObject)
});

✅ Best Practices

  • Use consistent and unique IDs for verbs and objects
  • Avoid sending incomplete or duplicate statements
  • Validate your JSON using tools like xAPI Statement Validator
  • Secure your LRS endpoint with authentication
  • Store statement IDs or logs for audit and debugging

๐Ÿง  Real-World Example

Use Case: Track when a learner flags inappropriate content in a course.

{
  "actor": { "mbox": "mailto:dev@xapiverse.com" },
  "verb": {
    "id": "https://xapiverse.com/verbs/flagged-content",
    "display": { "en-US": "flagged" }
  },
  "object": {
    "id": "https://xapiverse.com/courses/module-3/slide-5",
    "definition": {
      "name": { "en-US": "Slide 5 - Discussion Thread" },
      "description": { "en-US": "User-flagged inappropriate comment" }
    },
    "objectType": "Activity"
  },
  "timestamp": "2025-07-01T13:21:45Z"
}

๐Ÿ“Œ Final Thoughts

Creating custom xAPI statements is a critical step toward truly personalized, data-rich learning analytics. It gives you power to track almost anything—from mouse clicks to offline tasks—in a standardized, machine-readable format.

Start small. Test. Validate. And soon, you’ll be building a learning ecosystem that’s as smart as the learners inside it.


Comments

Popular posts from this blog

What is xAPI? A Complete Guide for eLearning Developers

Choosing the Right LRS: A Technical Evaluation for Developers