Authentication: API keys and OAuth
Updated 27.10.2026
In API VISH, there are three ways to access the method: without logging in, with an API key, and with an OAuth token from “Logging in through VISH”. Which one to choose depends on whose data you are reading and who is running the program. Checked with booth d1 on October 23, 2026.
What to choose
| Without login | API key | OAuth token (“Login via VISH”) | |
|---|---|---|---|
| What is | Open data for: schedules, groups, teachers, classrooms | Your script, bot, upload, dashboard | Your website or application that includes other people |
| On behalf of whom | On behalf of no one | On your behalf, within the rights of the key | On behalf of the logged-in person, with his consent |
| How is | transmitted — | Header X-Api-Key: vish_… | Header Authorization: Bearer … |
| What is allowed | Public methods GET | Everything that is allowed by the key and your role | Read-only from the short list of methods |
| Срок | — | До даты в ключе (выпущенный себе — не дольше 730 дней) | 15 минут, дальше обновление токеном refresh |
| Where there is | d1 and production | d1 and production | So far only d1 |
If you don't need to read anything personal, do without logging in: fewer secrets, fewer risks.
API Key
The key is obtained on the “Developer page in the application. For” more information, see the API and Access Keys page. The key starts with vish_ and is passed in a separate header.:
curl -H "X-Api-Key: $VISH_API_KEY" "$VISH_API/auth/me"
- A request with a key is a request on your behalf, but only within the rights specified when issuing the key. What is not in the set, the key will be refused, even if you have the right to do so yourself. If your role's rights are later reduced, the key also loses them — immediately, from the next request.
- The key is in the header, never in the address: addresses end up in logs, browser history, and header
Referer. - If both the key and
Authorizationare in the request, the key is counted. - Some methods are only for the person in the application: your key, personal notes, consent, account deletion. You can't call them with a key — the answer is 403
SESSION_REQUIRED. - Reissue the key that appeared somewhere with the “Reissue” button on the “developer” page: the old line stops working immediately.
Check the key and see what it is allowed to do:
// Who the key acts as, and which permissions it carries.
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}/auth/me`, { headers: { 'X-Api-Key': KEY } })
const me = await response.json()
if (!response.ok || !me.id) throw new Error(`HTTP ${response.status}: ${JSON.stringify(me)}`)
console.log('role:', me.role)
console.log('permissions:', me.permissions.length ? me.permissions.join(', ') : '(none: public reads only)')The OAuth token
The access token allows you to “log in through VISH”: a person logs into your app with account VISH and allows them access. How to enable it is on the Login through VISH for developers page. Here's how the token differs from the key.:
- Passed in header
Authorization: Bearer <access_token>. - It acts on behalf of the logged-in person, but only for reading and only for the methods that the granted permission calls.:
schedule:read—GET /schedule,GET /schedule/subscriptions/mine,GET /schedule/{id}/subscription;notes:read—GET /schedule/{id}/notes. Any other method will answer 403OAUTH_SCOPE_INSUFFICIENT. - Employee or administrator rights, if a person has them, are not transferred to the token.
- It lives for 15 minutes; a new one is received with a refresh token (30 days, changes with each update).
- The browser will not allow you to read responses to such requests (CORS) from a page on another site: call schedule methods with a token from your server. Only protocol addresses
/oauth/…are available from the browser. - A person can disable your application in “Settings” → “Access” → “Connected token applications” stop working from the next request.
Log in to the app itself
Application VISH logs in via Telegram or MAX and receives its Bearer token. This input is for people in the application, not for integrations: do not try to repeat it from the script. The script needs a key, and someone else's site needs to “log in through VISH”.
Login Errors
| HTTP | error.code | What happened |
|---|---|---|
| 401 | AUTH_REQUIRED | The method requires login, but there is no key or token |
| 401 | UNAUTHORIZED | The key is incorrect, revoked, expired, or its owner is no longer there |
| 401 | ACCESS_TOKEN_INVALID | Bearer-the token is invalid or expired — update it |
| 403 | SESSION_REQUIRED | The human-only method in Appendix |
| 403 | OAUTH_SCOPE_INSUFFICIENT | This method is not allowed for the OAuth token |
| 403 | FORBIDDEN | Missing rights — see Access Rights (RBAC) |
What failures look like — without a real key, with obviously incorrect values:
// A made-up key and a made-up bearer token are both refused with 401.
const API = process.env.VISH_API ?? 'https://d1.vish-app.ru/api/v1'
const attempt = async (headers) => {
const response = await fetch(`${API}/auth/me`, { headers })
return { status: response.status, code: (await response.json()).error?.code }
}
const key = await attempt({ 'X-Api-Key': 'vish_not_a_real_key' })
const bearer = await attempt({ Authorization: 'Bearer not-a-real-token' })
if (key.status !== 401 || key.code !== 'UNAUTHORIZED') throw new Error(`key: ${JSON.stringify(key)}`)
if (bearer.status !== 401 || bearer.code !== 'ACCESS_TOKEN_INVALID') throw new Error(`bearer: ${JSON.stringify(bearer)}`)
console.log('made-up key ->', key.status, key.code)
console.log('made-up token ->', bearer.status, bearer.code)Try it: the method below will answer 401 without a key, and with your key in the “API Key” field, it will answer with your data. The key remains only in this tab and is not saved anywhere.
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._