Timetable API
Updated 27.10.2026
The schedule is the main thing that gives API VISH away: classes for groups and teachers RUT (MIIT) with classrooms, types of classes, cancellations and edits. Anyone can read it, without a key. Checked with booth d1 on October 23, 2026; the methods of this page are also available on production.
Methods
Lessons: GET /schedule
The main method. Without filters, he gives all classes on a page-by-page basis; usually he is asked about one group or one teacher per period.
| Параметр | Что значит |
|---|---|
group | Код группы ровно как в /groups, например ШАД-111. Тогда в ответе есть и поле group |
groupId | The same for the group ID |
teacher, teacherId | Full name of the teacher (in Russian) or his identifier |
scope | With a group and a teacher together: group (by default) — only this teacher's classes in this group, all — the entire teacher's schedule |
date | One day, ГГГГ-ММ-ДД; replaces dateFrom and dateTo |
dateFrom, dateTo | Period; by default — from the beginning of the semester to the end of schedule |
lessonType | lecture, practice, lab, seminar, consultation, exam, credit, other |
room | Audience, for example 8412 |
status | scheduled or cancelled |
page, perPage, all | Page output (by default, 20 per page, no more than 200; all=1 — up to 2000 at once) |
What does the class have?: id, date, startAt, endAt, number ( the number of the pair, null outside the call grid), subject (name in three languages), lessonType (object: code from the list above and label in three languages), room and roomLabel (name if the audience is named with words), subgroup, status, weekParity (1 or 2), teachers, groups, extraGroups (groups in the same class that are not in VISH), notesCount, reactions, isSubscribed and subscribersCount (subscriptions to the class), isOverridden (the class was edited at the institute), updatedAt.
What else is there
GET /app-config— semester (semester.startDate,endDate,scheduleEndsAt), current week and its parity (currentWeek.number,currentWeek.parity), call grid (schedule.lessonSlots).GET /schedule/changes— what has recently changed in the schedule of the group or teacher (groupIdorteacherId);period=weeks— changes in classes this and next week. Convenient for the survey — see Notifications and calendars.GET /session— exams, tests, and consultations with a group or teacher;hasUpcoming— whether there is an exam or test in the next 30 days.GET /schedule/filters,GET /schedule/lesson-types,GET /schedule/subjects,GET /schedule/courses— values for filters: types of classes, subjects, courses.GET /schedule/export.pdf— print schedule (same filters), no more than 10 requests per minute.GET /calendar/schedule.icsandGET /session.icsare the same in calendar format.
Only employees with schedule:lesson:* rights can change the schedule (POST, PATCH, DELETE to /schedule…), and only in their groups and institutes.
Example: group week
The example takes the group's classes for the current week and compares the time of each pair with a call grid of /app-config. The group is set to variable VISH_GROUP (default is ШАД-111).
// This week's lessons of one group, checked against the bell schedule.
const API = process.env.VISH_API ?? 'https://d1.vish-app.ru/api/v1'
const GROUP = process.env.VISH_GROUP ?? 'ШАД-111'
const get = async (path, params = {}) => {
const url = new URL(`${API}${path}`)
for (const [name, value] of Object.entries(params)) url.searchParams.set(name, String(value))
const response = await fetch(url)
if (!response.ok) throw new Error(`${url}: HTTP ${response.status}`)
return response.json()
}
// Monday to Sunday of the current week, on the Moscow calendar.
const moscowToday = new Date(Date.now() + 3 * 60 * 60 * 1000)
const monday = new Date(moscowToday)
monday.setUTCDate(moscowToday.getUTCDate() - ((moscowToday.getUTCDay() + 6) % 7))
const sunday = new Date(monday)
sunday.setUTCDate(monday.getUTCDate() + 6)
const day = (date) => date.toISOString().slice(0, 10)
const config = await get('/app-config')
const slots = new Map(config.schedule.lessonSlots.map((slot) => [slot.number, slot]))
const week = await get('/schedule', { group: GROUP, dateFrom: day(monday), dateTo: day(sunday), all: 1 })
if (week.group?.name !== GROUP) throw new Error(`group ${GROUP} not found`)
console.log(`${GROUP}, week ${config.currentWeek.number} (parity ${config.currentWeek.parity}): ${week.list.length} lessons`)
for (const lesson of week.list) {
// Wall-clock Moscow time in a UTC field: read the digits as they are.
const start = lesson.startAt.slice(11, 16)
const slot = slots.get(lesson.number)
if (slot && slot.startTime !== start) throw new Error(`lesson ${lesson.id} starts ${start}, pair ${lesson.number} at ${slot.startTime}`)
const cancelled = lesson.status === 'cancelled' ? ' (cancelled)' : ''
console.log(`${lesson.date.slice(0, 10)} ${start} ${lesson.subject.ru} — ${lesson.room ?? 'no room'}${cancelled}`)
}To try
Try the request
Only methods with a lock need a key. It lives on this page only: it is never stored, goes out only as a header of this request and is forgotten when you leave. Where to get a key
If something is wrong
- Empty
list— the group has no classes during this period (holidays, session). - 404
NOT_FOUND— there is no group with this code. The code must matchnameof the/groupscharacters (Cyrillic, hyphen); you can find it in/groups?search=…. - 400
VALIDATION_ERRORis an incorrect parameter format;error.details.issuessays which one. - 400 at
all=1— more than 2000 classes are filtered out: narrow down the period or go through the pages.
Verified: 2026-10, PWA aa337c45, platform bff65fce._