Важно: после запроса одноразового кода на вашу почту придёт письмо. Оно может попасть в папку «Спам». Проверьте «Спам», найдите письмо от api@mgkeit.space и нажмите «Не спам», чтобы получать письма дальше.
Для разработчиков
Как начать, авторизация, лимиты и подробные описания методов с примерами.
Базовый URL https://api.mgkeit.space
, префикс /api/v1
.
Начало работы
- Запросите одноразовый код при помощи метода POST /auth/request-otp (6 цифр, действует 10 минут).
- Код нужен для получения токена при помощи метода POST /auth/verify-otp - в ответ вернётся строка вида mgk_live_....
- При использование API передавайте заголовок Authorization: Bearer <token> или X-API-Key: <token>.
Аутентификация
Тело | Описание |
---|---|
Заголовок |
Authorization: Bearer mgk_live_...
или
X-API-Key: mgk_live_...
|
Scopes | read:schedules |
Формат ошибок | {"error":{"code","message","details","request_id"}} |
cURL - при помощи Authorization: Bearer
curl -s "https://api.mgkeit.space/api/v1/auth/me" \
-H "Authorization: Bearer mgk_live_..."
cURL - при помощи X-API-Key
curl -s "https://api.mgkeit.space/api/v1/auth/me" \
-H "X-API-Key: mgk_live_..."
Лимиты и кэш
- С ключом: 100/мин
- При
429
вернётся заголовокRetry-After
/buildings
,/groups
,/timetable
,/replacements
отдаютETag
и поддерживаютIf-None-Match
Формат и типы ошибок
{
"error": {
"code": "invalid_param | rate_limited | "401" | "404" | "500"",
"message": "Текст ошибки",
"details": { подробная ошибка },
"request_id": "94062d0d..."
}
}
HTTP | Error Code | Когда |
---|---|---|
400 | "400" | Неверный/просроченный OTP в /auth/verify-otp |
401 | "401" | Недействительный токен |
404 | "404" | Ресурс не найден |
422 | invalid_param | Ошибка валидации |
429 | rate_limited | Превышен лимит |
500 | "500" | Внутренняя ошибка |
/api/v1/auth/request-otp
без авторизации
Отправляет одноразовый код (6 цифр) на указанный Email. Код действует 10 минут.
Ограничения | Описание |
---|---|
Лимит по ключу | 5 запросов/минуту |
Антиспам на адрес | не чаще 1 запроса/мин. на один Email |
Тело запроса
{ "email": "you@example.com" }
Ответ (200)
{ "status": "ok" }
Ошибки
- 422 - некорректный Email.
- 429 - частые запросы (общее 5/мин или чаще 1/мин на один адрес).
- 500 - внутренняя ошибка.
curl -s -X POST "https://api.mgkeit.space/api/v1/auth/request-otp" \
-H "Content-Type: application/json" \
-d '{"email":"you@example.com"}'
import requests
r = requests.post('https://api.mgkeit.space/api/v1/auth/request-otp', json={'email':'you@example.com'})
print(r.json())
/api/v1/auth/verify-otp
без авторизации
Проверяет OTP и создаёт API-ключ. Возвращает полный токен с префиксом mgk_live_.
Ограничения | Описание |
---|---|
Лимит | 10 запросов/час |
Срок действия OTP | 10 минут |
Тело запроса
{ "email":"you@example.com", "code":"123456" }
Ответ (200)
{
"token": "mgk_live_xxx",
"token_prefix": "mgk_live_",
"created_at": "2025-09-07",
"scopes": ["read:schedules"]
}
Ошибки
- 400 - неверный/просроченный код.
- 422 - ошибки валидации тела.
- 429 - превышен лимит (10/час).
curl -s -X POST "https://api.mgkeit.space/api/v1/auth/verify-otp" \
-H "Content-Type: application/json" \
-d '{"email":"you@example.com","code":"123456"}'
import requests
r = requests.post('https://api.mgkeit.space/api/v1/auth/verify-otp', json={'email':'you@example.com','code':'123456'})
print(r.json())
/api/v1/auth/me
без авторизации
Возвращает информацию о текущем API-ключе (владельце и параметрах лимитов).
Ограничения | Описание |
---|---|
Лимит | Индивидуальный для ключа (обычно 100/мин). |
Тело запроса
{ "TOKEN": "mgk_live_..." }
Ответ (200)
{
"_id": "XXXXXXXXXXXXXXXXXXXXXXX",
"email": "you@example.com",
"active": true,
"scopes": ["read:schedules"],
"ratelimit": "100/minute",
"created_at": "2025-09-09T10:00:00+00:00",
"last_used_at": "2025-09-09T19:05:00+00:00"
}
Ошибки
- 422 - некорректный Email.
- 429 - частые запросы (общее 5/мин или чаще 1/мин на один адрес).
- 500 - внутренняя ошибка.
curl -s -X POST "https://api.mgkeit.space/api/v1/auth/me" \
-H "Authorization: Bearer mgk_live_xxx" | jq
import requests
r = requests.post("https://api.mgkeit.space/api/v1/auth/me", headers={"Authorization": "Bearer mgk_live_xxx"})
print(r.json())
/api/v1/buildings
Bearer
Возвращает список всех корпусов.
Метод поддерживает кэширование по ETag
.
- Аутентификация при помощи заголовока
Authorization: Bearer mgk_live_...
- Кэш с использованием
ETag
из ответа. Передавайте его вIf-None-Match
- при отсутствии изменений сервер вернёт304 Not Modified
.
Кэш | Заголовки |
---|---|
ETag + 304 |
ETag
,
Cache-Control: public, max-age=60
,
If-None-Match
|
cURL
BASE="https://api.mgkeit.space"
TOKEN="mgk_live_xxx"
# Простой запрос
curl -i -X POST "$BASE/api/v1/buildings" \
-H "Authorization: Bearer $TOKEN"
# Повторный запрос с кэшем:
# Подставьте тот ETag, который вернул сервер ранее.
ETAG="<ETAG_ИЗ_ПРЕДЫДУЩЕГО_ОТВЕТА>"
curl -i -X POST "$BASE/api/v1/buildings" \
-H "Authorization: Bearer $TOKEN" \
-H "If-None-Match: $ETAG" # -> 304 Not Modified, если список не менялся
Ответ (200)
{
"buildings": [
"Судостроительная",
"Коломенская",
"Академика Миллионщикова",
"Бирюлёво"
]
}
Ошибки
- 401 - отсутствует или неверный Bearer-токен.
- 422 - некорректное тело запроса (валидация JSON).
- 304 - данные не изменились (при использовании
If-None-Match
). - 429 - превышен лимит запросов.
/api/v1/groups
Bearer
Возвращает список всех групп для выбранного корпуса. Метод поддерживает кэширование по ETag
Тело (JSON) | Тип | Обяз. | По умолч. | Описание |
---|---|---|---|---|
building |
string | да | - | Название корпуса. Рекомендуем получать из /api/v1/buildings . |
limit |
int [1-500] | нет | 100 | Размер страницы. |
offset |
int ≥ 0 | нет | 0 | Смещение (для пагинации). |
Кэш | Заголовки |
---|---|
ETag + 304 |
ETag
,
Cache-Control: public, max-age=60
,
If-None-Match
При повторном запросе с тем же телом можно отправить
If-None-Match - если данные не изменились, придёт 304 Not Modified.
|
cURL
curl -s -X POST "https://api.mgkeit.space/api/v1/groups" \
-H "Authorization: Bearer mgk_live_xxx" \
-H "Content-Type: application/json" \
-d '{"building":"Судостроительная","limit":50,"offset":0}' | jq
# Следующая страница
curl -s -X POST "https://api.mgkeit.space/api/v1/groups" \
-H "Authorization: Bearer mgk_live_xxx" \
-H "Content-Type: application/json" \
-d '{"building":"Судостроительная","limit":50,"offset":50}' | jq
# Повторный запрос с кэшем
curl -i -X POST "https://api.mgkeit.space/api/v1/groups" \
-H "Authorization: Bearer mgk_live_xxx" \
-H "Content-Type: application/json" \
-H 'If-None-Match: W/"abc123"' \
-d '{"building":"Судостроительная","limit":50,"offset":0}' # -> 304 Not Modified
Ответ (200)
{
"building": "Судостроительная",
"total": 123,
"limit": 50,
"offset": 0,
"groups": ["1КС-1-11-25", "1ОЗИП-1-11-25 (ОЗФ)", "..."]
}
Ошибки
- 401 - отсутствует или неверный Bearer-токен.
- 422 - некорректное тело запроса (валидация JSON).
- 304 - данные не изменились (при использовании
If-None-Match
). - 429 - превышен лимит запросов.
/api/v1/replacements
Bearer
Возвращает список замен за указанную дату. Можно дополнительно фильтровать по корпусу и/или группе.
Тело (JSON) | Тип | Обяз. | По умолч. | Описание |
---|---|---|---|---|
date |
string (YYYY-MM-DD) | да | - | Дата замен в формате ISO, например 2025-09-09 . Часовой пояс - Europe/Moscow. |
building |
string | нет | - | Фильтр по корпусу. Если не указан - вернутся замены по всем корпусам за дату. |
group |
string | нет | - | Фильтр по группе. |
Кэш | Заголовки |
---|---|
ETag + 304 |
ETag
,
Cache-Control: public, max-age=60
,
If-None-Match
При повторном запросе с тем же телом можно отправить
If-None-Match -
если данные не изменились, придёт 304 Not Modified.
|
cURL
# Все замены по дате
curl -s -X POST "https://api.mgkeit.space/api/v1/replacements" \
-H "Authorization: Bearer mgk_live_xxx" \
-H "Content-Type: application/json" \
-d '{"date":"2025-09-09"}' | jq
# Фильтр по корпусу
curl -s -X POST "https://api.mgkeit.space/api/v1/replacements" \
-H "Authorization: Bearer mgk_live_xxx" \
-H "Content-Type: application/json" \
-d '{"date":"2025-09-09","building":"Академика Миллионщикова"}' | jq
# Фильтр по группе
curl -s -X POST "https://api.mgkeit.space/api/v1/replacements" \
-H "Authorization: Bearer mgk_live_xxx" \
-H "Content-Type: application/json" \
-d '{"date":"2025-09-09","group":"1ИП-3-25"}' | jq
# Повторный запрос с кэшем
curl -i -X POST "https://api.mgkeit.space/api/v1/replacements" \
-H "Authorization: Bearer mgk_live_xxx" \
-H "Content-Type: application/json" \
-H 'If-None-Match: W/"abc123"' \
-d '{"date":"2025-09-09"}' # -> 304 Not Modified
Ответ (200)
{
"meta": {
"version": "1.0",
"date": "2025-09-09",
"building": "Академика Миллионщикова",
"count": 3
},
"items": [
{
"group": "2ИП-4-24",
"lessons": [3, 4],
"teacher_from": "Геворгян А.А.",
"teacher_to": "Ахмерова Н.Д.",
"room_schedule": "411",
"room_replace": null
},
{
"group": "1РКИ-3-25",
"lessons": [3],
"teacher_from": "Вакансия",
"teacher_to": "Мызников В.И.",
"room_schedule": "320",
"room_replace": "102"
},
{
"group": "1ИП-6-25",
"lessons": [5, 6],
"teacher_from": "Маликова А.Р.",
"teacher_to": "Горбунов О.В.",
"room_schedule": "307",
"room_replace": null
}
]
}
Примечания
- Совмещение фильтров. Если указаны и
building
иgroup
- применяются оба фильтра. - Нумерация занятий. Поле
lessons
содержит номера занятий по дню. - Кэширование. Ответ кэшируется заголовками
ETag
/Cache-Control
; можно использоватьIf-None-Match
для экономии трафика.
Ошибки
- 401 - отсутствует или неверный Bearer-токен.
- 422 - некорректное тело запроса (например, опечатка в ключе
date
). - 304 - данные не изменились (при использовании
If-None-Match
). - 429 - превышен лимит запросов.
/api/v1/timetable
Bearer
Возвращает расписание группы на выбранный день или на «рабочие» дни корпуса (если день не указан и для корпуса задано ограничение).
Парные пары уже объединены и имеют итоговое время в полях start
/end
.
Тело (JSON) | Тип | Обяз. | По умолч. | Описание |
---|---|---|---|---|
group |
string | да | - | Название группы, например 1ОЗИП-1-11-25 (ОЗФ) или 1КС-1-11-25 . |
building |
string | нет | - | Название корпуса, например если одинаковые названия групп встречаются в разных корпусах. Если не указан - выбирается лучший матч автоматически. |
week |
"current"|"even"|"odd" |
нет | "current" |
Выбранная неделя для отдачи. Текущая, чётная, нечётная |
day |
int (0-5) | нет | - | День недели. 0 - Пн, 1 - Вт, 2 - Ср, 3 - Чт, 4 - Пт, 5 - Сб. Если не указан - вернутся только «разрешённые» дни для корпуса. |
Кэш | Заголовки |
---|---|
ETag + 304 |
ETag
,
Cache-Control: public, max-age=60
,
If-None-Match
При повторном запросе с тем же телом можно отправить
If-None-Match - если данные не изменились, придёт 304 Not Modified.
|
cURL
# Минимальный запрос (корпус определится автоматически)
curl -s -X POST "https://api.mgkeit.space/api/v1/timetable" \
-H "Authorization: Bearer mgk_live_xxx" \
-H "Content-Type: application/json" \
-d '{"group":"1ОЗИП-1-11-25 (ОЗФ)"}' | jq
# С указанием корпуса, недели и дня (среда)
curl -s -X POST "https://api.mgkeit.space/api/v1/timetable" \
-H "Authorization: Bearer mgk_live_xxx" \
-H "Content-Type: application/json" \
-d '{"group":"1ОЗИП-1-11-25 (ОЗФ)","building":"Академика Миллионщикова","week":"odd","day":2}' | jq
# Повторный запрос с кэшем
curl -i -X POST "https://api.mgkeit.space/api/v1/timetable" \
-H "Authorization: Bearer mgk_live_xxx" \
-H "Content-Type: application/json" \
-H 'If-None-Match: W/"abc123"' \
-d '{"group":"1ОЗИП-1-11-25 (ОЗФ)","day":2}' # -> 304 Not Modified
Ответ (200)
{
"meta": {
"version": "1.0",
"generated_at": "2025-09-09T19:04:24.941351+00:00",
"group": "1ОЗИП-1-11-25 (ОЗФ)",
"building": "Академика Миллионщикова",
"week": "even",
"current_week": "even",
"day_filter": 2
},
"data": [
{
"day_index": 2,
"day_name": "Среда",
"units": [
{
"kind": "pair",
"number": 1,
"display_number": 1,
"start": "15:50",
"end": "17:20",
"subject": "ОП.02 Информационные технологии / Адаптивные информационные и коммуникационные технологии",
"teacher": "Вакансия часы ОЗ",
"room": "академика Миллионщикова. каб: 321",
"subgroup": "",
"source": "base"
},
{
"kind": "pair",
"number": 2,
"display_number": 2,
"start": "17:30",
"end": "19:00",
"subject": "ОГСЭ.02 История",
"teacher": "Вакансия часы ОЗ",
"room": "академика Миллионщикова. каб: 305",
"subgroup": "",
"source": "base"
}
]
}
]
}
Как выбирается корпус и день
- Группа. Ищем строгое совпадение с припиской в скобках, затем «база+приписка», затем «база без приписки». Если задан
building
, он учитывается в поиске. - Корпус. Если
building
не указан, выбирается документ с непустым корпусом и самой поздней датой обновления. - Дни. Если
day
не указан, возвращаются только «разрешённые» дни для выбранного корпуса. - Склейка пар. Две соседние одинаковые записи (предмет/преподаватель/аудитория/подгруппа) объединяются в
kind="pair"
с суммарным временем.
Ошибки
- 401 - отсутствует или неверный Bearer-токен.
- 422 - некорректное тело запроса (валидация JSON).
- 304 - данные не изменились (при использовании
If-None-Match
). - 429 - превышен лимит запросов.