MeetingHub MeetingHub Télécharger la collection Postman

Référence — feuilles de présence

Les objets Feuille et Ligne, et les formats JSON, CSV et HTML.

Récupérer la feuille de présence d'un cours — l'émargement, pour un financeur — en JSON, en CSV ou prête à imprimer. Ces routes s'appellent avec une clé d'intégration : voir Conventions.

Toutes sont sous /api/institutions/:institutionId, noté … dans les titres ci-dessous, où :institutionId est l'identifiant de l'établissement de la clé, rendu par GET /api/me.

Quand une feuille existe

Une feuille est arrêtée une fois, et ne change plus ensuite :

Un cours sans classe attendue et sans aucun participant n'a pas de feuille : il n'y a personne à attendre ni personne de venu. Un cours avec une classe a toujours sa feuille, même si personne n'est venu.

L'arrêt d'une feuille émet l'événement attendance.closed, qui porte, dans sessionId, l'identifiant du cours à utiliser dans les routes ci-dessous — le :lessonId : voir Webhooks.

L'objet Feuille

{
  "id": "e3b0c442-98fc-4c14-9afb-f4c8996fb924",
  "sessionId": "9214f192-5c1e-4a0e-9b6e-1c2d3e4f5a6b",
  "roomName": "Salle 204",
  "groupName": "BTS SIO 1",
  "siteName": "Campus de Douala",
  "title": "Mathématiques",
  "startsAt": "2026-10-14T08:00:00.000Z",
  "durationMinutes": 120,
  "expectedCount": 28,
  "presentCount": 26,
  "closedAt": "2026-10-14T10:30:00.000Z",
  "signature": "Q2hhcnNldCBsaWtlIGEgc2lnbmF0dXJlIGhlcmUuLi4"

}
ChampTypeDescription
iduuidIdentifiant de la feuille
sessionIduuid ou nullLe cours — son :lessonId
roomNamestringLe nom de la salle, recopié à l'arrêt ; (salle supprimée) si la salle n'existait plus
groupNamestring ou nullLe nom de la classe, recopié à l'arrêt ; pour un cours diffusé à d'autres classes, leurs noms joints par + ; null si aucune
siteNamestring ou nullLe nom du centre de la salle, recopié à l'arrêt ; null si la salle n'est rattachée à aucun centre. Hors du code de vérification : c'est un classement, pas un fait de présence
titlestring ou nullL'intitulé du cours
startsAtdatetimeL'heure de début prévue
durationMinutesintegerLa durée prévue, en minutes, au moins 1
expectedCountintegerL'effectif attendu : les membres des classes attendues ; à défaut, le nombre d'invités de la salle ; à défaut, 0
presentCountintegerLe nombre de personnes venues au moins une fois : c'est le nombre de lignes
closedAtdatetime ou nullLe moment de l'arrêt
signaturestring ou nullLe code de vérification de la feuille. Voir Le code de vérification

Les noms sont RECOPIÉS dans la feuille, et non liés : une salle supprimée ou une classe archivée ne change pas une feuille déjà arrêtée.

L'objet Ligne

Une ligne par personne. Les connexions successives d'une même personne — un même compte, ou, sans compte, une même connexion reprise — sont fusionnées.

ChampTypeDescription
accountIduuid ou nullLe compte de la personne ; null pour un participant venu sans compte
displayNamestringLe nom affiché pendant le cours
emailstring ou nullL'adresse du compte, recopiée à l'arrêt ; null sans compte, ou pour un compte sans courriel
firstSeenAtdatetimeLa première entrée dans la salle
lastSeenAtdatetimeLa dernière sortie, bornée à la fermeture de la salle
presentSecondsintegerLe temps de présence cumulé, en secondes, sans compter le temps après closesAt
interruptionsintegerLe nombre de coupures d'au moins 60 secondes entre deux connexions successives
qualitystringLa qualité de réception vécue : good, fair, poor ou unknown. Quand la personne s'est connectée plusieurs fois, c'est la plus mauvaise de ses connexions. Voir Qualité vécue

Les lignes sont rendues dans l'ordre alphabétique de displayName, puis par première entrée.

Qualité vécue

Elle mesure ce que le serveur a réussi à transmettre à la personne. Le serveur note de 0 à 10 chaque flux qu'elle reçoit, audio comme vidéo ; à chaque instant, c'est le plus mauvais des flux reçus qui compte. Une note inférieure à 5 est une réception dégradée, de 5 à 7 une réception moyenne, de 8 à 10 une bonne réception. Le verdict est pondéré par le temps passé à chaque niveau, et non moyenné.

ValeurRègle
poorRéception dégradée pendant au moins un quart du temps observé
fairSinon : réception moyenne ou dégradée pendant au moins un quart du temps, ou au moins 2 minutes cumulées de réception dégradée
goodSinon
unknownMoins d'une minute observée : une présence trop brève, ou une personne qui n'a reçu aucun flux, seule dans la salle par exemple

Le code de vérification

Le champ signature porte le code de vérification de la feuille : un HMAC-SHA256 de son contenu, encodé en base64url — 43 caractères. Il est calculé par le serveur à l'arrêt, avec une clé secrète qu'il est seul à connaître. Vous ne pouvez pas le recalculer de votre côté : archivez-le avec la feuille.

N'importe qui peut en revanche le faire contrôler, sans compte, sur la page publique /verification de l'instance — par exemple https://reunion.votre-etablissement.fr/verification?code=Q2hhcnNldCBs…. La page dit si la feuille est authentique ou si elle a été modifiée depuis son arrêt, et rappelle l'établissement, la salle, le cours et les effectifs. Un financeur qui tient la feuille imprimée peut ainsi la vérifier lui-même.

GET …/lessons/:lessonId/attendance

La feuille en JSON. Exige attendance.read — la portée attendance:read.

Paramètre de cheminTypeDescription
lessonIduuidL'identifiant MeetingHub du cours, celui de sessionId dans le webhook

Réponse 200 :

{
  "sheet": { "id": "e3b0c442-…", "presentCount": 26, "…": "…" },
  "lines": [
    {
      "accountId": "5a74f72e-81af-402c-a2af-a5ebd35b7bba",
      "displayName": "Awa Diallo",
      "email": "awa@ecole.fr",
      "firstSeenAt": "2026-10-14T07:58:12.000Z",
      "lastSeenAt": "2026-10-14T10:01:40.000Z",
      "presentSeconds": 7240,
      "interruptions": 1,
      "quality": "good"
    }
  ],
  "filename": "emargement-salle-204-2026-10-14.csv"

}
ChampTypeDescription
sheetFeuilleVoir L'objet Feuille
linesLigne[]Voir L'objet Ligne ; vide si personne n'est venu
filenamestringLe nom de fichier proposé pour l'export CSV : emargement-, le nom de la salle simplifié, puis la date de début au format AAAA-MM-JJ
CodeCorpscodeCause
403cet accès ne permet pas cela — il faut : attendance.readforbiddenPortée absente
404établissement inconnunot-found:institutionId n'est pas l'établissement de la clé
409feuille non encore arrêtée — attendez l’alerte attendance.closedsheet.not-closedAucune feuille pour ce lessonId : le cours n'est pas encore terminé, n'a rien à relever, n'existe pas dans l'établissement, ou l'identifiant est mal formé

Avec une session plutôt qu'une clé, un directeur de centre ne lit que les feuilles des cours de ses centres ; pour un autre cours, la réponse est 404, cours inconnu.

GET …/lessons/:lessonId/attendance.csv

La même feuille, en CSV. Exige attendance.read. Mêmes paramètres et mêmes erreurs que la route JSON.

Réponse 200 :

En-têteValeur
Content-Typetext/csv; charset=utf-8
Content-Dispositionattachment; filename="emargement-salle-204-2026-10-14.csv"

Format du fichier

PropriétéValeur
EncodageUTF-8, avec l'indicateur d'ordre des octets en tête : Excel en français l'ouvre sans conversion
Séparateur;
Fin de ligne\r\n
GuillemetsUn champ qui contient ;, " ou un saut de ligne est entouré de guillemets ; ses guillemets sont doublés
FormulesUn champ qui commence par =, +, -, @, une tabulation ou un retour chariot est précédé d'une apostrophe, pour qu'un tableur ne l'exécute pas
DatesJJ/MM/AAAA HH:MM, en UTC

Le fichier commence par un bloc d'en-tête, une ligne vide, la ligne des colonnes, puis une ligne par personne — ou une ligne Aucun participant.

Ligne d'en-têteContenu
Feuille de présenceTitre, seul sur sa ligne
SalleroomName
ClassegroupName, ou —
Courstitle, ou —
DébutstartsAt
Durée prévuedurationMinutes, suivi de min
Effectif attenduexpectedCount
PrésentspresentCount
Clôturée leclosedAt, ou non clôturée
Code de vérificationsignature, ou —
ColonneContenu
NomdisplayName
Courrielemail, vide sans courriel
Première entréefirstSeenAt, au format JJ/MM/AAAA HH:MM
Dernière sortielastSeenAt, heure seule au format HH:MM
Présence (minutes)presentSeconds converti en minutes, arrondi à l'entier
Présence (h:mm)La même durée, au format H:MM
Interruptionsinterruptions
AssiduitéLa part de la durée prévue passée dans la salle, plafonnée à 100 %, avec une décimale et une virgule : 87,5 %
Qualité vécuebonne, moyenne, dégradée ou inconnue — pour good, fair, poor et unknown

GET …/lessons/:lessonId/attendance.html

La même feuille, prête à imprimer. Exige attendance.read. Mêmes paramètres et mêmes erreurs que la route JSON.

Réponse 200 :

En-têteValeur
Content-Typetext/html; charset=utf-8
Content-Dispositioninline; filename="emargement-salle-204-2026-10-14.html"

Une page autonome, au format A4, sans aucune ressource extérieure : elle s'ouvre hors ligne et s'imprime en PDF depuis n'importe quel navigateur. L'en-tête du tableau se répète sur chaque page imprimée, et une ligne n'est jamais coupée entre deux pages. Elle porte un cadre pour le visa du responsable, le code de vérification de la feuille et, quand l'instance connaît son adresse publique, l'adresse de la page où le vérifier.

POST …/lessons/:lessonId/attendance/close

Arrête la feuille sans attendre le balayage. Exige schedule.write — la portée schedule:write. Aucun corps.

Réponse 201 :

{ "sheet": { "id": "e3b0c442-…", "closedAt": "2026-10-14T10:05:00.000Z", "…": "…" } 
}
ChampTypeDescription
sheetFeuilleLa feuille arrêtée. Si elle l'était déjà, elle est rendue telle quelle, sans être recalculée

Une feuille arrêtée avant la fin du cours ne compte que les présences enregistrées jusque-là : elle ne change plus ensuite. Le premier arrêt émet attendance.closed ; un second appel ne l'émet pas une nouvelle fois.

CodeCorpscodeCause
403cet accès ne permet pas cela — il faut : schedule.writeforbiddenPortée absente
404cours inconnunot-foundAucun cours de cet identifiant dans l'établissement, ou lessonId mal formé
409rien à relever : ni classe attendue, ni présencesheet.emptyLe cours n'a ni classe attendue ni participant : il n'a pas de feuille

Toutes les feuilles d'un coup

GET …/export/attendance.csv rend toutes les feuilles de l'établissement en un seul fichier, une ligne par personne et par cours. Elle exige institution.export, que seul le Promoteur de l'établissement détient, avec sa session : une clé ne l'atteint pas. Elle reste ouverte quand l'établissement est en pause, pour qu'il puisse emporter ses feuilles.

Les anciennes adresses

GET /api/integration/sessions/:id/attendance, et ses variantes .csv et .html, répondent encore avec une clé d'établissement, comme alias dépréciés de ces routes : chaque réponse porte Deprecation: true et un en-tête Link vers la route de /api. Passez à /api.