Для AI-агентов: markdown этой страницы — /docs-content/keys-auth/oauth.md индекс документации — /llms.txt
Авторизация пользователей приложения
Порядок OAuth-авторизации для приложений, работающих от лица разных пользователей портала. Пользователь входит через Битрикс24, приложение получает токен сессии и дальше обращается к API от его имени. AI-агент, которому передали ключ авторизации, проходит весь этот поток самостоятельно — по шагам ниже.
Скоуп: не требуется | Базовый URL: https://vibecode.bitrix24.tech/v1 | Авторизация: ключ авторизации в параметре app_key
Когда нужна авторизация пользователя
Ключ авторизации vibe_app_ работает от лица конкретного пользователя, установившего приложение. Чтобы платформа знала, от чьего имени обращаться к Битрикс24, к запросу прикладывается токен сессии в заголовке Authorization: Bearer. Токен выдаётся в конце этого потока.
Личный ключ vibe_api_ работает от лица своего владельца и токен сессии не использует. Для фоновых сценариев без пользователя у экрана берите его, а не ключ авторизации — Передача ключа.
Эндпоинты /v1/oauth/* заголовок X-Api-Key не читают. Ключ авторизации они принимают параметром app_key: в адресе запроса у GET /v1/oauth/authorize и GET /v1/oauth/poll, в теле у POST /v1/oauth/token и POST /v1/oauth/placement-session. Исключение — POST /v1/oauth/revoke: ключ авторизации ему не нужен, он принимает только токен сессии в заголовке Authorization: Bearer.
Шаг 1. Отправьте пользователя на авторизацию
Сгенерируйте state — криптослучайную строку 16–512 символов. Это защита от подделки межсайтового запроса по RFC 6749 §10.12: значение генерирует клиент, а на возврате сверяет, что пришло то же самое. Сервер сгенерировать state за вас не может.
Вызовите GET /v1/oauth/authorize с сервера приложения и отключите автоматический переход по перенаправлению. Платформа проверит app_key и redirect_uri и ответит 302: в заголовке Location придёт адрес страницы входа Битрикс24. Перенаправьте браузер пользователя на этот адрес. Ключа авторизации в адресе из Location нет, поэтому ключ остаётся на сервере. Ссылку на сам GET /v1/oauth/authorize браузеру не передавайте: в ней app_key.
// Выполняется на сервере приложения
const state = crypto.randomUUID()
// Сохраните state в сессии пользователя, чтобы сверить его на возврате
const url = new URL('https://vibecode.bitrix24.tech/v1/oauth/authorize')
url.searchParams.set('app_key', 'YOUR_APP_KEY')
url.searchParams.set('state', state)
url.searchParams.set('redirect_uri', 'https://myapp.example.com/callback')
const res = await fetch(url, { redirect: 'manual' })
if (res.status !== 302) throw new Error(await res.text())
const location = res.headers.get('location')
// Ответьте браузеру пользователя перенаправлением 302 на location
Если проверка не прошла, вместо 302 придёт JSON с ошибкой — коды в разделе Ошибки. Открывайте адрес из Location переходом верхнего уровня, а не фоновым запросом: страница входа Битрикс24 отдаёт заголовок X-Frame-Options и внутри iframe не открывается. После авторизации Битрикс24 вернёт пользователя на зарегистрированный обработчик приложения, а платформа — на ваш redirect_uri.
Шаг 2. Примите возврат на `redirect_uri`
После авторизации платформа перенаправляет браузер на ваш redirect_uri с одноразовым кодом и вашим state:
https://myapp.example.com/callback?code=VIBE_AUTH_CODE&state=YOUR_STATE
Сверьте state с тем, что сохранили на шаге 1. Если значения не совпадают, прервите авторизацию. Разбор ошибок в этом адресе — Что приходит на redirect_uri.
Шаг 3. Обменяйте код на токен сессии
С сервера приложения обменяйте code на токен сессии. redirect_uri в теле точно равен тому, что был на шаге 1.
cURL
curl -X POST https://vibecode.bitrix24.tech/v1/oauth/token \
-H "Content-Type: application/json" \
-d '{
"app_key": "YOUR_APP_KEY",
"code": "VIBE_AUTH_CODE",
"redirect_uri": "https://myapp.example.com/callback"
}'
JavaScript
const res = await fetch('https://vibecode.bitrix24.tech/v1/oauth/token', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
app_key: 'YOUR_APP_KEY',
code: 'VIBE_AUTH_CODE',
redirect_uri: 'https://myapp.example.com/callback',
}),
})
const { access_token, user, expires_in } = await res.json()
// Сохраните access_token — он действует 24 часа
{
"success": true,
"access_token": "vibe_session_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"user": { "id": "42", "name": "Иван Петров", "email": "user@example.com" },
"expires_in": 86400
}
Код одноразовый и действует 5 минут.
Шаг 4. Вызывайте API с токеном сессии
Каждый запрос к API идёт с двумя заголовками — ключ авторизации в X-Api-Key и токен сессии в Authorization: Bearer:
cURL
curl https://vibecode.bitrix24.tech/v1/deals \
-H "X-Api-Key: YOUR_APP_KEY" \
-H "Authorization: Bearer USER_SESSION_TOKEN"
JavaScript
const res = await fetch('https://vibecode.bitrix24.tech/v1/deals', {
headers: {
'X-Api-Key': 'YOUR_APP_KEY',
'Authorization': 'Bearer USER_SESSION_TOKEN',
},
})
const { data } = await res.json()
Сессия наследует права приложения на портале. Без заголовка Authorization: Bearer эндпоинты, которым нужен пользовательский контекст, возвращают 401 TOKEN_MISSING.
Что приходит на `redirect_uri`
Платформа возвращает пользователя на redirect_uri с результатом в параметрах запроса. Всегда приходит ваш state — сверяйте его первым.
| Параметр | Когда приходит | Значение |
|---|---|---|
Параметрcode |
Когда приходитАвторизация прошла | ЗначениеОдноразовый код для обмена на токен. Действует 5 минут |
Параметрstate |
Когда приходитВсегда | ЗначениеЗначение state, переданное на шаге 1 |
Параметрerror |
Когда приходитАвторизация не удалась | ЗначениеПричина отказа — одно из значений ниже |
Значения error:
error |
Что произошло |
|---|---|
errortoken_exchange_failed |
Что произошлоБитрикс24 не выдал токены по коду авторизации |
errorinvalid_domain |
Что произошлоДомен портала не прошёл проверку |
errorprofile_fetch_failed |
Что произошлоНе удалось прочитать профиль пользователя на портале |
errorapp_unavailable |
Что произошлоПриложение больше не доступно: его автор удалил свои данные |
Часть отказов на приёме возврата приходит не в адресе, а JSON-ответом со статусом 400 или 500 — когда платформа ещё не знает redirect_uri, вернуть на него нельзя. Это MISSING_PARAMS, INVALID_STATE и APP_CONFIG_ERROR из таблицы Ошибки.
Правило `redirect_uri`
redirect_uri должен точно совпадать с одним из адресов, зарегистрированных у приложения — совпадают схема, хост, порт и путь. Добавить адрес возврата можно в карточке приложения в разделе Ключи авторизации — поле «Redirect URI (OAuth)».
У нового приложения по умолчанию зарегистрирован адрес http://localhost — без порта и с путём /. Совпадение точное, поэтому http://localhost:3000/callback под него не подходит. Чтобы возврат шёл на ваш адрес — http://localhost:3000/callback или https://myapp.example.com/callback — сначала добавьте его в карточке приложения. Иначе GET /v1/oauth/authorize вернёт 400 INVALID_REDIRECT_URI.
Если redirect_uri опущен, платформа использует встроенную страницу возврата — Авторизация без своего redirect_uri.
Авторизация без своего `redirect_uri`
Когда redirect_uri опущен, платформа возвращает пользователя на встроенную страницу /oauth/complete и создаёт токен сессии на своей стороне. Сервер приложения забирает результат опросом GET /v1/oauth/poll по тому же state. Из браузера этот запрос не делайте: в его адресе app_key.
cURL
curl "https://vibecode.bitrix24.tech/v1/oauth/poll?app_key=YOUR_APP_KEY&state=YOUR_STATE"
JavaScript
// Выполняется на сервере приложения
const url = `https://vibecode.bitrix24.tech/v1/oauth/poll?app_key=YOUR_APP_KEY&state=${state}`
const res = await fetch(url)
const result = await res.json()
if (result.status === 'complete') {
// result.access_token, result.user, result.expires_in
}
Пока пользователь не завершил вход, приходит статус pending:
{ "success": true, "status": "pending" }
После входа тот же запрос отдаёт токен сессии. Результат одноразовый — следующий опрос по этому же state снова вернёт pending:
{
"success": true,
"status": "complete",
"access_token": "vibe_session_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"user": { "id": "42", "name": "Иван Петров", "email": "user@example.com" },
"expires_in": 86400
}
Результат хранится 10 минут. Забирайте его сразу после возврата пользователя на страницу входа.
Токен сессии: срок и отзыв
Токен сессии действует 24 часа и не обновляется — поле expires_in в ответе равно 86400. Механизма продления нет. После истечения вызовы за пользователя возвращают 401 INVALID_SESSION — это сигнал заново пройти авторизацию: GET /v1/oauth/authorize → POST /v1/oauth/token.
Досрочно отозвать токен — POST /v1/oauth/revoke с токеном сессии в заголовке Authorization: Bearer. Отзыв удаляет сессию пользователя, дальнейшие вызовы с этим токеном отклоняются.
cURL
curl -X POST https://vibecode.bitrix24.tech/v1/oauth/revoke \
-H "Authorization: Bearer USER_SESSION_TOKEN"
JavaScript
const res = await fetch('https://vibecode.bitrix24.tech/v1/oauth/revoke', {
method: 'POST',
headers: { 'Authorization': 'Bearer USER_SESSION_TOKEN' },
})
const { revoked } = await res.json()
{ "success": true, "revoked": true }
Поле revoked равно false, если действующей сессии с таким токеном уже не было. Ответ приходит со статусом 200 в обоих случаях.
Приложение на своём сервере
Отдельная вкладка для входа доступна не всегда — например, приложение открывается как размещение внутри Битрикс24, а страница согласия внутри iframe не открывается. Если приложение размещено на собственном сервере, а не за Black Hole, токен сессии текущего пользователя получают одним из двух способов — по тому, чей обработчик принимает размещение.
Приложение Вайбкод, appUrl — ваш сервер. Размещение приходит на обработчик Вайбкод, и платформа перенаправляет браузер на <appUrl>/?code=<одноразовый код>&placement=...&member_id=.... Ваш сервер обменивает код на токен сессии тем же запросом POST /v1/oauth/token с телом { app_key, code, redirect_uri }, где redirect_uri точно равен настроенному appUrl. Токен сессии в браузер не попадает — в адресе только одноразовый код, бесполезный без app_key. Поле appUrl редактируется в карточке приложения в разделе Ключи авторизации.
Собственное приложение Битрикс24 со своим обработчиком. Размещение приходит напрямую на ваш сервер с токеном пользователя Битрикс24. Обменяйте его на токен сессии серверным запросом — POST /v1/oauth/placement-session.
cURL
curl -X POST https://vibecode.bitrix24.tech/v1/oauth/placement-session \
-H "Content-Type: application/json" \
-d '{
"app_key": "YOUR_APP_KEY",
"access_token": "BITRIX24_USER_TOKEN",
"member_id": "MEMBER_ID",
"domain": "mycompany.bitrix24.ru"
}'
JavaScript
const res = await fetch('https://vibecode.bitrix24.tech/v1/oauth/placement-session', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
app_key: 'YOUR_APP_KEY',
access_token: 'BITRIX24_USER_TOKEN',
member_id: 'MEMBER_ID',
domain: 'mycompany.bitrix24.ru',
}),
})
const { access_token, user, expires_in } = await res.json()
{
"success": true,
"access_token": "vibe_session_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"user": { "id": "42", "name": "Иван Петров", "email": "user@example.com" },
"expires_in": 86400
}
domain должен совпадать с порталом приложения. Поля refresh_token и expires_in в теле необязательны и описывают токен пользователя Битрикс24: expires_in — сколько он действует, по умолчанию 3600 секунд. Без действующего refresh_token токен Битрикс24 автоматически не обновляется — после его истечения переоткройте размещение. Сам токен сессии, как и в основном потоке, действует 24 часа.
Полный жизненный цикл встроенного приложения и примеры обработчика на Node, Python и Go — Авторизация в приложении на Black Hole.
Справочник эндпоинтов
| Метод | Путь | Описание |
|---|---|---|
| МетодGET | Путь/v1/oauth/authorize |
ОписаниеНачать авторизацию — редирект на страницу входа Битрикс24 |
| МетодGET | Путь/v1/oauth/callback |
ОписаниеПриём ответа Битрикс24. Вызывается Битрикс24, не приложением |
| МетодPOST | Путь/v1/oauth/token |
ОписаниеОбменять код на токен сессии |
| МетодGET | Путь/v1/oauth/poll |
ОписаниеЗабрать результат авторизации без своего redirect_uri |
| МетодPOST | Путь/v1/oauth/placement-session |
ОписаниеТокен сессии для приложения на своём сервере |
| МетодPOST | Путь/v1/oauth/revoke |
ОписаниеОтозвать токен сессии |
Ошибки
Ключ авторизации проверяется на входе GET /v1/oauth/authorize, POST /v1/oauth/token и POST /v1/oauth/placement-session:
| HTTP | Код | Описание |
|---|---|---|
| HTTP401 | КодINVALID_APP_KEY |
Описаниеapp_key не найден или это не ключ авторизации |
| HTTP401 | КодKEY_INACTIVE |
ОписаниеКлюч авторизации отозван |
| HTTP401 | КодKEY_EXPIRED |
ОписаниеСрок действия ключа авторизации прошёл |
| HTTP403 | КодOWNER_BLOCKED |
ОписаниеВладелец ключа заблокирован или больше не активен на портале |
GET /v1/oauth/authorize:
| HTTP | Код | Описание |
|---|---|---|
| HTTP400 | КодINVALID_REQUEST |
ОписаниеНет обязательного state или он вне диапазона 16–512 символов |
| HTTP400 | КодINVALID_REQUEST |
Описаниеstate начинается с open-app: — этот префикс зарезервирован платформой |
| HTTP400 | КодINVALID_REDIRECT_URI |
Описаниеredirect_uri не зарегистрирован у приложения |
| HTTP500 | КодNO_PORTAL |
ОписаниеПриложение не привязано к порталу |
GET /v1/oauth/callback (вызывается Битрикс24):
| HTTP | Код | Описание |
|---|---|---|
| HTTP400 | КодMISSING_PARAMS |
ОписаниеБитрикс24 вернулся без code или state |
| HTTP400 | КодINVALID_STATE |
Описаниеstate не найден или истёк за 20 минут. В error.details.reason — NOT_FOUND или EXPIRED |
| HTTP500 | КодAPP_CONFIG_ERROR |
ОписаниеУ приложения не заданы OAuth-учётные данные |
POST /v1/oauth/token:
| HTTP | Код | Описание |
|---|---|---|
| HTTP400 | КодINVALID_REQUEST |
ОписаниеВ теле нет code или redirect_uri |
| HTTP400 | КодINVALID_CODE |
ОписаниеКод не найден или принадлежит другому приложению |
| HTTP400 | КодCODE_EXPIRED |
ОписаниеСрок действия кода прошёл — 5 минут |
| HTTP400 | КодCODE_ALREADY_USED |
ОписаниеКод уже обменян на токен |
| HTTP400 | КодREDIRECT_URI_MISMATCH |
Описаниеredirect_uri не совпадает с переданным в GET /v1/oauth/authorize |
| HTTP500 | КодTOKEN_NOT_FOUND |
ОписаниеТокен пользователя не найден |
GET /v1/oauth/poll:
| HTTP | Код | Описание |
|---|---|---|
| HTTP400 | КодINVALID_REQUEST |
Описаниеstate короче 16 символов или нет app_key |
| HTTP401 | КодINVALID_APP_KEY |
Описаниеapp_key не найден или это не ключ авторизации |
POST /v1/oauth/placement-session:
| HTTP | Код | Описание |
|---|---|---|
| HTTP400 | КодINVALID_REQUEST |
ОписаниеВ теле нет access_token, member_id или domain |
| HTTP400 | КодDOMAIN_MISMATCH |
Описаниеdomain не совпадает с порталом приложения |
| HTTP401 | КодUSER_AUTH_REQUIRED |
ОписаниеТокен пользователя Битрикс24 не подтвердил авторизацию на портале |
| HTTP403 | КодAPP_UNAVAILABLE |
ОписаниеПриложение больше не доступно: его автор удалил свои данные |
| HTTP500 | КодNO_PORTAL |
ОписаниеПриложение не привязано к порталу |
POST /v1/oauth/revoke:
| HTTP | Код | Описание |
|---|---|---|
| HTTP400 | КодMISSING_TOKEN |
ОписаниеНе передан Authorization: Bearer с токеном сессии |
Вызовы API с токеном сессии:
| HTTP | Код | Описание |
|---|---|---|
| HTTP401 | КодTOKEN_MISSING |
ОписаниеКлюч авторизации отправлен без Authorization: Bearer на эндпоинт, которому нужен пользовательский контекст |
| HTTP401 | КодINVALID_SESSION |
ОписаниеТокен сессии истёк, отозван или не найден. Пройдите авторизацию заново: GET /v1/oauth/authorize → POST /v1/oauth/token |
Полный список общих ошибок API — Ошибки.
Пример ответа при ошибке
400 — не передан обязательный state:
{
"success": false,
"error": {
"code": "INVALID_REQUEST",
"message": "state: Required"
}
}