Тенанты и брендинг
Управление школами (тенантами) суперадмином платформы, публичный брендинг для экрана входа, чтение/редактирование собственной школы и настройки видимости разделов клиентского меню.
- GET
/api/v1/public/tenantПубличный брендинг школы - POST
/api/v1/admin/tenants/Создать школу - PUT
/api/v1/admin/tenants/:idОбновить школу (суперадмин) - DELETE
/api/v1/admin/tenants/:idУдалить школу (суперадмин) - GET
/api/v1/t/tenantТекущая школа - PATCH
/api/v1/t/tenantОбновить свою школу - GET
/api/v1/t/tenant/screenshot-protectionСтатистика защиты от скриншотов - PATCH
/api/v1/t/tenant/screenshot-protectionМассово изменить защиту от скриншотов
/api/v1/public/tenantПубличный брендинг школы
Возвращает безопасную публичную проекцию школы (название, субдомен, логотип, цветовая схема) по субдомену. Используется экраном входа на {subdomain}.edumentor.kz для отрисовки бренда ДО авторизации. Авторизация не требуется.
Приостановленные, ожидающие и удалённые школы возвращают 404 — без раскрытия факта существования (защита от перечисления школ). Поле logo всегда отдаётся как готовый URL: если логотип хранится как медиа-ассет, сервер подставляет свежий presigned-URL.
Query-параметры
| Параметр | Тип | Описание |
|---|---|---|
subdomainобяз. | string | Субдомен школы.Пример: acme |
Пример запроса
curl "https://api.edumentor.kz/api/v1/public/tenant?subdomain=acme"Пример ответа
{
"success": true,
"data": {
"title": "Acme School",
"subdomain": "acme",
"logo": "https://cdn.edumentor.kz/logos/acme.png",
"color_scheme": "#2563eb"
}
}Ошибки
| Код | error | Когда |
|---|---|---|
| 400 | subdomain_required | Параметр subdomain отсутствует или пуст. |
| 404 | tenant_not_found | Школа не найдена либо неактивна (приостановлена/удалена). |
/api/v1/admin/tenants/Создать школу
Создаёт новую школу (тенант) со статусом pending. Доступно только суперадмину платформы. Slug и субдомен нормализуются к нижнему регистру и должны быть уникальны.
Настройки видимости hide_tests, hide_assignments и hide_trial_exams для новой школы создаются со значением false: самостоятельные разделы клиентского меню по умолчанию видимы.
Тело запроса
| Параметр | Тип | Описание |
|---|---|---|
titleобяз. | string | Название школы (2–255 символов). |
slugобяз. | string | Уникальный slug (латиница/цифры, 2–100).Пример: acme |
subdomainобяз. | string | Уникальный субдомен (латиница/цифры, 2–100).Пример: acme |
logoопц. | string | URL логотипа или UUID медиа-ассета (изображение). |
color_schemeопц. | string | HEX-цвет ровно из 7 символов (например #2563eb).Пример: #2563eb |
Пример запроса
curl -X POST https://api.edumentor.kz/api/v1/admin/tenants/ \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"title": "Acme School",
"slug": "acme",
"subdomain": "acme",
"color_scheme": "#2563eb"
}'Пример ответа
{
"success": true,
"data": {
"id": "8f3b1c2a-1d2e-4a5b-9c6d-7e8f9a0b1c2d",
"title": "Acme School",
"slug": "acme",
"subdomain": "acme",
"logo": null,
"color_scheme": "#2563eb",
"hide_tests": false,
"hide_assignments": false,
"hide_trial_exams": false,
"status": "pending",
"timezone": "Asia/Almaty",
"storage_cap_bytes": 5368709120,
"plan_state": "trial",
"expires_at": "2026-06-12T00:00:00Z",
"created_at": "2026-05-28T10:00:00Z",
"updated_at": "2026-05-28T10:00:00Z"
}
}Ошибки
| Код | error | Когда |
|---|---|---|
| 400 | slug or subdomain already taken | Школа с таким slug или субдоменом уже существует. |
| 401 | unauthorized | Токен отсутствует, истёк или недействителен. |
| 403 | forbidden | Недостаточно прав — требуется роль суперадмина. |
/api/v1/admin/tenants/:idОбновить школу (суперадмин)
Частично обновляет название, логотип, цветовую схему и настройки видимости разделов клиентского меню школы. Доступно только суперадмину. Slug и субдомен через этот эндпоинт не меняются — переименования каскадно затрагивают URL и интеграции.
hide_tests, hide_assignments и hide_trial_exams управляют только самостоятельными пунктами меню. Они не меняют серверные права и не блокируют API или прямые маршруты; прикреплённый контент остаётся доступен со страницы соответствующего курса или урока.
Параметры пути
| Параметр | Тип | Описание |
|---|---|---|
idобяз. | uuid | Идентификатор школы. |
Тело запроса
| Параметр | Тип | Описание |
|---|---|---|
titleопц. | string | Новое название (2–255 символов). |
logoопц. | string | URL логотипа или UUID медиа-ассета (изображение). |
color_schemeопц. | string | HEX-цвет ровно из 7 символов.Пример: #16a34a |
hide_testsопц. | boolean | true — скрыть самостоятельный пункт «Тесты» в клиентском меню; false — показывать. |
hide_assignmentsопц. | boolean | true — скрыть самостоятельный пункт «Задания» в клиентском меню; false — показывать. |
hide_trial_examsопц. | boolean | true — скрыть самостоятельный пункт «Пробные ЕНТ» в клиентском меню; false — показывать. |
Пример запроса
curl -X PUT https://api.edumentor.kz/api/v1/admin/tenants/8f3b1c2a-1d2e-4a5b-9c6d-7e8f9a0b1c2d \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"title": "Acme Academy",
"color_scheme": "#16a34a",
"hide_tests": true,
"hide_assignments": false,
"hide_trial_exams": true
}'Пример ответа
{
"success": true,
"data": {
"id": "8f3b1c2a-1d2e-4a5b-9c6d-7e8f9a0b1c2d",
"title": "Acme Academy",
"slug": "acme",
"subdomain": "acme",
"logo": null,
"color_scheme": "#16a34a",
"hide_tests": true,
"hide_assignments": false,
"hide_trial_exams": true,
"status": "active",
"plan_state": "trial",
"expires_at": "2026-06-12T00:00:00Z",
"created_at": "2026-05-28T10:00:00Z",
"updated_at": "2026-05-28T11:30:00Z"
}
}Ошибки
| Код | error | Когда |
|---|---|---|
| 400 | invalid id format | Идентификатор школы не является корректным UUID. |
| 401 | unauthorized | Токен отсутствует, истёк или недействителен. |
| 403 | forbidden | Недостаточно прав — требуется роль суперадмина. |
| 404 | tenant not found | Школа с таким идентификатором не найдена. |
/api/v1/admin/tenants/:idУдалить школу (суперадмин)
Мягко удаляет школу (проставляет deleted_at). Доступно только суперадмину. После удаления школа исчезает из публичного брендинга и недоступна для входа.
Параметры пути
| Параметр | Тип | Описание |
|---|---|---|
idобяз. | uuid | Идентификатор школы. |
Пример запроса
curl -X DELETE https://api.edumentor.kz/api/v1/admin/tenants/8f3b1c2a-1d2e-4a5b-9c6d-7e8f9a0b1c2d \
-H "Authorization: Bearer <token>"Пример ответа
{
"success": true,
"data": { "deleted": true }
}Ошибки
| Код | error | Когда |
|---|---|---|
| 400 | invalid id format | Идентификатор школы не является корректным UUID. |
| 401 | unauthorized | Токен отсутствует, истёк или недействителен. |
| 403 | forbidden | Недостаточно прав — требуется роль суперадмина. |
| 404 | tenant not found | Школа с таким идентификатором не найдена. |
/api/v1/t/tenantТекущая школа
Возвращает полную запись школы, включая настройки видимости hide_tests, hide_assignments и hide_trial_exams, в которую разрешён запрос по заголовку субдомена. Доступно любому авторизованному участнику школы. Эндпоинт открыт даже при приостановленном биллинге — чтобы клиент мог отрисовать брендинг и актуальное меню.
Значение true скрывает только самостоятельный пункт соответствующего раздела в клиентском меню. Серверные права, API и прямые маршруты не блокируются; тест, задание или пробный ЕНТ, прикреплённые к курсу, остаются доступны со страницы курса или урока.
Пример запроса
curl https://api.edumentor.kz/api/v1/t/tenant \
-H "Authorization: Bearer <token>" \
-H "X-Tenant-Subdomain: acme"Пример ответа
{
"success": true,
"data": {
"id": "8f3b1c2a-1d2e-4a5b-9c6d-7e8f9a0b1c2d",
"title": "Acme School",
"slug": "acme",
"subdomain": "acme",
"logo": "https://cdn.edumentor.kz/logos/acme.png",
"color_scheme": "#2563eb",
"hide_tests": true,
"hide_assignments": false,
"hide_trial_exams": true,
"status": "active",
"timezone": "Asia/Almaty",
"storage_cap_bytes": 5368709120,
"plan_state": "trial",
"expires_at": "2026-06-12T00:00:00Z",
"created_at": "2026-05-28T10:00:00Z",
"updated_at": "2026-05-28T10:00:00Z"
}
}Ошибки
| Код | error | Когда |
|---|---|---|
| 401 | unauthorized | Токен отсутствует, истёк или недействителен либо школа не определена. |
/api/v1/t/tenantОбновить свою школу
Тенант-админ обновляет название, логотип, цветовую схему и настройки видимости hide_tests, hide_assignments и hide_trial_exams собственной школы. Доступно только роли admin. Slug и субдомен остаются под управлением суперадмина. Требует активного биллинга.
Каждый флаг изменяется независимо; пропущенное поле сохраняет текущее значение. true скрывает самостоятельный пункт меню, false возвращает его. Это настройка навигации, а не авторизации: API и прямые маршруты остаются доступны, а прикреплённый контент открывается со страницы курса или урока.
Тело запроса
| Параметр | Тип | Описание |
|---|---|---|
titleопц. | string | Новое название (2–255 символов). |
logoопц. | string | URL логотипа или UUID медиа-ассета (изображение). |
color_schemeопц. | string | HEX-цвет ровно из 7 символов.Пример: #7c3aed |
hide_testsопц. | boolean | true — скрыть самостоятельный пункт «Тесты» в клиентском меню; false — показывать. |
hide_assignmentsопц. | boolean | true — скрыть самостоятельный пункт «Задания» в клиентском меню; false — показывать. |
hide_trial_examsопц. | boolean | true — скрыть самостоятельный пункт «Пробные ЕНТ» в клиентском меню; false — показывать. |
Пример запроса
curl -X PATCH https://api.edumentor.kz/api/v1/t/tenant \
-H "Authorization: Bearer <token>" \
-H "X-Tenant-Subdomain: acme" \
-H "Content-Type: application/json" \
-d '{
"title": "Acme Online",
"color_scheme": "#7c3aed",
"hide_tests": true,
"hide_assignments": false,
"hide_trial_exams": true
}'Пример ответа
{
"success": true,
"data": {
"id": "8f3b1c2a-1d2e-4a5b-9c6d-7e8f9a0b1c2d",
"title": "Acme Online",
"slug": "acme",
"subdomain": "acme",
"logo": "https://cdn.edumentor.kz/logos/acme.png",
"color_scheme": "#7c3aed",
"hide_tests": true,
"hide_assignments": false,
"hide_trial_exams": true,
"status": "active",
"plan_state": "trial",
"expires_at": "2026-06-12T00:00:00Z",
"created_at": "2026-05-28T10:00:00Z",
"updated_at": "2026-05-28T12:00:00Z"
}
}Ошибки
| Код | error | Когда |
|---|---|---|
| 400 | validation error | Тело запроса не прошло валидацию (например, color_scheme не из 7 символов). |
| 401 | unauthorized | Токен отсутствует, истёк или недействителен либо школа не определена. |
| 403 | forbidden | Недостаточно прав — требуется роль администратора школы. |
/api/v1/t/tenant/screenshot-protectionСтатистика защиты от скриншотов
Возвращает статистику текущей школы по урокам, тестам, заданиям и пробным ЕНТ: общее количество активных объектов, сколько из них разрешают скриншоты и сколько требуют блокировки. Доступно только администратору школы и требует активного биллинга.
screenshot_protection_enabled=false попадает в screenshots_allowed, true — в screenshots_blocked. Мягко удалённые объекты не учитываются. Сервер только отдаёт политику; фактическую блокировку скриншотов выполняет мобильное приложение.
Пример запроса
curl https://api.edumentor.kz/api/v1/t/tenant/screenshot-protection \
-H "Authorization: Bearer <token>" \
-H "X-Tenant-Subdomain: acme"Пример ответа
{
"success": true,
"data": {
"lessons": { "total": 42, "screenshots_allowed": 10, "screenshots_blocked": 32 },
"quizzes": { "total": 12, "screenshots_allowed": 12, "screenshots_blocked": 0 },
"assignments": { "total": 8, "screenshots_allowed": 3, "screenshots_blocked": 5 },
"exams": { "total": 4, "screenshots_allowed": 0, "screenshots_blocked": 4 }
}
}Ошибки
| Код | error | Когда |
|---|---|---|
| 401 | unauthorized | Токен отсутствует, истёк или недействителен либо школа не определена. |
| 403 | forbidden | Недостаточно прав — требуется роль администратора школы. |
| 403 | PAYMENT_REQUIRED | Биллинг школы неактивен. |
/api/v1/t/tenant/screenshot-protectionМассово изменить защиту от скриншотов
Устанавливает одно значение screenshot_protection_enabled для всех активных объектов выбранного типа в текущей школе. Позволяет, например, заблокировать скриншоты во всех уроках и отдельно разрешить их во всех тестах.
enabled=true включает защиту, enabled=false разрешает скриншоты. Обновляются только строки, значение которых действительно меняется; их число возвращается в updated_count. Операция не меняет updated_at контента и не затрагивает мягко удалённые объекты. В settings приходит свежая статистика по всем четырём типам.
Тело запроса
| Параметр | Тип | Описание |
|---|---|---|
content_typeобяз. | string | Тип контента: lessons, quizzes, assignments или exams.Пример: quizzes |
enabledобяз. | boolean | true — блокировать скриншоты; false — разрешить. |
Пример запроса
curl -X PATCH https://api.edumentor.kz/api/v1/t/tenant/screenshot-protection \
-H "Authorization: Bearer <token>" \
-H "X-Tenant-Subdomain: acme" \
-H "Content-Type: application/json" \
-d '{ "content_type": "quizzes", "enabled": false }'Пример ответа
{
"success": true,
"data": {
"content_type": "quizzes",
"screenshot_protection_enabled": false,
"updated_count": 7,
"settings": {
"lessons": { "total": 42, "screenshots_allowed": 10, "screenshots_blocked": 32 },
"quizzes": { "total": 12, "screenshots_allowed": 12, "screenshots_blocked": 0 },
"assignments": { "total": 8, "screenshots_allowed": 3, "screenshots_blocked": 5 },
"exams": { "total": 4, "screenshots_allowed": 0, "screenshots_blocked": 4 }
}
}
}Ошибки
| Код | error | Когда |
|---|---|---|
| 400 | validation error | Не передан enabled или content_type не входит в допустимый список. |
| 401 | unauthorized | Токен отсутствует, истёк или недействителен либо школа не определена. |
| 403 | forbidden | Недостаточно прав — требуется роль администратора школы. |
| 403 | PAYMENT_REQUIRED | Биллинг школы неактивен. |