Cours personnalisés
Un cours personnalisé est une séquence curatée orientée apprenant de sujets et scénarios tirés du catalogue de contenu SecureCodingHub. Une fois créé, un cours personnalisé peut être attribué exactement comme un sujet ou une catégorie intégrée. Nécessite custom-courses:read ou custom-courses:write selon le verbe.
Points de terminaison
| Méthode | Chemin | Portée | Objectif |
|---|---|---|---|
GET | /custom-courses | custom-courses:read | Lister tous les cours personnalisés de l'organisation. |
GET | /custom-courses/{'{'}id{'}'} | custom-courses:read | Récupérer un cours personnalisé unique avec ses éléments ordonnés. |
POST | /custom-courses | custom-courses:write | Créer un nouveau cours personnalisé. |
PATCH | /custom-courses/{'{'}id{'}'} | custom-courses:write | Mettre à jour les métadonnées et/ou remplacer la liste d'éléments. |
DELETE | /custom-courses/{'{'}id{'}'} | custom-courses:write | Désactiver doucement un cours personnalisé. |
Tous les chemins sont relatifs à https://api.limeplate.com/api/public/v1.
Le modèle d'élément
Chaque cours personnalisé contient une liste ordonnée d'éléments. Chaque élément est une référence à un sujet ou scénario du catalogue — voir Catalogue de contenu pour les identifiants.
| Champ | Type | Signification |
|---|---|---|
itemType | string | Soit "topic" (un sujet de pratique comme sql-injection) soit "scenario" (un scénario en mode apprentissage). |
itemId | string | L'id catalogue du sujet ou scénario. |
orderIndex | integer | Ordre d'affichage basé sur zéro dans l'interface apprenant. Les valeurs plus basses apparaissent en premier. |
Sur PATCH, omettez le champ items pour laisser les éléments intacts, ou envoyez une liste de remplacement complète pour écraser. Il n'y a pas de mise à jour d'élément partielle — renvoyez la séquence entière dans l'ordre que vous voulez qu'elle soit stockée.
Lister les cours personnalisés
Renvoie une entrée par cours personnalisé actif dans l'organisation, triées par mise à jour la plus récente.
GET /api/public/v1/custom-courses
Authorization: Bearer scs_live_…Réponse
[
{
"id": "8b1f0c2e-3a45-4d99-9a7e-2c5e1b3a8f02",
"name": "Backend Onboarding — Q2",
"description": "Required reading for new backend hires.",
"icon": "shield",
"color": "#3b82f6",
"itemCount": 6,
"usageCount": 12,
"createdByUserId": "1a2b3c4d-5e6f-7081-9203-4d5e6f708192",
"createdByName": "Jane Smith",
"createdAt": "2026-04-10T09:22:14Z",
"updatedAt": "2026-05-18T15:01:47Z"
}
]Exemple
curl -sS \
-H "Authorization: Bearer $SCH_API_KEY" \
https://api.limeplate.com/api/public/v1/custom-coursesRécupérer un cours personnalisé
Renvoie le cours avec ses éléments ordonnés développés. resolvedTitle est le titre humainement lisible du sujet ou scénario sous-jacent au moment de la lecture — pratique pour rendre sans une seconde recherche de catalogue.
GET /api/public/v1/custom-courses/{customCourseId}
Authorization: Bearer scs_live_…Réponse
{
"id": "8b1f0c2e-3a45-4d99-9a7e-2c5e1b3a8f02",
"name": "Backend Onboarding — Q2",
"description": "Required reading for new backend hires.",
"icon": "shield",
"color": "#3b82f6",
"items": [
{
"id": "c1d2e3f4-5060-7081-9203-4d5e6f708192",
"itemType": "topic",
"itemId": "sql-injection",
"resolvedTitle": "SQL Injection",
"orderIndex": 0
},
{
"id": "d2e3f405-6070-8192-0304-5e6f70819203",
"itemType": "scenario",
"itemId": "auth-bypass-walkthrough",
"resolvedTitle": "Auth Bypass Walkthrough",
"orderIndex": 1
},
{
"id": "e3f40506-7081-9203-0405-6f7081920304",
"itemType": "topic",
"itemId": "xss",
"resolvedTitle": "Cross-Site Scripting",
"orderIndex": 2
}
],
"usageCount": 12,
"createdByUserId": "1a2b3c4d-5e6f-7081-9203-4d5e6f708192",
"createdByName": "Jane Smith",
"createdAt": "2026-04-10T09:22:14Z",
"updatedAt": "2026-05-18T15:01:47Z"
}Exemple
curl -sS \
-H "Authorization: Bearer $SCH_API_KEY" \
https://api.limeplate.com/api/public/v1/custom-courses/8b1f0c2e-3a45-4d99-9a7e-2c5e1b3a8f02Créer un cours personnalisé
Crée un cours et renvoie la vue détail. L'organisation de la clé API possède le nouveau cours ; l'utilisateur qui a émis la clé est enregistré comme créateur.
POST /api/public/v1/custom-courses
Authorization: Bearer scs_live_…
Content-Type: application/jsonCorps de requête
{
"name": "Backend Onboarding — Q2",
"description": "Required reading for new backend hires.",
"icon": "shield",
"color": "#3b82f6",
"items": [
{ "itemType": "topic", "itemId": "sql-injection", "orderIndex": 0 },
{ "itemType": "scenario", "itemId": "auth-bypass-walkthrough", "orderIndex": 1 },
{ "itemType": "topic", "itemId": "xss", "orderIndex": 2 }
]
}name est requis et doit être unique dans l'organisation. description, icon et color sont optionnels — color prend toute chaîne hex CSS. items peut être vide à la création ; vous pouvez le peupler plus tard via PATCH.
Réponse
Même forme que Récupérer un cours personnalisé.
Exemple
curl -sS -X POST \
-H "Authorization: Bearer $SCH_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "Backend Onboarding — Q2",
"description": "Required reading for new backend hires.",
"icon": "shield",
"color": "#3b82f6",
"items": [
{ "itemType": "topic", "itemId": "sql-injection", "orderIndex": 0 },
{ "itemType": "topic", "itemId": "xss", "orderIndex": 1 }
]
}' \
https://api.limeplate.com/api/public/v1/custom-coursesMettre à jour un cours personnalisé
Tous les champs de la requête sont optionnels. Passez uniquement les champs que vous voulez modifier. Envoyer items remplace toute la liste d'éléments — pour réordonner, renvoyez chaque élément avec de nouvelles valeurs orderIndex.
PATCH /api/public/v1/custom-courses/{customCourseId}
Authorization: Bearer scs_live_…
Content-Type: application/jsonCorps de requête
{
"name": "Backend Onboarding — Q3",
"items": [
{ "itemType": "topic", "itemId": "sql-injection", "orderIndex": 0 },
{ "itemType": "topic", "itemId": "ssrf", "orderIndex": 1 },
{ "itemType": "scenario", "itemId": "jwt-tampering", "orderIndex": 2 }
]
}Réponse
L'objet détail mis à jour.
Exemple
curl -sS -X PATCH \
-H "Authorization: Bearer $SCH_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "name": "Backend Onboarding — Q3" }' \
https://api.limeplate.com/api/public/v1/custom-courses/8b1f0c2e-3a45-4d99-9a7e-2c5e1b3a8f02Supprimer un cours personnalisé
Désactive doucement le cours. Il cesse d'apparaître dans GET /custom-courses et dans les interfaces apprenant. Les affectations existantes qui référençaient le cours continuent de suivre la progression historique mais ne sont pas livrées aux nouveaux destinataires.
DELETE /api/public/v1/custom-courses/{customCourseId}
Authorization: Bearer scs_live_…Réponse
{ "message": "Custom course deactivated" }Exemple
curl -sS -X DELETE \
-H "Authorization: Bearer $SCH_API_KEY" \
https://api.limeplate.com/api/public/v1/custom-courses/8b1f0c2e-3a45-4d99-9a7e-2c5e1b3a8f02Attribuer un cours personnalisé
Un cours personnalisé n'est pas livré aux apprenants tant qu'il n'est pas attribué. Utilisez Affectations avec targetType: "custom-course" et targetId définis sur l'id du cours personnalisé :
curl -sS -X POST \
-H "Authorization: Bearer $SCH_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"assigneeType": "user",
"assigneeId": "1a2b3c4d-5e6f-7081-9203-4d5e6f708192",
"contentArea": "practice",
"targetType": "custom-course",
"targetId": "8b1f0c2e-3a45-4d99-9a7e-2c5e1b3a8f02",
"deadline": "2026-06-15T00:00:00Z",
"isMandatory": true
}' \
https://api.limeplate.com/api/public/v1/assignmentsL'apprenant voit les éléments dans l'ordre orderIndex. Les sujets de pratique et les scénarios d'apprentissage sont suivis sous leurs points de terminaison de progression respectifs — voir Progression.