Chapitre 6.2 — Anatomie d’un statement
⏱️ TL;DR — La brique de xAPI, c’est le statement : une phrase, en JSON, qui décrit une expérience. Sa colonne vertébrale tient en trois champs obligatoires —
actor(qui),verb(quoi),object(sur quoi) — la traduction directe de « Je – ai terminé – le module ». Autour de ce noyau viennent des champs optionnels qui enrichissent :result(le score, la réussite, la durée),context(ce qui relie et situe l’expérience),timestamp(quand ça s’est passé),authority(qui l’atteste), plus des champs posés par le LRS (id,stored). Ce chapitre lit un statement complet de FormaCampus, champ par champ. Retiens la phrase :actor–verb–object, et tout le reste est du contexte.
🎯 Objectifs
- Réciter la structure minimale d’un statement :
actor–verb–object, et rien d’autre n’est obligatoire. - Lire un statement JSON complet et savoir ce que fait chaque champ.
- Distinguer ce que tu poses (acteur, verbe, objet, result, context) de ce que le LRS pose (
id,stored, souventauthority). - Survoler le rôle de
result,context,timestamp,authority(détaillés aux chapitres 6.3 et 6.4).
La phrase : acteur, verbe, objet
xAPI part d’une intuition linguistique : toute expérience d’apprentissage se dit comme une phrase simple — sujet, verbe, complément.
- « Je » → l’acteur (
actor) : qui a vécu l’expérience. - « ai terminé » → le verbe (
verb) : quoi, l’action. - « le module Sécurité » → l’objet (
object) : sur quoi porte l’action.
Ces trois champs — actor, verb, object — sont les seuls obligatoires d’un statement. Un statement minimal valide, c’est littéralement une phrase de trois mots :
{
"actor": { "mbox": "mailto:lea.martin@formacampus.fr" },
"verb": {
"id": "http://adlnet.gov/expapi/verbs/completed",
"display": { "fr-FR": "a terminé" }
},
"object": {
"id": "https://formacampus.fr/xapi/activities/atelier-soudure"
}
}Trois champs, et c’est un statement recevable par un LRS. Tout le reste — score, durée, contexte, horodatage — est optionnel : on l’ajoute quand on a quelque chose à dire de plus.
💡 Réflexe — Avant d’écrire un statement, formule-le à voix haute en français : « Qui – fait quoi – sur quoi ». Si la phrase ne tient pas debout (« l’atelier a terminé Léa » ?), c’est que tu as inversé acteur et objet. La grammaire de xAPI suit la grammaire naturelle : c’est voulu, et ça évite la moitié des erreurs.
Un statement complet, commenté
Voici un statement réel de FormaCampus, cette fois enrichi. Léa a terminé l’atelier de soudure, avec un score, une durée, et un contexte qui le rattache à sa formation. Lis-le de haut en bas ; on détaillera chaque bloc plus loin.
{
"id": "8f2a1c30-6b4e-4d2a-9f11-3c7e5a9b0d21", // UUID du statement — souvent posé par le LRS
"actor": { // QUI — l'acteur (chap. 6.3)
"objectType": "Agent",
"name": "Léa Martin",
"mbox": "mailto:lea.martin@formacampus.fr" // identifiant : l'e-mail en mailto
},
"verb": { // QUOI — le verbe (chap. 6.3)
"id": "http://adlnet.gov/expapi/verbs/completed", // IRI unique, vocabulaire ADL réutilisé
"display": { "fr-FR": "a terminé", "en-US": "completed" } // libellé lisible, multilingue
},
"object": { // SUR QUOI — ici une Activity (chap. 6.3)
"objectType": "Activity",
"id": "https://formacampus.fr/xapi/activities/atelier-soudure", // identifiant IRI de l'activité
"definition": {
"name": { "fr-FR": "Atelier soudure d'angle" },
"description": { "fr-FR": "Atelier pratique de soudure à l'arc en présentiel" },
"type": "http://adlnet.gov/expapi/activities/course" // type issu du vocabulaire ADL
}
},
"result": { // OPTIONNEL — le résultat (chap. 6.4)
"score": { "scaled": 0.92, "raw": 46, "min": 0, "max": 50 }, // scaled : ratio -1..1
"success": true, // a réussi
"completion": true, // a terminé
"duration": "PT1H15M" // durée ISO 8601 : 1 h 15 min
},
"context": { // OPTIONNEL — le contexte (chap. 6.4)
"registration": "3d6d3e0c-1f2b-4b8a-8c1a-9e2f7a6b5c4d", // UUID de la tentative
"instructor": { // le formateur qui atteste
"objectType": "Agent",
"name": "Karim Benali",
"mbox": "mailto:karim.benali@formacampus.fr"
},
"contextActivities": {
"parent": [
{ "id": "https://formacampus.fr/xapi/activities/cpjs-soudure-2026" }
] // l'activité parente : le parcours
}
},
"timestamp": "2026-03-14T10:45:00+01:00", // OPTIONNEL — quand l'expérience a eu lieu
"stored": "2026-03-14T10:45:03+01:00", // posé par le LRS — quand il l'a enregistré
"authority": { // OPTIONNEL — qui atteste (souvent posé par le LRS)
"objectType": "Agent",
"account": {
"homePage": "https://lrs.formacampus.fr",
"name": "app-atelier-mobile"
}
}
}Deux versions du même fait : la phrase de trois mots plus haut, et cette version riche. Les deux sont valides. La différence, c’est combien on en dit. Un tableau de bord sérieux voudra le result et le context ; un simple « a vu la vidéo » se contente du noyau.
⚠️ Piège — Confondre les champs que tu poses et ceux que le LRS pose.
idetstored(et souventauthority) sont typiquement remplis par le LRS à la réception. Si tu génères toi-même l’id(un UUID), c’est possible et parfois utile (voir lePUTau chapitre 6.5), mais ne fabrique jamaisstored: c’est l’horodatage d’enregistrement, la propriété du LRS. Ne confonds pas non plustimestamp(quand l’expérience a eu lieu) etstored(quand le LRS l’a reçue) : ils diffèrent, surtout en mobile hors-ligne synchronisé plus tard.
Le tour des champs optionnels (survol)
On les détaille aux chapitres suivants, mais voici la carte pour ne pas se perdre :
| Champ | Rôle | Détaillé au |
|---|---|---|
result | Le résultat mesurable : score (scaled/raw/min/max), success, completion, duration, response. | Chapitre 6.4 |
context | Ce qui situe et relie : registration, instructor, contextActivities (parent/grouping/category), extensions. | Chapitre 6.4 |
timestamp | Quand l’expérience a eu lieu (ISO 8601). À distinguer de stored. | Ce chapitre |
authority | Qui atteste de la véracité du statement (souvent le système émetteur, posé par le LRS). | Ce chapitre |
id, stored | Posés par le LRS : identifiant unique et horodatage d’enregistrement. | Chapitre 6.5 |
Deux points de vigilance sur le noyau lui-même :
objectTypeest optionnel quand il n’y a pas d’ambiguïté : unactoravec unmboxest unAgentpar défaut ; unobjectavec unedefinitionest uneActivitypar défaut. On l’écrit quand même pour la clarté, et il devient obligatoire dès que l’objet n’est pas une activité (unAgent, unStatementRef… — chapitre 6.3).displaydu verbe est purement décoratif : c’est l’id(l’IRI) qui identifie le verbe, pas le libellé humain. Deux statements avec le mêmeverb.idparlent du même verbe, même si l’un affiche « a terminé » et l’autre « completed ».
📚 La spec — La structure du statement (champs obligatoires
actor/verb/object, champs optionnelsresult/context/timestamp/authority, propriétés posées par le LRS commeid/stored) est définie par xAPI (ADL,adlnet.gov; norme IEEE 9274.1.1 pour la 2.0). Les valeurs detyped’activité (commehttp://adlnet.gov/expapi/activities/course) proviennent de vocabulaires publiés suradlnet.gov: on les réutilise, on ne les invente pas.
🧭 Sur FormaCampus — Premier vrai statement en production. L’appli tablette du formateur, à la fin de l’atelier, construit exactement le JSON ci-dessus et l’envoie au LRS de FormaCampus. Le noyau (
actor/verb/object) dit l’essentiel — « Léa a terminé l’atelier soudure » ; leresultprouve la réussite (score 46/50) ; lecontextrattache l’atelier au parcours de l’apprentie et nomme le formateur qui atteste. La même appli, hors-ligne dans un atelier sans wifi, met le statement en file d’attente :timestampfige le moment réel (10 h 45), etstoredsera posé par le LRS au moment de la synchronisation, plus tard. La distinctiontimestampvsstoredn’est pas académique : c’est ce qui garde l’historique juste.
✏️ Exercices
Exercice 1 — Le statement minimal. Écris le plus petit statement valide décrivant : « l’apprenant sami@formacampus.fr a expérimenté la vidéo d’introduction https://formacampus.fr/xapi/activities/intro-video ». Utilise le verbe ADL experienced.
✅ Solution
Trois champs suffisent — actor, verb, object — le reste est optionnel :
{
"actor": { "mbox": "mailto:sami@formacampus.fr" },
"verb": {
"id": "http://adlnet.gov/expapi/verbs/experienced",
"display": { "fr-FR": "a expérimenté" }
},
"object": {
"id": "https://formacampus.fr/xapi/activities/intro-video"
}
}On réutilise le verbe ADL http://adlnet.gov/expapi/verbs/experienced (on n’invente pas). L’mbox seul identifie l’acteur (objectType Agent implicite). Pas de result, pas de context : rien de plus à dire ici.
Exercice 2 — Qui a posé quoi ? Dans le statement complet plus haut, classe ces champs selon qu’ils sont normalement posés par l’application émettrice ou par le LRS : verb, stored, result, id, context, authority.
✅ Solution
Posés par l’application émettrice : verb, result, context (c’est toi qui décris l’expérience). Posés par le LRS : stored (horodatage d’enregistrement, toujours au LRS), et souvent id et authority (le LRS génère l’identifiant si tu ne l’as pas fourni, et renseigne l’autorité d’après l’identité authentifiée). Nuance : tu peux fournir id toi-même (utile pour un PUT idempotent, chapitre 6.5), mais jamais stored.
Exercice 3 — timestamp vs stored. Une apprentie termine un exercice mobile à 8 h 30 dans le métro (hors-ligne). L’appli synchronise au bureau à 9 h 05. Quelles valeurs attends-tu dans timestamp et stored ? Pourquoi la distinction compte-t-elle ?
✅ Solution
timestamp = 8 h 30 (le moment où l’expérience a réellement eu lieu, figé par l’appli avant la mise en file d’attente). stored = 9 h 05 (le moment où le LRS a reçu et enregistré le statement). La distinction est cruciale en mobile/hors-ligne : sans timestamp explicite, on croirait l’exercice fait à 9 h 05, ce qui fausserait tout ordre chronologique et toute analyse de régularité. Toujours poser timestamp côté émetteur ; laisser stored au LRS.
🧠 Quiz de révision
1. Quels sont les champs obligatoires d’un statement xAPI ?
Trois et seulement trois : actor (qui), verb (quoi), object (sur quoi). Tout le reste — result, context, timestamp, authority, id, stored — est optionnel ou posé par le LRS. Un statement de trois champs est déjà valide.
2. Le champ display d’un verbe change-t-il son identité ?
display d’un verbe change-t-il son identité ?Non. C’est l’id (l’IRI, ex. http://adlnet.gov/expapi/verbs/completed) qui identifie le verbe. display n’est qu’un libellé humain, multilingue et décoratif. Deux statements avec le même verb.id parlent du même verbe, quel que soit le texte affiché.
3. Quelle différence entre timestamp et stored ?
timestamp et stored ?timestamp = quand l’expérience a eu lieu (posé par l’émetteur). stored = quand le LRS l’a enregistrée (posé par le LRS). Ils diffèrent notamment en mobile hors-ligne synchronisé plus tard. On ne fabrique jamais stored soi-même.
4. À quoi sert authority dans un statement ?
authority dans un statement ?authority indique qui atteste de la véracité du statement — en général le système/compte authentifié qui l’a émis. Il est le plus souvent posé par le LRS d’après l’identité utilisée pour l’envoi. Il répond à la question « qui affirme que c’est vrai ? », distincte de « qui a vécu l’expérience ? » (l’actor).
5. Quand objectType devient-il obligatoire sur l’objet ?
objectType devient-il obligatoire sur l’objet ?Il est optionnel quand l’objet est une Activity (valeur par défaut, déduite de la présence d’une definition ou d’un simple id). Il devient obligatoire dès que l’objet n’est pas une activité : un Agent, un Group, un StatementRef ou un SubStatement doivent déclarer explicitement leur objectType (chapitre 6.3).
Chapitre suivant : 6.3 — Acteur, verbe, objet — on ouvre chacune des trois briques : comment identifier un acteur, choisir un verbe sans en inventer, et structurer un objet.