API-интеграции AI-агента

API-интеграция — это набор ручек вашего бэкенда, которые AI-оператор может вызывать по ходу диалога. Интеграция привязывается к AI-агенту и состоит из папок (структурирование) и эндпоинтов (описание метода/URL/параметров). Агент с этой интеграцией выбирается на канале.

Токен должен иметь scope ai_agents_api_integrations.

Базовый URL: https://api.apx.chat/api/v1/ai-agents/external

Успешные ответы имеют форму { "status": "OK", "data": ... }. Поле signingSecret никогда не возвращается; вместо него используется hasSigningSecret.

Структура интеграции

JSON
{
  "id": "uuid",
  "aiAgentId": "uuid",
  "name": "Магазин",
  "authPrefix": "Bearer",
  "authMode": "user_token",
  "hasSigningSecret": false,
  "folders": [
    {
      "id": "uuid",
      "name": "Пользователи",
      "order": 0,
      "endpoints": [
        {
          "id": "uuid",
          "method": "GET",
          "url": "https://api.example.com/users/{id}",
          "description": "Получить пользователя по id",
          "responseExample": "{ \"id\": 1, \"name\": \"Иван\" }",
          "enabled": true,
          "useUserToken": false,
          "order": 0
        }
      ],
      "children": []
    }
  ]
}
  • name — обязательно.
  • authPrefix — опциональный префикс (например Bearer), пробелы убираются.
  • authMode — режим персональной авторизации: user_token или signed_identity.
  • hasSigningSecret — выпущен ли секрет для signed_identity; само значение секрета API никогда не возвращает.
  • folders — иерархия; у каждой папки есть endpoints и children (вложенные папки).
  • useUserToken — включает персональную авторизацию для конкретной ручки. В режиме user_token это токен пользователя, в режиме signed_identity — подтверждённая личность и подпись запроса.

Два режима авторизации

Режим задаётся полем authMode для всей интеграции. Он применяется только к ручкам с useUserToken: true; ручки с useUserToken: false вызываются без персональных заголовков.

Переключатель APX: X-Api-Token / APX: Bearer в редакторе меняет авторизацию входящего запроса к публичному API APX. Поле authMode ниже управляет другим потоком — исходящим запросом AI-оператора в API вашего сайта. Эти настройки независимы.

authModeЧто передаёт виджетЧто хранит APXЧто получает ваша ручка
user_tokenwidget.setToken(token)токен пользователя в зашифрованном виде, не более 24 часов без активностиAuthorization: <authPrefix> <token>
signed_identitywidget.setIdentity(identityJwt)зашифрованное подписанное утверждение; токен авторизации пользователя не передаётся и не хранитсяX-Apx-User-Id, X-Apx-Timestamp, X-Apx-Signature

Токен пользователя (user_token)

Это режим по умолчанию. Укажите authPrefix (Bearer, если поле не передано), включите useUserToken у нужных ручек и после входа пользователя передайте отдельный короткоживущий токен виджету:

JS
window.apxChat.init('ВАШ_ТОКЕН_ВИДЖЕТА');
window.apxChat.setToken(userApiToken);

// При выходе пользователя
window.apxChat.clearToken();

APX хранит значение в зашифрованном виде и формирует Authorization только перед HTTP-вызовом. Токен не попадает в localStorage, интерфейс оператора или контекст AI-модели. Полный жизненный цикл описан в widget.setToken().

Подписанная личность (signed_identity)

Этот режим подходит, если токен пользователя нельзя передавать APX или авторизация сайта использует httpOnly-куки. Ваш бэкенд выпускает короткоживущий HS256 JWT с sub, а браузер передаёт готовое утверждение виджету:

JS
window.apxChat.init('ВАШ_ТОКЕН_ВИДЖЕТА');
window.apxChat.setIdentity(identityJwtFromYourBackend);

// При выходе пользователя
window.apxChat.clearIdentity();

Токен авторизации пользователя в этом потоке не существует на стороне APX. Перед вызовом ручки APX проверяет JWT и подписывает исходящий запрос секретом интеграции. Формат JWT, каноническая строка подписи и готовый код проверки X-Apx-* приведены на странице «Подписанная личность».

Секрет нельзя передать в JSON публичного API. Выпустите его в редакторе: AI-агенты → нужный агент → API → Способ авторизации → Подписанная личность → Выпустить секрет. Значение показывается один раз. Кнопка «Выпустить новый» выполняет немедленную ротацию: старый секрет перестаёт действовать сразу. Публичный API возвращает только hasSigningSecret.

Endpoints

Список

GET /api/v1/ai-agents/external/api-integrations

Создание

POST /api/v1/ai-agents/external/api-integrations

Опциональное поле agentId сразу привязывает интеграцию к AI-агенту — агент получит ссылку на эту интеграцию.

Вариант с токеном пользователя

const url = "https://api.apx.chat/api/v1/ai-agents/external/api-integrations";

const payload = {
  "name": "Магазин",
  "agentId": "b0c6c50b-9e8b-470a-ae92-457ec2190042",
  "authMode": "user_token",
  "authPrefix": "Bearer",
  "folders": [
    {
      "name": "Пользователи",
      "endpoints": [
        {
          "method": "GET",
          "url": "https://api.example.com/users/{id}",
          "description": "Получить пользователя по id",
          "enabled": true,
          "availableToAiOperator": true,
          "useUserToken": true
        }
      ]
    }
  ]
};

const response = await fetch(url, {
  method: "POST",
  headers: {
    "X-Api-Token": "tok_xxxxx",
    "Content-Type": "application/json",
  },
  body: JSON.stringify(payload),
});

const data = await response.json();
console.log(data);

Вариант с подписанной личностью

const url = "https://api.apx.chat/api/v1/ai-agents/external/api-integrations";

const payload = {
  "name": "Магазин без передачи токенов",
  "agentId": "b0c6c50b-9e8b-470a-ae92-457ec2190042",
  "authMode": "signed_identity",
  "folders": [
    {
      "name": "Пользователи",
      "endpoints": [
        {
          "method": "GET",
          "url": "https://api.example.com/users/{id}",
          "description": "Получить пользователя по подтверждённому X-Apx-User-Id",
          "enabled": true,
          "availableToAiOperator": true,
          "useUserToken": true
        }
      ]
    }
  ]
};

const response = await fetch(url, {
  method: "POST",
  headers: {
    "X-Api-Token": "tok_xxxxx",
    "Content-Type": "application/json",
  },
  body: JSON.stringify(payload),
});

const data = await response.json();
console.log(data);

После создания откройте интеграцию в редакторе и выпустите секрет. hasSigningSecret: false означает, что подписанные персональные вызовы ещё не настроены; публичного endpoint для чтения, выпуска или ротации plaintext-секрета нет.

Получение / обновление / удаление

  • GET /api/v1/ai-agents/external/api-integrations/{id}
  • PATCH /api/v1/ai-agents/external/api-integrations/{id} — частичное обновление (полная замена структуры folders, если передать её)
  • DELETE /api/v1/ai-agents/external/api-integrations/{id} — удаляет интеграцию и снимает её с привязанного агента

Выбор AI-агента на канале

Чтобы AI-оператор начал вызывать ваш API, привяжите интеграцию к AI-агенту (поле agentId) и выберите агента на канале через настройки AI-оператора канала.