Notes API
Updated 27.10.2026
There are two types of notes in VISH: lesson notes that the teacher or staff member leaves for the whole group, and personal notes that the person writes only for themselves. They are available in different ways through the API. Checked with booth d1 on October 23, 2026; the methods of this page are also available on production.
Notes for the lesson
Material for the group: homework, link, file. Anyone who sees the lesson can read them — without a key.
| Method | What does | Who can |
|---|---|---|
GET /schedule/{id}/notes | Notes of one lesson | All |
POST /schedule/{id}/notes | Add a note | Right schedule:note:create |
POST /schedule/{id}/notes/attachments | Upload a file for a note (up to 10 MB, one at a time) | Right schedule:note:create |
PATCH /schedule/notes/{noteId} | Edit Note | Right schedule:note:update |
DELETE /schedule/notes/{noteId} | Delete Note | Right schedule:note:delete |
Notes: id, lessonId, content (Markdown as written), contentL10n (translations), attachments, author, createdAt, updatedAt. You can see how many notes the class has in the schedule itself — field notesCount.
You can write notes with a key: the teacher's key with the marked rights schedule:note:* acts as the teacher himself. The file is first uploaded as a separate request, and what the download returned is sent to the note. Images are saved in WebP; PDF, office documents, and text are saved as download files; others are not accepted (415).
Such a request publishes a real note that the whole group will see. Try it in your group's class on d1.:
curl -X POST "$VISH_API/schedule/$LESSON_ID/notes" \
-H "X-Api-Key: $VISH_API_KEY" -H "Content-Type: application/json" \
-d '{"content": "Homework: exercises 1–5, page 42"}'The “Login token after VISH” with a resolution of notes:read reads only GET /schedule/{id}/notes.
Personal notes
A note that only its author sees.: GET, POST /personal-notes, GET, PATCH, DELETE /personal-notes/{noteId} and uploading files POST /personal-notes/attachments.
To verify this with your key, the request does not change anything and should be rejected.:
// Personal notes belong to the person in the app: a key is refused with 403 SESSION_REQUIRED.
const API = process.env.VISH_API ?? 'https://d1.vish-app.ru/api/v1'
const KEY = process.env.VISH_API_KEY
if (!KEY) throw new Error('set VISH_API_KEY')
const response = await fetch(`${API}/personal-notes`, { headers: { 'X-Api-Key': KEY } })
const body = await response.json()
if (response.status !== 403 || body.error?.code !== 'SESSION_REQUIRED') {
throw new Error(`expected 403 SESSION_REQUIRED, got ${response.status} ${JSON.stringify(body)}`)
}
console.log('refused as designed:', body.error.code)Example: notes for the group's classes
The example finds the group's classes with notes (notesCount > 0) and reads the notes of the first one. The group is VISH_GROUP, with ШАД-111 by default.
// Find a group's lessons that carry notes and read the notes of one; no key needed.
const API = process.env.VISH_API ?? 'https://d1.vish-app.ru/api/v1'
const GROUP = process.env.VISH_GROUP ?? 'ШАД-111'
const get = async (path) => {
const response = await fetch(`${API}${path}`)
if (!response.ok) throw new Error(`${path}: HTTP ${response.status}`)
return response.json()
}
const lessons = (await get(`/schedule?group=${encodeURIComponent(GROUP)}&all=1`)).list
if (lessons.length === 0) throw new Error(`no lessons for ${GROUP}`)
const withNotes = lessons.filter((lesson) => lesson.notesCount > 0)
const lesson = withNotes[0] ?? lessons[0]
const notes = await get(`/schedule/${lesson.id}/notes`)
if (!Array.isArray(notes.list) || notes.list.some((note) => note.lessonId !== lesson.id)) {
throw new Error('unexpected notes answer')
}
console.log(`${GROUP}: ${lessons.length} lessons, ${withNotes.length} with notes`)
console.log(`${lesson.date.slice(0, 10)} ${lesson.subject.ru}: ${notes.list.length} notes`)
for (const note of notes.list) console.log('-', note.content.slice(0, 80), `(${note.attachments.length} files)`)Reactions
GET /schedule/{id}/reactions — reactions to the lesson, open to everyone; GET /reactions/config — what reactions are allowed. You can set or remove your reaction (POST /schedule/{id}/reactions) only after logging in — with the key too, you don't need any special rights.
To try
Substitute id classes out of GET /schedule:
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._