/ developers / OAuth 2.0 v1

OAuth 2.0 для third-party приложений

BOTIX выступает как OAuth-провайдер. Если вы делаете публичное приложение поверх BOTIX, используйте OAuth 2.0 Authorization Code Flow вместо запроса API-ключа у каждого клиента.

Когда использовать OAuth, а когда API-ключ

СценарийЧто использовать
Своя система интегрируется с одним проектом BOTIX API-ключ — проще, выпускается в кабинете BOTIX
Публичное приложение работает с несколькими клиентами BOTIX OAuth 2.0 — каждый клиент даёт согласие, без передачи секретов
Server-to-server интеграция (cron, ETL) API-ключ
Расширение для CMS (Tilda, Bitrix) или мобильное приложение OAuth 2.0

Регистрация приложения

Откройте кабинет BOTIX → Настройки → Мои OAuth-приложения → Создать приложение. Введите название, redirect URIs (точные URL — без wildcards), выберите нужные scopes. BOTIX выдаст client_id и client_secret.

client_secret показывается ровно один раз. Скопируйте его сразу и храните в безопасном месте — в БД серверного приложения, не в JS-коде или мобильном бинарнике. Для SPA и мобильных приложений (где secret хранить негде) — используйте PKCE вместо secret.

Доступные scopes

contacts:read contacts:write messages:read messages:send scenarios:read scenarios:run chats:read channels:read webhooks:read webhooks:write

Authorization Code Flow

1
Редирект пользователя на authorize

Ваше приложение открывает https://app.botix.pro/oauth/authorize с параметрами:

https://app.botix.pro/oauth/authorize
  ?client_id=YOUR_CLIENT_ID
  &redirect_uri=https://yourapp.com/oauth/callback
  &response_type=code
  &scope=contacts:read messages:send
  &state=random_csrf_token
  &code_challenge=BASE64URL(SHA256(verifier))     # опционально, для PKCE
  &code_challenge_method=S256                      # опционально, для PKCE
2
Пользователь даёт согласие

BOTIX показывает страницу со списком запрошенных scopes. После «Разрешить» — редирект:

https://yourapp.com/oauth/callback?code=AUTH_CODE&state=random_csrf_token

Проверьте, что state совпадает с тем, что вы отправили — это защита от CSRF.

3
Обмен code → access_token

Серверный POST на https://api.botix.pro/oauth/token:

curl
PHP
Python
Node
curl -X POST https://api.botix.pro/oauth/token \
  -d "grant_type=authorization_code" \
  -d "code=AUTH_CODE" \
  -d "redirect_uri=https://yourapp.com/oauth/callback" \
  -d "client_id=YOUR_CLIENT_ID" \
  -d "client_secret=YOUR_CLIENT_SECRET"
<?php
$response = file_get_contents('https://api.botix.pro/oauth/token', false, stream_context_create([
    'http' => [
        'method'  => 'POST',
        'header'  => "Content-Type: application/x-www-form-urlencoded\r\n",
        'content' => http_build_query([
            'grant_type'    => 'authorization_code',
            'code'          => $_GET['code'],
            'redirect_uri'  => 'https://yourapp.com/oauth/callback',
            'client_id'     => getenv('BOTIX_CLIENT_ID'),
            'client_secret' => getenv('BOTIX_CLIENT_SECRET'),
        ]),
    ],
]));
$tokens = json_decode($response, true);
// $tokens['access_token'], $tokens['refresh_token']
import os, requests

r = requests.post('https://api.botix.pro/oauth/token', data={
    'grant_type':    'authorization_code',
    'code':          request.args['code'],
    'redirect_uri':  'https://yourapp.com/oauth/callback',
    'client_id':     os.environ['BOTIX_CLIENT_ID'],
    'client_secret': os.environ['BOTIX_CLIENT_SECRET'],
})
tokens = r.json()
# tokens['access_token'], tokens['refresh_token']
const params = new URLSearchParams({
    grant_type:    'authorization_code',
    code:          req.query.code,
    redirect_uri:  'https://yourapp.com/oauth/callback',
    client_id:     process.env.BOTIX_CLIENT_ID,
    client_secret: process.env.BOTIX_CLIENT_SECRET,
});
const r = await fetch('https://api.botix.pro/oauth/token', {
    method: 'POST', body: params,
});
const tokens = await r.json();
// tokens.access_token, tokens.refresh_token

Ответ

{
  "access_token":  "btx_oauth_8f2a...",
  "token_type":    "Bearer",
  "expires_in":    3600,
  "refresh_token": "btx_refresh_6e1c...",
  "scope":         "contacts:read messages:send"
}
4
Использование access_token

Передавайте токен в заголовке Authorization: Bearer при вызовах публичного API:

curl https://api.botix.pro/public/v1/me \
  -H "Authorization: Bearer btx_oauth_8f2a..."

Refresh — обновление токена

Access-токен живёт 1 час. Когда он истёк — обменяйте refresh_token на новую пару. BOTIX делает rotation: старый refresh при обмене отзывается, выдаётся новый.

curl -X POST https://api.botix.pro/oauth/token \
  -d "grant_type=refresh_token" \
  -d "refresh_token=btx_refresh_6e1c..." \
  -d "client_id=YOUR_CLIENT_ID" \
  -d "client_secret=YOUR_CLIENT_SECRET"

PKCE для SPA и мобильных приложений

Если вы не можете хранить client_secret в безопасности (SPA, мобильное приложение) — используйте PKCE (RFC 7636).

  1. Сгенерируйте code_verifier — случайная строка 43–128 символов из [A-Za-z0-9-._~].
  2. Посчитайте code_challenge = BASE64URL(SHA256(code_verifier)).
  3. В URL authorize добавьте code_challenge и code_challenge_method=S256.
  4. При обмене code → token передайте code_verifier вместо client_secret.

Ошибки

Все ошибки соответствуют RFC 6749. Примеры:

{ "error": "invalid_grant",
  "error_description": "Authorization code невалиден или истёк." }

{ "error": "invalid_client",
  "error_description": "client_secret невалиден." }

{ "error": "unsupported_grant_type",
  "error_description": "Поддерживаются только authorization_code и refresh_token." }

Безопасность

Документация публичного API: developers.botix.pro.

API: проверяем…