Dokumente/API & Webhooks/Benutzerdefinierte Kurse

Benutzerdefinierte Kurse

Ein benutzerdefinierter Kurs ist eine für den Lernenden sichtbare kuratierte Sequenz von Topics und Szenarien, die aus dem SecureCodingHub-Inhaltskatalog gezogen werden. Einmal erstellt, kann ein benutzerdefinierter Kurs genauso wie ein eingebautes Topic oder eine Kategorie zugewiesen werden. Erfordert custom-courses:read oder custom-courses:write je nach Verb.

Endpunkte

MethodePfadGeltungsbereichZweck
GET/custom-coursescustom-courses:readAlle benutzerdefinierten Kurse in der Organisation auflisten.
GET/custom-courses/{'{'}id{'}'}custom-courses:readEinen einzelnen benutzerdefinierten Kurs mit seinen geordneten Elementen abrufen.
POST/custom-coursescustom-courses:writeEinen neuen benutzerdefinierten Kurs erstellen.
PATCH/custom-courses/{'{'}id{'}'}custom-courses:writeMetadaten aktualisieren und/oder die Elementliste ersetzen.
DELETE/custom-courses/{'{'}id{'}'}custom-courses:writeEinen benutzerdefinierten Kurs soft-deaktivieren.

Alle Pfade sind relativ zu https://api.limeplate.com/api/public/v1.

Das Element-Modell

Jeder benutzerdefinierte Kurs enthält eine geordnete Liste von Elemente. Jedes Element ist eine Referenz zu einem Topic oder Szenario aus dem Katalog — siehe Inhaltskatalog für die Kennzeichner.

FeldTypBedeutung
itemTypestringEntweder "topic" (ein Übungs-Topic wie sql-injection) oder "scenario" (ein Lern-Szenario).
itemIdstringDie Katalog-ID des Topics oder Szenarios.
orderIndexintegerNull-basierte Anzeigereihenfolge in der Lernenden-UI. Niedrigere Werte erscheinen zuerst.

Bei PATCH lassen Sie das items-Feld weg, um Elemente unangetastet zu lassen, oder senden Sie eine vollständige Ersatzliste zum Überschreiben. Es gibt keine partielle Element-Aktualisierung — senden Sie die gesamte Sequenz in der gewünschten Reihenfolge erneut.

Benutzerdefinierte Kurse auflisten

Gibt einen Eintrag pro aktivem benutzerdefiniertem Kurs in der Organisation zurück, sortiert nach zuletzt aktualisiert.

GET /api/public/v1/custom-courses
Authorization: Bearer scs_live_…

Antwort

[
  {
    "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"
  }
]

Beispiel

curl -sS \
  -H "Authorization: Bearer $SCH_API_KEY" \
  https://api.limeplate.com/api/public/v1/custom-courses

Einen benutzerdefinierten Kurs abrufen

Gibt den Kurs mit seinen geordneten Elementen expandiert zurück. resolvedTitle ist der menschenlesbare Titel des zugrundeliegenden Topics oder Szenarios zum Zeitpunkt des Lesens — praktisch zum Rendern ohne einen zweiten Katalog-Lookup.

GET /api/public/v1/custom-courses/{customCourseId}
Authorization: Bearer scs_live_…

Antwort

{
  "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"
}

Beispiel

curl -sS \
  -H "Authorization: Bearer $SCH_API_KEY" \
  https://api.limeplate.com/api/public/v1/custom-courses/8b1f0c2e-3a45-4d99-9a7e-2c5e1b3a8f02

Einen benutzerdefinierten Kurs erstellen

Erstellt einen Kurs und gibt die Detailansicht zurück. Die Organisation des API-Schlüssels besitzt den neuen Kurs; der Benutzer, der den Schlüssel ausgegeben hat, wird als Ersteller aufgezeichnet.

POST /api/public/v1/custom-courses
Authorization: Bearer scs_live_…
Content-Type: application/json

Anfragetext

{
  "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 ist erforderlich und muss innerhalb der Organisation eindeutig sein. description, icon und color sind optional — color akzeptiert jeden CSS-Hex-String. items kann bei Erstellung leer sein; Sie können es später über PATCH füllen.

Antwort

Gleiche Form wie Einen benutzerdefinierten Kurs abrufen.

Beispiel

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-courses

Einen benutzerdefinierten Kurs aktualisieren

Alle Felder in der Anfrage sind optional. Übergeben Sie nur die Felder, die Sie ändern möchten. Das Senden von items ersetzt die gesamte Elementliste — zum Neuordnen senden Sie jedes Element mit neuen orderIndex-Werten erneut.

PATCH /api/public/v1/custom-courses/{customCourseId}
Authorization: Bearer scs_live_…
Content-Type: application/json

Anfragetext

{
  "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 }
  ]
}

Antwort

Das aktualisierte Detail-Objekt.

Beispiel

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-2c5e1b3a8f02

Einen benutzerdefinierten Kurs löschen

Soft-deaktiviert den Kurs. Er erscheint nicht mehr in GET /custom-courses und den Lernenden-UIs. Bestehende Zuweisungen, die auf den Kurs verweisen, verfolgen weiterhin historischen Fortschritt, werden aber nicht mehr an neue Empfänger zugestellt.

DELETE /api/public/v1/custom-courses/{customCourseId}
Authorization: Bearer scs_live_…

Antwort

{ "message": "Custom course deactivated" }

Beispiel

curl -sS -X DELETE \
  -H "Authorization: Bearer $SCH_API_KEY" \
  https://api.limeplate.com/api/public/v1/custom-courses/8b1f0c2e-3a45-4d99-9a7e-2c5e1b3a8f02

Einen benutzerdefinierten Kurs zuweisen

Ein benutzerdefinierter Kurs wird an Lernende erst dann zugestellt, wenn er zugewiesen ist. Verwenden Sie Zuweisungen mit targetType: "custom-course" und targetId gesetzt auf die ID des benutzerdefinierten Kurses:

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/assignments

Der Lernende sieht die Elemente in orderIndex-Reihenfolge. Übungs-Topics und Lern-Szenarien werden unter ihren jeweiligen Fortschritts-Endpunkten verfolgt — siehe Fortschritt.