MeetingHub MeetingHub Télécharger la collection Postman

Référence — clés d'intégration

Les routes de gestion, l’objet Clé, les portées et le journal.

Les routes de gestion des clés, sous /api/institutions/:institutionId/keys, demandent la session d'un administrateur de l'établissement — la capacité institution.manage : voir Conventions. Un éditeur partenaire les appelle aussi, avec sa clé mhp_…, sur les établissements qu'il a ouverts : il ne voit et ne révoque que les clés qu'il a créées lui-même. Voir Éditeurs partenaires.

L'usage d'une clé sur le reste de /api est décrit à la fin de cette page.

L'objet Clé

{
  "id": "2d388508-08af-4066-bc9e-2a705426a434",
  "label": "ENT — émargement",
  "prefix": "Abdvt1rV",
  "scopes": ["attendance:read"],
  "partnerId": null,
  "expiresAt": "2027-09-01T00:00:00.000Z",
  "revokedAt": null,
  "lastUsedAt": "2026-10-14T10:21:00.000Z",
  "createdAt": "2026-09-02T08:00:00.000Z"

}
ChampTypeDescription
iduuidIdentifiant de la clé, le :keyId des routes
labelstringLe nom donné à la clé, de 1 à 120 caractères
prefixstringLes 8 caractères qui suivent mhk_ dans la clé. Ils sont stockés en clair et identifient la clé dans un journal
scopesstring[]Les portées de la clé, sans doublon. Voir Portées
partnerIduuid ou nullL'éditeur partenaire qui a créé la clé ; null si l'établissement l'a créée lui-même
expiresAtdatetime ou nullL'échéance de la clé ; null si elle n'en a pas
revokedAtdatetime ou nullLa date de la PREMIÈRE révocation ; null tant que la clé est active
lastUsedAtdatetime ou nullLe dernier usage réussi à s'authentifier, noté à la minute près ; null si la clé n'a jamais servi
createdAtdatetimeLa date de création

Le secret de la clé n'est jamais rendu, sauf une fois, à la création, dans le champ plaintext. Le serveur n'en conserve qu'une empreinte.

Portées

Chaque portée devient, à l'usage, une capacité : c'est elle que les routes exigent, et que GET /api/me rend dans capabilities. Toute clé a en plus institution.view, qui ouvre la lecture de son établissement.

Dans ce tableau, … vaut /api/institutions/:institutionId.

PortéeCapacitéRoutes ouvertesÉcrit des données
attendance:readattendance.readGET …/lessons/:lessonId/attendance, .csv et .htmlnon
schedule:readschedule.readGET …/lessons, GET …/lessons/:lessonId, GET …/lessons/conflictsnon
schedule:writeschedule.writePUT …/lessons, DELETE …/lessons/by-ref/:ref, et les autres écritures sous …/lessonsoui : peut créer, déplacer et annuler des cours, créer des salles et des classes
roster:writeroster.writePUT …/classes/by-ref/:ref/rosteroui : peut créer des comptes et obtenir leurs liens d'activation

GET /api/me, GET /api/institutions et les lectures de l'établissement (GET …, GET …/centres, GET …/room-kinds) ne demandent aucune portée. Il n'existe pas d'autre portée ; une valeur inconnue est refusée à la création de la clé. La liste complète des routes et de ce qu'elles exigent est dans Conventions.

GET /api/institutions/:institutionId/keys

Liste les clés de l'établissement, révoquées comprises. Exige institution.manage ou partner.manage. Un éditeur partenaire ne reçoit que les clés qu'il a créées.

Aucun paramètre de requête.

Réponse 200 :

{
  "keys": [ { "id": "…", "label": "ENT — émargement", "partnerId": null, "…": "…" } ],
  "scopes": ["attendance:read", "schedule:read", "schedule:write", "roster:write"]

}
ChampTypeDescription
keysClé[]Les clés, de la plus ancienne à la plus récente. Voir L'objet Clé
scopesstring[]Toutes les portées qui existent, dans cet ordre
CodecodeCause
403forbiddenNi administrateur de l'établissement, ni l'éditeur qui l'a ouvert
404not-foundÉtablissement inconnu, ou que l'appelant n'atteint pas

POST /api/institutions/:institutionId/keys

Crée une clé et la rend en clair, une seule fois. Exige institution.manage ou partner.manage.

{
  "label": "ENT — émargement",
  "scopes": ["attendance:read", "schedule:write"],
  "expiresAt": "2027-09-01T00:00:00Z"

}
ChampTypeObligatoireRègles
labelstringouiEspaces de bord retirés ; ne peut pas être vide ; tronqué à 120 caractères
scopesstring[]ouiPeut être vide. Chaque valeur doit être une portée existante ; les doublons sont retirés
expiresAtdatetime ou nullnonAbsent, null ou "" : sans échéance. Sinon, une date dans le futur

Réponse 201 :

{
  "key": {
    "id": "2d388508-08af-4066-bc9e-2a705426a434",
    "label": "ENT — émargement",
    "prefix": "Abdvt1rV",
    "scopes": ["attendance:read", "schedule:write"],
    "partnerId": null,
    "expiresAt": "2027-09-01T00:00:00.000Z",
    "revokedAt": null,
    "lastUsedAt": null,
    "createdAt": "2026-09-02T08:00:00.000Z",
    "plaintext": "mhk_Abdvt1rV_47R9xK2pQ…"
  },
  "notice": "Cette clé ne sera plus affichée. Copiez-la maintenant."

}
ChampTypeDescription
keyCléLa clé créée, avec en plus le champ plaintext
key.plaintextstringLa clé complète, à placer dans l'en-tête Authorization. Elle n'est plus jamais rendue
noticestringUn rappel destiné à la personne qui crée la clé
CodeCorpsCause
400donnez un nom à cette clé — sinon nul n’osera la révoquerlabel absent ou vide
400scopes attend une listescopes absent ou pas un tableau
400portée inconnue : … — parmi …Une valeur de scopes n'est pas une portée
400expiresAt attend une date ISOexpiresAt n'est ni une chaîne ni null
400expiresAt illisibleexpiresAt n'est pas une date
400une échéance déjà passée n’ouvrirait rienexpiresAt est dans le passé
403portée réservée aux éditeurs partenaires sous accord de données personnelles : …Un éditeur partenaire sans accord demande attendance:read ou roster:write

Ces refus portent le code invalid (400) ou forbidden (403).

DELETE /api/institutions/:institutionId/keys/:keyId

Révoque une clé. Exige institution.manage ou partner.manage. La clé n'est pas supprimée : elle reste listée, avec sa date de révocation, et son journal reste consultable.

Paramètre de cheminTypeDescription
keyIduuidL'identifiant de la clé

Réponse 200 :

{ "key": { "id": "…", "revokedAt": "2026-10-20T09:00:00.000Z", "…": "…" } 
}
ChampTypeDescription
keyCléLa clé révoquée

La révocation est idempotente : révoquer une clé déjà révoquée rend 200 et garde la date de la première révocation. Une clé révoquée est refusée dès la requête suivante.

CodeCorpsCause
404clé inconnueAucune clé de cet identifiant dans l'établissement, keyId mal formé, ou — pour un éditeur partenaire — une clé qu'il n'a pas créée

GET /api/institutions/:institutionId/keys/:keyId/activity

Le journal de ce qu'une clé a fait, du plus récent au plus ancien. Exige institution.manage : l'administration de l'établissement seulement.

Paramètre de cheminTypeDescription
keyIduuidL'identifiant de la clé
Paramètre de requêteTypeDéfautBornesDescription
limitinteger201 à 100Nombre de traces rendues
offsetinteger00 ou plusNombre de traces à sauter
searchstringvide120 caractèresCherche dans action, actorEmail, actorLabel et targetId, sans tenir compte de la casse

Réponse 200 :

{
  "rows": [
    {
      "id": "b0f3…",
      "actorId": null,
      "actorEmail": null,
      "actorKeyId": "2d388508-08af-4066-bc9e-2a705426a434",
      "actorLabel": "ENT — émargement",
      "action": "GET /api/institutions/:institutionId/lessons/:lessonId/attendance.csv",
      "targetType": "/api/institutions/:institutionId/lessons/:lessonId/attendance.csv",
      "targetId": null,
      "metadata": { "status": 200 },
      "at": "2026-10-14T10:21:07.412Z"
    }
  ],
  "total": 1

}
ChampTypeDescription
rowsTrace[]Les traces de la tranche. Voir L'objet Trace
totalintegerLe nombre total de traces de cette clé qui répondent à search
CodeCorpsCause
403cet accès ne permet pas cela — il faut : institution.manageL'appelant n'administre pas l'établissement
404clé inconnueAucune clé de cet identifiant dans l'établissement, ou keyId mal formé

L'objet Trace

ChampTypeDescription
iduuidIdentifiant de la trace
actorIduuid ou nullLe compte qui a agi ; null quand c'est une clé
actorEmailstring ou nullL'adresse de ce compte, recopiée au moment de l'acte ; null pour une clé
actorKeyIduuid ou nullLa clé d'établissement qui a agi ; null quand c'est un compte ou un éditeur partenaire
actorLabelstring ou nullLe nom de la clé, recopié au moment de l'acte : il survit à la suppression de la clé. Pour un éditeur partenaire : éditeur partenaire « … »
actionstringLa méthode HTTP et le motif de la route, par exemple PUT /api/institutions/:institutionId/lessons
targetTypestringLe motif de la route, sans la méthode
targetIdstring ou nullLa valeur du paramètre :id, :shortId ou :accountId de la route ; null pour les autres, dont celles à :lessonId, :keyId ou :ref
metadataobjectLe code de réponse, dans status (integer), et les champs simples du corps de la requête
atdatetimeLe moment de l'acte

Dans metadata, un tableau du corps est remplacé par "[N éléments]" et un objet par "[objet]". Les champs password, roomPassword, token, csv, secret et admin ne sont jamais inscrits.

Ce qui est inscrit. Pour une clé, chaque requête qui aboutit — code de réponse inférieur à 400 —, lectures comprises. Une requête refusée n'est pas inscrite, qu'elle le soit à l'authentification ou ensuite, par exemple faute de capacité.

Échecs d'authentification

Sur /api, la clé se présente dans l'en-tête Authorization: Bearer …, et une requête ne porte qu'un justificatif. Une clé mal formée, inconnue, révoquée ou expirée rend 401, avec un en-tête WWW-Authenticate :

SituationCodeCorpscodeEn-tête WWW-Authenticate
Ni clé ni session, sur une route qui demande un appelant (sous /api/institutions/:institutionId, la réponse est 404)401identification requiseauth.required—
En-tête Authorization qui n'est pas Bearer …401en-tête Authorization attendu : Bearer <clé>auth.invalid-keyBearer error="invalid_token"
Clé mal formée401clé d’intégration illisibleauth.invalid-keyBearer error="invalid_token"
Clé inconnue, ou secret faux401clé d’intégration inconnue ou révoquéeauth.invalid-keyBearer error="invalid_token"
Clé révoquée401clé d’intégration inconnue ou révoquéeauth.invalid-keyBearer error="invalid_token"
Clé expirée401clé d’intégration expiréeauth.invalid-keyBearer error="invalid_token"
Établissement de la clé en pause403l’accès de cet établissement est en pause : …institution.paused—
Cookie de session et en-tête Authorization ensemble400une seule identité par requête : …auth.ambiguous—

Une clé inconnue et une clé au mauvais secret reçoivent la même réponse, à dessein. Une clé expirée reçoit un message distinct : il faut la remplacer, pas la corriger.

Une clé valide qui appelle une route hors de ses portées reçoit 403, et le message nomme la capacité manquante :

CodeCorpscode
403cet accès ne permet pas cela — il faut : schedule.readforbidden

Une clé qui désigne un autre établissement que le sien reçoit 404, code not-found : pour elle, cet établissement n'existe pas.

Sur les anciennes adresses /api/integration/…, alias dépréciés de ces routes, une requête sans clé d'établissement rend 401, clé d’intégration requise, avec l'en-tête WWW-Authenticate: Bearer realm="MeetingHub".