BOTIX выступает как OAuth-провайдер. Если вы делаете публичное приложение поверх BOTIX, используйте OAuth 2.0 Authorization Code Flow вместо запроса 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.
Ваше приложение открывает 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
BOTIX показывает страницу со списком запрошенных scopes. После «Разрешить» — редирект:
https://yourapp.com/oauth/callback?code=AUTH_CODE&state=random_csrf_token
Проверьте, что state совпадает с тем, что вы отправили — это защита от CSRF.
Серверный POST на https://api.botix.pro/oauth/token:
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"
}
Передавайте токен в заголовке Authorization: Bearer при вызовах публичного API:
curl https://api.botix.pro/public/v1/me \ -H "Authorization: Bearer btx_oauth_8f2a..."
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"
Если вы не можете хранить client_secret в безопасности (SPA, мобильное приложение) —
используйте PKCE (RFC 7636).
code_verifier — случайная строка 43–128 символов из [A-Za-z0-9-._~].code_challenge = BASE64URL(SHA256(code_verifier)).code_challenge и code_challenge_method=S256.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." }
redirect_uri (исключение — http://localhost для разработки).Документация публичного API: developers.botix.pro.