Справочник API
Подключение внешнего редактора
Безопасный Bearer-токен для загрузки материалов из CLI, серверного скрипта или настольного редактора.
Маршруты раздела
| Метод | Маршрут | Доступ | Назначение |
|---|---|---|---|
GET |
/api/account/api-tokens |
Нужна сессия преподавателя | Получить список своих подключений и курсов для привязки. |
POST |
/api/account/api-tokens |
Нужна сессия преподавателя | Создать токен; секрет возвращается только один раз. |
DELETE |
/api/account/api-tokens/{id} |
Нужна сессия преподавателя | Немедленно отозвать своё подключение. |
Где создать токен
Откройте Настройки → API-токены (/profile/security?section=api). Укажите название подключения, выберите курсы, права и срок действия. Секрет показывается один раз: Latorn хранит только его SHA-256-хеш.
Для каждого редактора или устройства лучше создавать отдельный токен. Тогда одно подключение можно отозвать, не останавливая остальные.
Авторизация запроса
export LATORN_API_TOKEN='latorn_pat_…'
curl https://latorn.ru/api/courses?page=1 \
-H "Authorization: Bearer $LATORN_API_TOKEN"
const baseUrl = "https://latorn.ru";
const token = process.env.LATORN_API_TOKEN;
async function latorn(path: string, init: RequestInit = {}) {
const response = await fetch(baseUrl + path, {
...init,
headers: { ...init.headers, Authorization: `Bearer ${token}` },
});
if (!response.ok) {
const payload = await response.json().catch(() => null);
throw new Error(payload?.error?.message ?? `HTTP ${response.status}`);
}
return response;
}
Если заголовок Authorization присутствует, но токен неверен, истёк или отозван, Latorn возвращает 401 и не подменяет его cookie-сессией.
Права токена
COURSES_READ— читать сведения о выбранных курсах;COURSES_CREATE— создавать черновики курсов;COURSES_WRITE— менять настройки курса;COURSES_PUBLISH— запросить одноразовую ссылку на публикацию; решение подтверждает человек внутри Latorn;CONTENT_READ— читать секции, уроки и преподавательские блоки шагов;CONTENT_WRITE— создавать, менять и удалять секции, уроки и шаги;MEDIA_WRITE— загружать обложки, изображения и аудио;REVENUE_READ— читать только агрегированную аналитику продаж без покупателей и ID операций.
Токен — только верхняя граница доступа. При каждом запросе Latorn заново проверяет владельца или роль в команде курса. Если преподавателя удалили из команды, старый токен сразу перестанет работать. Даже расширенная роль аккаунта не даёт токену автоматический доступ к чужим курсам.
Токен не даёт управлять платежами, возвратами, выплатами, рассылками, пользователями или настройками аккаунта. REVENUE_READ открывает только агрегированную аналитику выбранных курсов. Прямое изменение статуса публикации по Bearer запрещено: COURSES_PUBLISH создаёт запрос, который владелец токена подтверждает в Latorn. Удаление целого курса через токен отключено.
Последовательность импорта
- Получите курс через
GET /api/coursesили создайте черновик черезPOST /api/courses. - Создайте секцию через
POST /api/sections. - Создайте урок через
POST /api/lessons. - Загрузите файлы, если они нужны.
- Создайте шаги через
POST /api/steps.
Новый курс, созданный токеном с правом COURSES_CREATE, автоматически добавляется в область действия этого токена.
Загрузка файла
Для Bearer-токена загрузка обязательно содержит courseId. Не задавайте Content-Type вручную: FormData сам добавит boundary.
const form = new FormData();
form.set("courseId", courseId);
form.set("file", file);
await latorn("/api/uploads/lesson-media", { method: "POST", body: form });
Обложки и изображения урока принимают PNG, JPEG, WebP и SVG. SVG ограничен 2 МБ, проверяется на активные и внешние конструкции и сохраняется только как PNG; исходный XML не публикуется. Аватары и вложения на проверку SVG не принимают.
Ошибки доступа
INVALID_API_TOKEN— формат или секрет неверен;API_TOKEN_EXPIRED— срок действия закончился;API_TOKEN_REVOKED— подключение отозвано;API_TOKEN_SCOPE_REQUIRED— не выдано нужное право;COURSE_ACCESS_DENIEDили404— курс не привязан либо текущие права пользователя изменились.
Персональный токен рассчитан на backend, CLI и desktop. Для браузерного редактора на другом домене используйте backend-proxy и храните секрет только на сервере.
