Les ressources exposées par l’API publique
⚠️ Prérequis : une clé d’API active. Voyez Générer et gérer vos clés d’API.
Les ressources exposées par l’API publique
⚠️ Prérequis : une clé d’API active. Voyez Générer et gérer vos clés d’API.
Cette page décrit les ressources exposées par l’API publique, les chemins sous lesquels elles répondent et celles qui acceptent une écriture. Le jeton obtenu à partir d’une clé porte la portée administrateur et ouvre tout le périmètre du compte : l’appelant est le compte et non une personne, et aucun droit de back-office n’intervient. Les mécaniques du jeton sont décrites dans S’authentifier sur l’API.
La spécification OpenAPI complète, avec les schémas et les exemples, est publiée sur doc.developers.beedeez.com et téléchargeable en openapi.json.
ℹ️ À savoir.
api.developers.beedeez.comest le serveur d’API, pas la documentation. Sa racine répond 404.
Les conventions communes
- Base :
https://api.developers.beedeez.com, en HTTPS, avecapplication/jsonen entrée comme en sortie. Le corps d’une requête est plafonné à 25 Mo. - Version : toutes les entrées sont sous
/v1. Une seule version est en service. - Identifiants : ils comportent 24 caractères hexadécimaux. Sur les entrées utilisateurs, groupes et notifications, un identifiant mal formé renvoie 400 et non 404.
- Dates : les paramètres de date sont interprétés par le serveur et l’ISO 8601 est le seul format sur lequel compter. Une valeur illisible renvoie 400.
Les ressources disponibles
| Ressource | Ce qu’elle expose | Chemins sous /v1 |
|---|---|---|
| Jetons | L’échange de la clé contre un jeton, seules entrées ouvertes sans jeton | POST /token, POST /token/refresh |
| Utilisateurs | Les comptes apprenants, leurs groupes et leurs notifications en lecture, plus la révocation du jeton d’un apprenant | GET /users, /users/email/{email}, /users/externalId/{externalId}, /users/{userId}/groups, /users/{userId}/notifications, POST /auth/logout-by-id |
| Groupes | Les groupes et leurs membres, en lecture seule | GET /groups, /groups/{groupId}, /groups/{groupId}/users, /groups/name/{uniqueName}, /groups/name/{uniqueName}/users |
| Capsules | Les capsules, en lecture et en création | GET /lessons, /lessons/{ID}, POST /lessons/create |
| Parcours et catégories | Les parcours et l’arborescence de classement, en lecture seule | GET /tracks, GET /categories |
| Activité | L’avancement d’un apprenant sur une capsule, en lecture seule | GET /active-lessons, /users/{USER_ID}/active-lessons, /lessons/{LESSON_ID}/active-lessons, /users/{USER_ID}/lessons/{LESSON_ID}/active-lessons |
| Réponses | Le détail question par question, en lecture seule | GET /users/{USER_ID}/answers, /lessons/{LESSON_ID}/answers, /users/{USER_ID}/lessons/{LESSON_ID}/answers |
| Sessions | Les sessions et leurs inscriptions, en lecture et en écriture | GET et POST /lesson-session, GET et PUT /lesson-session/{ID}, POST /lesson-session/{ID}/register/{USER_ID}, DELETE /lesson-session/{ID}/unregister/{USER_ID}, GET /lesson-session/{USER_ID}/registrations |
| Callbacks | La remontée de complétion depuis un outil tiers, en écriture | POST et GET /callbacks/update-user-lesson-status/{CALLBACK_TOKEN} |
Ces entrées forment une seule API, celle que décrit la spécification. Les webhooks reposent sur un mécanisme distinct, dans lequel Beedeez appelle votre URL.
La pagination
Deux paramètres gèrent la pagination partout où elle existe : pageSize et pageNumber, la première page portant le numéro 1. Les règles diffèrent selon la ressource.
GET /v1/lessons,GET /v1/active-lessonset les trois entrées de réponses plafonnentpageSizeà 500. Une valeur hors bornes renvoie 400.- Sans
pageSize,GET /v1/lessonsetGET /v1/active-lessonsretombent sur 50. Les entrées de réponses retombent sur un réglage serveur dont la valeur n’est pas publique. - Les entrées utilisateurs, groupes, notifications, ainsi que les trois entrées d’activité rattachées à un apprenant ou à une capsule, n’appliquent aucun plafond et utilisent le même réglage serveur en l’absence de paramètre. Passez donc toujours
pageSizeexplicitement sur ces entrées. - Les parcours, les catégories et les sessions ne sont pas paginés et renvoient tout le compte en un appel.
Les filtres disponibles
Le paramètre search n’examine pas les mêmes champs selon l’entrée appelée. Sur GET /v1/users, il cherche dans l’adresse e-mail, l’identifiant de connexion, le nom et le prénom. Sur GET /v1/groups, il porte sur le titre, le nom unique et la description du groupe, pas sur ses membres. Sur les deux entrées qui listent les membres d’un groupe, il cherche dans le nom, le prénom, l’adresse e-mail, l’identifiant de connexion et l’alias.
Les autres filtres se répartissent ainsi :
includeDisabled=trueréintègre les comptes et les groupes désactivés, exclus par défaut. Il s’applique àGET /v1/groupset aux deux entrées listant les membres d’un groupe.GET /v1/usersn’accepte pas ce paramètre et exclut toujours les comptes désactivés.updatedSincene renvoie que ce qui a changé depuis une date donnée. Il existe surGET /v1/active-lessons,GET /v1/lessons/{LESSON_ID}/answersetGET /v1/users/{USER_ID}/answers. C’est sur lui que repose une synchronisation incrémentale.includeArchivedetincludeEntryQuizajoutent les tentatives précédentes et le quiz d’entrée sur les trois entrées de réponses.since,seenetincludeBackOfficefiltrent les notifications d’un apprenant.
Aucun paramètre de tri n’existe. L’ordre est fixé par ressource.
Le cloisonnement par compte
Chaque appel authentifié est filtré sur le compte porté par le jeton : un identifiant appartenant à un autre compte renvoie 404 ou une liste vide, jamais la donnée.
Les deux callbacks font exception et n’exigent aucun jeton d’accès. Leur seule garantie est le jeton de callback présent dans l’URL, qui porte le compte, l’apprenant et la capsule. Traitez cette URL comme un secret, au même titre qu’une clé.
Les erreurs
Une erreur métier renvoie un corps JSON à trois champs :
{ "message": "Group not found", "kind": "DomainError", "statusCode": 404 }Une validation refusée renvoie 422 avec message et un objet details qui liste les champs en cause. Une erreur serveur renvoie 500 avec message seul. Les codes en service sont 400 pour un paramètre invalide, 401 pour un jeton absent, expiré ou sans portée, 403 pour un accès refusé, 404 pour une ressource introuvable, 422 pour une validation et 500 pour une erreur serveur.
Ce que l’API ne permet pas
Aucune écriture n’est possible sur les utilisateurs, les groupes, les parcours ni les catégories. Créer ou modifier un apprenant passe par le provisioning.
Aucun compteur total n’est renvoyé. Une réponse est un tableau nu, sans total, sans nombre de pages et sans lien vers la page suivante. Une page vide est le seul signal de fin.
GET /v1/lessons/{ID}/ranking ne renvoie pas de classement. L’entrée figure dans la spécification et répond 200 avec une chaîne de texte sans donnée.
Aucune limite de débit n’est publiée, et aucune n’est appliquée aujourd’hui. Ne construisez rien sur cette absence.
Les comportements à connaître avant d’intégrer
La pagination des réponses compte des activités, pas des réponses. Une page de pageSize activités s’aplatit en beaucoup plus de lignes : le nombre d’éléments reçus n’est jamais celui demandé.
Les deux entrées qui listent les membres d’un groupe renvoient une liste vide au lieu du 404 annoncé lorsque le groupe est introuvable. GET /v1/groups/{groupId}/users ne vérifie pas non plus que le groupe appartient à votre compte, contrairement à GET /v1/groups/{groupId} : un identifiant étranger renvoie simplement une liste vide. N’utilisez pas ces entrées pour vérifier qu’un groupe existe.
POST /v1/auth/logout-by-id attend l’identifiant externe de l’apprenant, celui de votre système de gestion, et non son identifiant Beedeez.
Pour aller plus loin
- S’authentifier sur l’API : obtenir le jeton et gérer son expiration, la première chose à écrire
- Faire remonter une complétion depuis un outil tiers : le seul usage des deux entrées callback décrites ci-dessus
- Les événements webhook disponibles : la liste des événements réellement émis
- API publique, webhooks, callbacks : que choisir : à relire si le mécanisme n’est pas encore tranché