Для AI-агентов: markdown этой страницы — /docs-content/keys-auth/oauth.md индекс документации — /llms.txt
Авторизация пользователей приложения
Порядок OAuth-авторизации для приложений, работающих от лица разных пользователей портала. Пользователь входит через Битрикс24, приложение получает токен сессии и дальше обращается к API от его имени. AI-агент, которому передали ключ авторизации, проходит весь этот поток самостоятельно — по шагам ниже.
Скоуп: не требуется | Базовый URL: https://vibecode.bitrix24.tech/v1 | Авторизация: X-Api-Key: YOUR_APP_KEY
Когда нужна авторизация пользователя
Ключ авторизации vibe_app_ работает от лица конкретного пользователя, установившего приложение. Чтобы платформа знала, от чьего имени обращаться к Битрикс24, к запросу прикладывается токен сессии в заголовке Authorization: Bearer. Токен выдаётся в конце этого потока.
Личный ключ vibe_api_ работает от лица своего владельца и токен сессии не использует. Для фоновых сценариев без пользователя у экрана берите его, а не ключ авторизации — Передача ключа.
Все эндпоинты /v1/oauth/* отвечают по одному заголовку X-Api-Key с ключом авторизации, без Authorization: Bearer.
Шаг 1. Отправьте пользователя на авторизацию
Сгенерируйте state — криптослучайную строку 16–512 символов. Это защита от подделки межсайтового запроса по RFC 6749 §10.12: значение генерирует клиент, а на возврате сверяет, что пришло то же самое. Сервер сгенерировать state за вас не может.
Соберите ссылку на GET /v1/oauth/authorize и перенаправьте на неё браузер пользователя. Это переход верхнего уровня, а не фоновый запрос — страница согласия Битрикс24 отдаёт заголовок X-Frame-Options и внутри iframe не открывается.
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')
window.location.href = url.toString()
Платформа проверит app_key и redirect_uri и перенаправит пользователя на страницу авторизации Битрикс24. После авторизации Битрикс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 |
Что произошло |
|---|---|
token_exchange_failed |
Битрикс24 не выдал токены по коду авторизации |
invalid_domain |
Домен портала не прошёл проверку |
profile_fetch_failed |
Не удалось прочитать профиль пользователя на портале |
Часть отказов на приёме возврата приходит не в адресе, а 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.
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 не открывается. Если приложение размещено на собственном сервере, а не за BlackHole, токен сессии текущего пользователя получают одним из двух способов — по тому, чей обработчик принимает размещение.
Приложение Вайбкод, 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 — Авторизация в приложении на BlackHole.
Справочник эндпоинтов
| Метод | Путь | Описание |
|---|---|---|
| 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 | Код | Описание |
|---|---|---|
| 401 | INVALID_APP_KEY |
app_key не найден или это не ключ авторизации |
| 401 | KEY_INACTIVE |
Ключ авторизации отозван |
| 401 | KEY_EXPIRED |
Срок действия ключа авторизации прошёл |
| 403 | OWNER_BLOCKED |
Владелец ключа заблокирован платформой |
GET /v1/oauth/authorize:
| HTTP | Код | Описание |
|---|---|---|
| 400 | INVALID_REQUEST |
Нет обязательного state или он вне диапазона 16–512 символов |
| 400 | INVALID_REDIRECT_URI |
redirect_uri не зарегистрирован у приложения |
| 500 | NO_PORTAL |
Приложение не привязано к порталу |
GET /v1/oauth/callback (вызывается Битрикс24):
| HTTP | Код | Описание |
|---|---|---|
| 400 | MISSING_PARAMS |
Битрикс24 вернулся без code или state |
| 400 | INVALID_STATE |
state не найден или истёк за 20 минут. В error.details.reason — NOT_FOUND или EXPIRED |
| 500 | APP_CONFIG_ERROR |
У приложения не заданы OAuth-учётные данные |
POST /v1/oauth/token:
| HTTP | Код | Описание |
|---|---|---|
| 400 | INVALID_REQUEST |
В теле нет code или redirect_uri |
| 400 | INVALID_CODE |
Код не найден или принадлежит другому приложению |
| 400 | CODE_EXPIRED |
Срок действия кода прошёл — 5 минут |
| 400 | CODE_ALREADY_USED |
Код уже обменян на токен |
| 400 | REDIRECT_URI_MISMATCH |
redirect_uri не совпадает с переданным в GET /v1/oauth/authorize |
| 500 | TOKEN_NOT_FOUND |
Токен пользователя не найден |
GET /v1/oauth/poll:
| HTTP | Код | Описание |
|---|---|---|
| 400 | INVALID_REQUEST |
state короче 16 символов или нет app_key |
| 401 | INVALID_APP_KEY |
app_key не найден или это не ключ авторизации |
POST /v1/oauth/placement-session:
| HTTP | Код | Описание |
|---|---|---|
| 400 | INVALID_REQUEST |
В теле нет access_token, member_id или domain |
| 400 | DOMAIN_MISMATCH |
domain не совпадает с порталом приложения |
| 401 | USER_AUTH_REQUIRED |
Токен пользователя Битрикс24 не подтвердил авторизацию на портале |
| 500 | NO_PORTAL |
Приложение не привязано к порталу |
POST /v1/oauth/revoke:
| HTTP | Код | Описание |
|---|---|---|
| 400 | MISSING_TOKEN |
Не передан Authorization: Bearer с токеном сессии |
Полный список общих ошибок API — Ошибки.
Пример ответа при ошибке
400 — не передан обязательный state:
{
"success": false,
"error": {
"code": "INVALID_REQUEST",
"message": "state: Required"
}
}