Пользовательские курсы
Пользовательский курс — это ориентированная на учащегося кураторская последовательность тем и сценариев, взятых из каталога контента SecureCodingHub. После создания пользовательский курс может быть назначен так же, как встроенная тема или категория. Требует custom-courses:read или custom-courses:write в зависимости от глагола.
Конечные точки
| Метод | Путь | Область действия | Назначение |
|---|---|---|---|
GET | /custom-courses | custom-courses:read | Список всех пользовательских курсов в организации. |
GET | /custom-courses/{'{'}id{'}'} | custom-courses:read | Получить один пользовательский курс с его упорядоченными элементами. |
POST | /custom-courses | custom-courses:write | Создать новый пользовательский курс. |
PATCH | /custom-courses/{'{'}id{'}'} | custom-courses:write | Обновить метаданные и/или заменить список элементов. |
DELETE | /custom-courses/{'{'}id{'}'} | custom-courses:write | Мягко деактивировать пользовательский курс. |
Все пути относительны к https://api.limeplate.com/api/public/v1.
Модель элемента
Каждый пользовательский курс содержит упорядоченный список элементы. Каждый элемент — это ссылка на тему или сценарий из каталога — см. Каталог контента для идентификаторов.
| Поле | Тип | Значение |
|---|---|---|
itemType | string | Либо "topic" (практическая тема, например sql-injection), либо "scenario" (сценарий learn-режима). |
itemId | string | Каталожный id темы или сценария. |
orderIndex | integer | Порядок отображения с нуля в UI учащегося. Меньшие значения появляются первыми. |
На PATCH опустите поле items, чтобы оставить элементы нетронутыми, или отправьте полный список замены для перезаписи. Частичного обновления элементов нет — отправьте всю последовательность повторно в том порядке, в котором Вы хотите её сохранить.
Список пользовательских курсов
Возвращает одну запись на активный пользовательский курс в организации, отсортированную по самым недавно обновлённым.
GET /api/public/v1/custom-courses
Authorization: Bearer scs_live_…Ответ
[
{
"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"
}
]Пример
curl -sS \
-H "Authorization: Bearer $SCH_API_KEY" \
https://api.limeplate.com/api/public/v1/custom-coursesПолучить пользовательский курс
Возвращает курс с раскрытыми упорядоченными элементами. resolvedTitle — это читаемый заголовок основной темы или сценария на момент чтения — удобно для рендеринга без второго поиска в каталоге.
GET /api/public/v1/custom-courses/{customCourseId}
Authorization: Bearer scs_live_…Ответ
{
"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"
}Пример
curl -sS \
-H "Authorization: Bearer $SCH_API_KEY" \
https://api.limeplate.com/api/public/v1/custom-courses/8b1f0c2e-3a45-4d99-9a7e-2c5e1b3a8f02Создать пользовательский курс
Создаёт курс и возвращает детальное представление. Организация API-ключа владеет новым курсом; пользователь, выпустивший ключ, записывается как создатель.
POST /api/public/v1/custom-courses
Authorization: Bearer scs_live_…
Content-Type: application/jsonТело запроса
{
"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 обязательно и должно быть уникальным в пределах организации. description, icon и color опциональны — color принимает любую CSS hex-строку. items может быть пустым при создании; Вы можете заполнить его позже через PATCH.
Ответ
Та же форма, что и Получить пользовательский курс.
Пример
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Обновить пользовательский курс
Все поля в запросе опциональны. Передайте только те поля, которые Вы хотите изменить. Отправка items заменяет весь список элементов — для переупорядочивания отправьте повторно каждый элемент с новыми значениями orderIndex.
PATCH /api/public/v1/custom-courses/{customCourseId}
Authorization: Bearer scs_live_…
Content-Type: application/jsonТело запроса
{
"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 }
]
}Ответ
Обновлённый детальный объект.
Пример
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Удалить пользовательский курс
Мягко деактивирует курс. Он перестаёт появляться в GET /custom-courses и интерфейсах учащегося. Существующие задания, которые ссылались на курс, продолжают отслеживать исторический прогресс, но не доставляются новым получателям.
DELETE /api/public/v1/custom-courses/{customCourseId}
Authorization: Bearer scs_live_…Ответ
{ "message": "Custom course deactivated" }Пример
curl -sS -X DELETE \
-H "Authorization: Bearer $SCH_API_KEY" \
https://api.limeplate.com/api/public/v1/custom-courses/8b1f0c2e-3a45-4d99-9a7e-2c5e1b3a8f02Назначение пользовательского курса
Пользовательский курс не доставляется учащимся, пока он не назначен. Используйте Задания с targetType: "custom-course" и targetId, установленными в id пользовательского курса:
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Учащийся видит элементы в порядке orderIndex. Практические темы и учебные сценарии отслеживаются под их соответствующими эндпоинтами прогресса — см. Прогресс.