{"name":"VK ID API","vendor":"VK","industry":"other","summary":"API единой системы авторизации VK ID: вход пользователей по OAuth 2.1 с обязательным PKCE, обмен кода на токены, обновление токенов, получение данных пользователя (маскированных и полных), отзыв разрешений и выход. Вход возможен через аккаунты VK ID, Одноклассников и Mail.ru.","docsUrl":"https://id.vk.ru/about/business/go/docs/ru/vkid/latest/vk-id/connection/api-description","coverage":{"included":[],"excluded":[]},"scenarios":[{"id":"sdelat-vhod-cherez-vk-id-na-sayte","title":"Сделать вход через VK ID на сайте","summary":"Кнопка «Войти через VK ID»: пользователь входит без пароля, сайт получает его имя, аватар и, если разрешено, телефон и email.","steps":["Создай приложение в кабинете VK ID и укажи redirect_uri. Для каждого входа сгенерируй code_verifier (43–128 символов), code_challenge — base64url от SHA-256 code_verifier — и state (не меньше 32 символов). Сохрани code_verifier и state в сессии.","Отправь пользователя на GET /authorize с response_type = code, client_id, redirect_uri, state, code_challenge, code_challenge_method = S256 и scope (по умолчанию vkid.personal_info; телефон и email — отдельные права). provider = ok_ru или mail_ru открывает вход через Одноклассники или Mail.ru.","На redirect_uri придут code (живёт 10 минут), device_id и state. Сравни state с сохранённым — иначе отклони запрос.","Обменяй код на токены: POST /oauth2/auth с grant_type = authorization_code, code, code_verifier, redirect_uri, client_id, device_id и state (form-urlencoded). В ответе access_token (живёт час), refresh_token, id_token и user_id.","Получи профиль: POST /oauth2/user_info с client_id и access_token — user_id, first_name, last_name, avatar, а также phone и email, если они есть в правах токена."],"code":"import base64, hashlib, secrets, requests\nfrom urllib.parse import urlencode\n\nCLIENT_ID, REDIRECT = \"<client_id>\", \"https://example.ru/auth/vk/callback\"\n\n# 1–2. Начало входа\nverifier = secrets.token_urlsafe(64)[:96]\nchallenge = base64.urlsafe_b64encode(hashlib.sha256(verifier.encode()).digest()).rstrip(b\"=\").decode()\nstate = secrets.token_urlsafe(32)\nsession.update(vk_verifier=verifier, vk_state=state)\nlogin_url = \"https://id.vk.ru/authorize?\" + urlencode({\n    \"response_type\": \"code\", \"client_id\": CLIENT_ID, \"redirect_uri\": REDIRECT, \"state\": state,\n    \"code_challenge\": challenge, \"code_challenge_method\": \"S256\", \"scope\": \"vkid.personal_info email\"})\n\n# 3–5. Обработчик redirect_uri\ndef callback(args):\n    if args[\"state\"] != session[\"vk_state\"]:\n        raise PermissionError(\"state mismatch\")\n    tokens = requests.post(\"https://id.vk.ru/oauth2/auth\", data={\n        \"grant_type\": \"authorization_code\", \"code\": args[\"code\"], \"code_verifier\": session[\"vk_verifier\"],\n        \"redirect_uri\": REDIRECT, \"client_id\": CLIENT_ID, \"device_id\": args[\"device_id\"], \"state\": args[\"state\"],\n    }).json()\n    user = requests.post(\"https://id.vk.ru/oauth2/user_info\",\n                         data={\"client_id\": CLIENT_ID, \"access_token\": tokens[\"access_token\"]}).json()[\"user\"]\n    return tokens, user","language":"python","methods":["GET /authorize","POST /oauth2/auth #2","POST /oauth2/auth #3","POST /oauth2/user_info"]},{"id":"prodlevat-sessiyu-bez-povtornogo-vhoda","title":"Продлевать сессию без повторного входа","summary":"Пользователь остаётся залогиненным неделями, хотя access_token живёт всего час.","steps":["Когда access_token истёк (или вот-вот истечёт по expires_in), вызови POST /oauth2/auth с grant_type = refresh_token, refresh_token, client_id, device_id (тот, что пришёл при входе) и state.","В ответе новая пара access_token и refresh_token, id_token не возвращается. Старая пара сразу перестаёт работать — сохраняй новую атомарно, иначе при параллельных запросах пользователя выкинет из сессии.","Делай обновление в одном месте (например, с блокировкой по пользователю), а не из каждого запроса отдельно.","Ошибка invalid_token значит, что refresh_token отозван или устарел: отправь пользователя на вход заново."],"code":"curl -s -X POST https://id.vk.ru/oauth2/auth \\\n  -H 'Content-Type: application/x-www-form-urlencoded' \\\n  -d grant_type=refresh_token \\\n  -d refresh_token=<refresh_token> \\\n  -d client_id=<client_id> \\\n  -d device_id=<device_id> \\\n  -d state=$(openssl rand -hex 24)","language":"bash","methods":["POST /oauth2/auth #2","POST /oauth2/auth #3"]},{"id":"pokazat-prodolzhit-kak-i-vyyti","title":"Показать «Продолжить как …» и выйти из аккаунта","summary":"Быстрый повторный вход по маскированным данным и корректный выход с отзывом доступа.","steps":["Для экрана «Продолжить как Анна П.» не нужен access_token: POST /oauth2/public_info с client_id и id_token вернёт имя, первую букву фамилии, маскированные телефон и email и аватар.","Выход: POST /oauth2/logout с client_id и access_token завершает сессию пользователя в твоём приложении.","Если пользователь удаляет аккаунт или отвязывает VK ID, отзови разрешения: POST /oauth2/revoke с client_id и access_token. Ответ — {\"response\": 1}.","Из браузера передавай токены только в теле form-urlencoded: заголовок Authorization и JSON ломают CORS preflight."],"code":"curl -s -X POST https://id.vk.ru/oauth2/public_info \\\n  -d client_id=<client_id> -d id_token=<id_token>\n\ncurl -s -X POST https://id.vk.ru/oauth2/logout \\\n  -d client_id=<client_id> -d access_token=<access_token>\n\ncurl -s -X POST https://id.vk.ru/oauth2/revoke \\\n  -d client_id=<client_id> -d access_token=<access_token>","language":"bash","methods":["POST /oauth2/public_info","POST /oauth2/revoke","POST /oauth2/logout"]}],"baseUrls":[{"label":"Боевой","url":"https://id.vk.ru"}],"auth":{"type":"oauth2","description":"Пользователь проходит `GET /authorize` и возвращается на `redirect_uri` с `code` и `device_id`; код обменивается на `access_token`, `refresh_token` и `id_token` методом `POST /oauth2/auth`. PKCE обязателен: `code_verifier` — 43–128 символов, `code_challenge` — base64url от SHA-256 строки `code_verifier`. Access token действует 1 час.","example":""},"methods":[{"id":"GET /authorize","title":"Код подтверждения и форма разрешений","httpMethod":"GET","path":"/authorize","description":"При успехе — редирект на `redirect_uri` с `code` (живёт 10 минут), `device_id` и `state`; при ошибке — JSON с `error` и `error_description`.","params":[{"name":"response_type","in":"query","type":"string","required":true,"description":"code"},{"name":"client_id","in":"query","type":"string","required":true,"description":"ID приложения"},{"name":"redirect_uri","in":"query","type":"string","required":true,"description":"Адрес возврата"},{"name":"state","in":"query","type":"string","required":true,"description":"Случайная строка, не меньше 32 символов"},{"name":"code_challenge","in":"query","type":"string","required":true,"description":"Хэш code_verifier"},{"name":"code_challenge_method","in":"query","type":"string","required":true,"description":"S256"},{"name":"scope","in":"query","type":"string","required":false,"description":"Права, по умолчанию vkid.personal_info"},{"name":"prompt","in":"query","type":"string","required":false,"description":"none, login, consent"},{"name":"provider","in":"query","type":"string","required":false,"description":"vkid, ok_ru, mail_ru"},{"name":"lang_id","in":"query","type":"string","required":false,"description":"Язык интерфейса"},{"name":"scheme","in":"query","type":"string","required":false,"description":"light или dark"}],"requestExample":"","responseExample":"","docsUrl":""},{"id":"POST /oauth2/auth #2","title":"Обмен кода на токены","httpMethod":"POST","path":"/oauth2/auth","description":"`grant_type=authorization_code`. В ответе: `access_token`, `refresh_token`, `id_token`, `token_type`, `expires_in`, `user_id`, `state`, `scope`.","params":[{"name":"grant_type","in":"body","type":"string","required":true,"description":"authorization_code"},{"name":"code","in":"body","type":"string","required":true,"description":"Код из редиректа"},{"name":"code_verifier","in":"body","type":"string","required":true,"description":"Исходная строка PKCE"},{"name":"redirect_uri","in":"body","type":"string","required":true,"description":"Тот же адрес возврата"},{"name":"client_id","in":"body","type":"string","required":true,"description":"ID приложения"},{"name":"device_id","in":"body","type":"string","required":true,"description":"device_id из редиректа"},{"name":"state","in":"body","type":"string","required":true,"description":"Строка state"},{"name":"service_token","in":"body","type":"string","required":false,"description":"Для конфиденциальных приложений"},{"name":"ip","in":"body","type":"string","required":false,"description":"IP пользователя"}],"requestExample":"","responseExample":"","docsUrl":""},{"id":"POST /oauth2/auth #3","title":"Обновление токенов","httpMethod":"POST","path":"/oauth2/auth","description":"`grant_type=refresh_token`. Возвращает новую пару `access_token` и `refresh_token` (без `id_token`); старая пара инвалидируется.","params":[{"name":"grant_type","in":"body","type":"string","required":true,"description":"refresh_token"},{"name":"refresh_token","in":"body","type":"string","required":true,"description":"Refresh-токен"},{"name":"client_id","in":"body","type":"string","required":true,"description":"ID приложения"},{"name":"device_id","in":"body","type":"string","required":true,"description":"ID устройства"},{"name":"state","in":"body","type":"string","required":true,"description":"Строка state"},{"name":"scope","in":"body","type":"string","required":false,"description":"Права"},{"name":"service_token","in":"body","type":"string","required":false,"description":"Для конфиденциальных приложений"},{"name":"ip","in":"body","type":"string","required":false,"description":"IP пользователя"}],"requestExample":"","responseExample":"","docsUrl":""},{"id":"POST /oauth2/user_info","title":"Данные пользователя (без маскирования)","httpMethod":"POST","path":"/oauth2/user_info","description":"В `user`: `user_id`, `first_name`, `last_name`, `avatar`, `sex`, `verified`, `birthday`; `phone` и `email` — если в токене есть соответствующие права.","params":[{"name":"client_id","in":"body","type":"string","required":true,"description":"ID приложения"},{"name":"access_token","in":"body","type":"string","required":true,"description":"Access-токен"}],"requestExample":"","responseExample":"","docsUrl":""},{"id":"POST /oauth2/public_info","title":"Маскированные данные пользователя","httpMethod":"POST","path":"/oauth2/public_info","description":"В `user`: `user_id`, `first_name`, `last_name` (первая буква), маскированные `phone` и `email`, `avatar`.","params":[{"name":"client_id","in":"body","type":"string","required":true,"description":"ID приложения"},{"name":"id_token","in":"body","type":"string","required":true,"description":"ID-токен"}],"requestExample":"","responseExample":"","docsUrl":""},{"id":"POST /oauth2/revoke","title":"Отзыв разрешений","httpMethod":"POST","path":"/oauth2/revoke","description":"Ответ: `{\"response\": 0 или 1}`.","params":[{"name":"client_id","in":"body","type":"string","required":true,"description":"ID приложения"},{"name":"access_token","in":"body","type":"string","required":true,"description":"Access-токен"}],"requestExample":"","responseExample":"","docsUrl":""},{"id":"POST /oauth2/logout","title":"Выход из аккаунта","httpMethod":"POST","path":"/oauth2/logout","description":"Ответ: `{\"response\": 0 или 1}`.","params":[{"name":"client_id","in":"body","type":"string","required":true,"description":"ID приложения"},{"name":"access_token","in":"body","type":"string","required":true,"description":"Access-токен"}],"requestExample":"","responseExample":"","docsUrl":""}],"codeExamples":[],"errors":[{"code":"access_denied","description":"Доступ запрещён"},{"code":"invalid_token","description":"Недействительный токен"},{"code":"invalid_client","description":"Неверный клиент"},{"code":"server_error","description":"Ошибка сервера"},{"code":"slow_down","description":"Слишком частые запросы"},{"code":"temporarily_unavailable","description":"Сервис временно недоступен"}],"limits":"- 120 000 запросов в сутки на конфиденциальное приложение.\n- 15 000 запросов в сутки с одного IP для публичных приложений.","gotchas":["Из браузера токен передаётся только в теле запроса с `Content-Type: application/x-www-form-urlencoded`: заголовок `Authorization` и JSON вызывают ошибку preflight CORS.","Неверный `grant_type` или `response_type` даёт ответ 404.","После обновления токенов старая пара `access_token`/`refresh_token` перестаёт работать.","`public_info` работает с `id_token` и отдаёт маскированные данные, `user_info` — с `access_token` и полные данные."],"slug":"vk-id","version":2,"updatedAt":"2026-10-24T17:05:39.219Z","sources":[{"title":"Описание API VK ID","url":"https://id.vk.ru/about/business/go/docs/ru/vkid/latest/vk-id/connection/api-description","kind":"research","addedAt":"2026-10-14T18:42:24.207Z"},{"title":"Вставленный текст","url":"","kind":"import","addedAt":"2026-10-14T18:42:24.207Z"},{"title":"scenarios-vk-id.md","url":"","kind":"import","addedAt":"2026-10-24T17:05:28.849Z"}],"logoUrl":null}