xapi-dotnet

Experience API (xAPI 2.0 / IEEE 9274.1.1, and 1.0.3) for .NET: models and validation, an async LRS client with a durable outbox, and a Learning Record Store you can embed in an ASP.NET Core app.

Status: 0.x. 0.2.0 is on NuGet and the LRS image is on ghcr.io. The API can change between minor versions until 1.0; the 1.0 milestone lists what is left.

This site is built from the main branch. The source, issues and the changelog are on GitHub.

Packages

Package What it is Targets
Xapi.Core Statement model, strict JSON reading and writing for 1.0.3 and 2.0.0, validation, statement comparison netstandard2.0, net10.0
Xapi.Client Async client for every LRS resource, version negotiation, attachments, statement signing netstandard2.0, net10.0
Xapi.Client.Outbox Durable outbox: retries, error classification, dead letters, idempotent resend netstandard2.0, net10.0
Xapi.Lrs AddXapiLrs / MapXapiLrs: an LRS inside your ASP.NET Core app net10.0
Xapi.Lrs.Sqlite SQLite storage and migrations for Xapi.Lrs net10.0
Xapi.Lrs.PostgreSql PostgreSQL storage and migrations for Xapi.Lrs net10.0

The API reference is generated from the XML documentation of the net10.0 builds.

Send a statement

With using Xapi; and using Xapi.Client;:

using var http = new HttpClient();
var client = new XapiClient(http, new XapiClientOptions
{
    Endpoint = new Uri("https://lrs.example.com/xapi/"),
    Credentials = XapiCredentials.Basic(key, secret),
});

var statement = new Statement(
    Agent.FromMbox("learner@example.com", "Ada Learner"),
    Verbs.Completed,
    new Activity(new Iri("https://example.com/courses/fire-safety")));

var id = await client.SaveStatementAsync(statement);
Console.WriteLine($"The LRS stored statement {id}");

The client asks the LRS which xAPI version to use, validates the statement for that version and sends it. The client guide covers the rest of the client, and the outbox guide keeps statements through network outages and restarts.

Host an LRS

In an ASP.NET Core app with the Xapi.Lrs.Sqlite package:

var builder = WebApplication.CreateBuilder(args);

builder.Services
    .AddXapiLrs(builder.Configuration.GetSection("Lrs"), options => options.MigrateOnStartup = true)
    .UseSqlite("Data Source=lrs.db");

var app = builder.Build();
app.MapXapiLrs("/xapi");
app.Run();

appsettings.json lists the credentials under Lrs, without their secrets:

{
  "Lrs": {
    "Credentials": [ { "Key": "my-app", "Scopes": [ "all" ] } ]
  }
}

The secret comes from user secrets or the environment (Lrs__Credentials__0__Secret). Clients then use https://<your app>/xapi/ as their endpoint, with the key my-app and that secret. The LRS guide covers scopes, delegated authentication, PostgreSQL, migrations and limits. The LRS passes the full ADL LRS Conformance Test Suite for both versions on both databases; see Conformance.

Guides

The design decisions are recorded as architecture decision records.

xAPI (Experience API) is a specification created by the Advanced Distributed Learning (ADL) Initiative and published as IEEE 9274.1.1-2023. This project is an independent implementation and is not affiliated with, endorsed by, or certified by ADL, the U.S. Department of Defense, IEEE, or Rustici Software. IEEE is a registered trademark of The Institute of Electrical and Electronics Engineers, Inc.