VISH app — RUT (MIIT) timetable

The timetable of the Russian University of Transport for students and staff of every institute. The timetable of your own group and of any teacher by day and week, free MIIT rooms right now, occupancy of rooms, groups and teachers, notifications about timetable changes and an AI timetable assistant.

Institutes

The RUT (MIIT) app covers five institutes: VISH — Higher Engineering School, AGA — Civil Aviation Academy, ADKH — Road Management Academy, PISH — Advanced Engineering School “HSR Academy” and IMTK — Institute of International Transport Communications. A group’s and a teacher’s timetable are searched the same way in any of them.

What the VISH app can do
Sections
Guide

Access rights (RBAC)

Updated 28.10.2026

Access to VISH is based on roles (RBAC): each account has one role, a role has a set of rights, and API methods require certain rights. The API key and the OAuth token only narrow down the rights and never expand them. Checked with booth d1 on October 23, 2026.

Roles

The role determines what a person can do in the app. Built-in roles:

CodeRoleShort
userUserWithout additional rights; this is how everyone starts
teacherTeacherLesson notes; account is linked to teacher's card
moderatorModeratorAdministers the Institute's schedule
managerManagerCurriculum Manager
programHeadProgram ManagerEducational Program Manager
analystAnalystLooks at and uploads summary analytics, does not change anything (so far only d1)
sales, adsManagerSales, Advertising ManagerLocations, Partners and advertising campaigns (so far only d1)
inspectorThe inspectorSees everything, does not change anything (viewing mode)
developer, adminDeveloper, AdministratorAll rights
team, product, colleagueVISH team, Product, ColleagueAll rights as a developer: VISH employees, product managers and colleagues from partners. New directory rights are obtained by themselves; the right withdrawn by the administrator is not returned (so far only d1)
changelog-publisherPublishing “What's new”The role of the bot that CI publishes “What's new”; it can't do anything else

Administrators can create their own roles. The account's role and rights are indicated in response GET /auth/me (fields role and permissions).

Rights

To the right is a row of the type область:объект:действие. Several that are most often needed for integrations:

RightWhat permits
schedule:note:create, schedule:note:update, schedule:note:deleteLesson notes
schedule:lesson:create, schedule:lesson:update, schedule:lesson:deleteSchedule edit
schedule:lesson:notifyNotify everyone who has a class on their schedule
analytics:readAnalytics: /usage/export/…, /reports/institute, workload. Discoveries are written to the audit log
analytics:exportUploading analytics as a file, for example, a schedule in JSON in POST /exports (so far only d1)
students:readLists of students of groups
api:keys:self-issueIssue an API key to yourself without an application

The full list with descriptions gives GET /rbac/permissions — it requires the right to rbac:roles:read. What rights a particular method requires is described in its description in OpenAPI (/documentation).

In addition to rights, an account can be limited to groups and institutions: then, even with the right to edit, a person can only edit the schedule of their groups.

How the request is verified

  1. Who you are. The key is X-Api-Key, otherwise the token is Authorization: Bearer. There is neither one nor the other — open methods respond like everyone else, the rest are 401 AUTH_REQUIRED.
  2. Role rights. They are read anew with each request: if the role has been changed, it is valid immediately, and not when the token expires.
  3. Narrowing. The rights key is the intersection of what was noted at the time of release and what the role gives now. The OAuth token has no role rights at all: only reading from a short list of methods that calls it scope.
  4. Viewing mode. The account in the viewing mode (the “Inspector” role) can only read: any changing request is 403 VIEW_ONLY, with the key too.
  5. Checking the method. There is no necessary right — 403 FORBIDDEN, missing rights are listed in error.message.

What does 403 mean?

error.codeReasonWhat to do
FORBIDDENThe role or key does not have the required permission; it is named in the messageRequest a role with this right or issue a key with it
VIEW_ONLYAccount in the viewing modeChanges — from another account
SESSION_REQUIREDHuman-only method in the applicationDo not use an OAuth key or token
PERSON_REQUIREDThe method is for humans only, not for bots—
OAUTH_SCOPE_INSUFFICIENTThis method is not allowed for the OAuth tokenOnly methods from the scope list

Rely on error.code: the text of the message is being translated and may change.

How to get more rights

  • Role. In the application, “My role” (/role, or “Settings” → “Access”): an application for the role of a teacher or employee. It is reviewed by an employee of the institute; the decision comes by notification.
  • Key. The key can't be more than your role. If the role has received new rights, but the key has not, the reissue will not add them (the rights and the term remain the same): You need a new key, either through an application or by issuing it yourself, see API and access keys.
  • The “Login application is through VISH”. Request only the scope that are needed; the list of allowed ones is set during registration.

Which methods are open?

An open method is one that does not have requirement security in OpenAPI. The example counts such methods according to the document of the stand itself.:

// Count public and protected operations in the stand's own OpenAPI document.
const API = process.env.VISH_API ?? 'https://d1.vish-app.ru/api/v1'
const DOC = new URL('/documentation/json', API)

const response = await fetch(DOC)
if (!response.ok) throw new Error(`${DOC}: HTTP ${response.status}`)
const openapi = await response.json()

const operations = Object.entries(openapi.paths).flatMap(([path, methods]) =>
	Object.entries(methods).map(([method, operation]) => ({
		line: `${method.toUpperCase()} ${path}`,
		isPublic: !operation.security?.length,
	})),
)
const isPublic = (line) => operations.find((operation) => operation.line === line)?.isPublic

if (isPublic('GET /api/v1/groups') !== true || isPublic('GET /api/v1/auth/me') !== false) {
	throw new Error('unexpected security in the OpenAPI document')
}
const open = operations.filter((operation) => operation.isPublic && operation.line.startsWith('GET '))
console.log(`${operations.length} operations, ${open.length} public GETs, for example:`)
for (const operation of open.slice(0, 8)) console.log(' ', operation.line)

You can view your role and rights like this (with the key in the “API Key” field):

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

Verified: 2026-10, PWA aa337c45, platform bff65fce._