xAPI Reference

Understanding Key Concepts

What is a DID?

A DID (Decentralized Identifier) is a unique identifier for your user that works across different systems. Think of it like an email address that works everywhere but is more secure and private.

Learn more about DIDs in LearnCard

Sending xAPI Statements

Here's how to send an xAPI statement to LearnCloud:

interface XAPIStatement {
    actor: {
        objectType: 'Agent';
        name: string;
        account: {
            homePage: string;
            name: string;
        };
    };
    verb: {
        id: string;
        display: {
            'en-US': string;
        };
    };
    object: {
        id: string;
        definition: {
            name: { 'en-US': string };
            description: { 'en-US': string };
            type: string;
        };
    };
}

async function sendXAPIStatement(
    statement: XAPIStatement,
    jwt: string,
    endpoint: string = 'https://cloud.learncard.com/xapi'
) {
    const response = await fetch(`${endpoint}/statements`, {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json',
            'X-Experience-API-Version': '1.0.3',
            'X-VP': jwt,
        },
        body: JSON.stringify(statement),
    });

    return response;
}

Example: Tracking Game Activities

Here are examples of tracking different activities in a skills-building game:

1. Tracking Activity Attempts

2. Tracking Skill Development

3. Tracking Achievements with Results

Common Gotchas and Tips

  1. DID Usage: Always use the same DID in both actor.name and actor.account.name. This DID should come from your authentication process.

  2. Verb Selection: Use standard xAPI verbs when possible. Common ones include:

    • attempted

    • completed

    • mastered

    • demonstrated

    • failed

    • progressed

  3. Activity IDs: Use consistent, unique URLs for your activity IDs. They don't need to be real URLs, but they should be unique identifiers following URL format.

  4. Authentication: The JWT token should be sent in the X-VP header. This is specific to LearnCloud's implementation.

  5. Error Handling: Always implement proper error handling:

Testing Your Implementation

Before sending real user data, test your implementation with sample statements. Verify that:

  1. The authentication works (200 status code)

  2. The statements are properly formatted

  3. The DIDs are correctly included in both required locations

  4. The verbs and activity types make sense for your use case

Reading xAPI Statements

After sending xAPI statements, you can retrieve them using the same endpoint:

Important Security Notes

  1. Users can only read statements about themselves

  2. The DID in the JWT (X-VP header) must match the actor's DID

  3. A 401 error means either:

    • Invalid authentication

    • Trying to read another user's statements

    • Expired or malformed JWT

Delegated Access

If you need to allow another party to read statements:

  1. Create a delegate credential:

  1. Use the delegate credential to create a presentation:

  1. Use this JWT in the X-VP header to read statements

Contract-Scoped xAPI Statements

When using delegate credentials through ConsentFlow, you can track which contract was used to make xAPI statements. This allows you to query all statements made through a specific contract.

How It Works

When a user consents to a contract, the LearnCard app generates a delegate credential and wraps it in a Verifiable Presentation (VP). To enable contract tracking, the contractUri is embedded in the VP before signing:

Contract URI Injection

When a statement is sent with a VP containing a contractUri, the LearnCloud xAPI service automatically injects it into the statement's context.extensions:

Querying Statements by Contract

To retrieve all statements made through a specific contract, query statements for the user and filter by the contract extension:

Use Cases

Contract-scoped xAPI statements enable:

  1. Game/App Analytics: Track all learning activities that occurred through a specific game or application's contract

  2. Program Reporting: Generate reports showing all xAPI statements for learners enrolled via a specific program contract

  3. Audit Trails: Maintain clear records of which third-party contract was responsible for each statement

  4. Multi-Contract Support: When a user has consented to multiple contracts, distinguish statements by source

Voiding Statements

To remove a statement (mark it as void):

Important: You can only void statements that you created.

Validation Tips

  1. Check Response Status:

    • 200: Success

    • 401: Authentication/permission error

    • Other: Server/request error

  2. Common Implementation Issues:

    • JWT not matching actor DID

    • Missing or malformed agent parameter

    • Incorrect content type header

    • Missing xAPI version header

  3. Testing Checklist:

    • Can read own statements

    • Cannot read others' statements

    • Delegate access works as expected

    • Can void own statements

    • Cannot void others' statements

Remember: The xAPI server maintains strict permissions - users can only read and modify their own statements unless explicitly delegated access by the statement owner.

Advanced xAPI Statement Queries

Filtering Large Statement Sets

When dealing with large statement volumes or statements with extensive data in extensions, you can use the following techniques to retrieve more manageable subsets of data.

Basic Query Parameters

The xAPI API supports several query parameters to limit and filter your results:

Key Filtering Parameters

Parameter
Description
Example

limit

Maximum number of statements to return

limit=20

since

ISO 8601 date to filter statements after

since=2024-03-01T00:00:00Z

until

ISO 8601 date to filter statements before

until=2024-03-31T23:59:59Z

verb

Filter by verb ID

verb=http://adlnet.gov/expapi/verbs/completed

activity

Filter by activity ID

activity=http://yourgame.com/activities/level-1

ascending

Return in ascending order (oldest first)

ascending=true

Using Pagination

For very large datasets, implement pagination:

Reducing Statement Size

If dealing with extremely large data in extensions:

  1. Reference Instead of Embed: Store large data elsewhere and include a reference URL in your statement:

  1. Summarize Data: Include only essential information in statements:

Specialized Queries

Activity-Specific Statements

To retrieve all statements about a specific activity regardless of verb:

Timeline Analysis

To analyze progress over time, sort statements in chronological order:

Skill-Based Filtering

To filter statements related to a specific skill or competency:

Completion Status

To find all completed activities:

Aggregation Queries

To retrieve summary data rather than individual statements:

Best Practices for Large Data Sets

  1. Use IDs Effectively: Query by specific activity IDs to get only statements related to particular challenges or learning objectives

  2. Time-Based Queries: Filter by recent time periods when monitoring current progress

  3. Aggregate First: If analyzing patterns, consider creating aggregated statements that summarize multiple detailed statements

  4. Batch Processing: For analysis, retrieve data in small batches and process incrementally

  5. Cache Common Queries: If your application frequently needs the same filtered view, consider caching the results

Last updated

Was this helpful?