Integration API

Подключение клиентов партнёра: аккаунт, API-ключ, тариф, отключение

API для команд, которые подключают своих клиентов к A5X. Создаёте аккаунт по своему external_id, получаете ключ sk_live_…, при необходимости меняете ключ или отключаете клиента. Дальше клиент работает с Public и Speech на s2t.a5x.pro уже своим ключом. Типичный путь: создать клиента → сохранить ключ → вызывать Speech/Public → открывать кабинет через session-link.

Базовый URL

https://int.a5x.pro

В заголовке Authorization: Bearer int_live_… — секрет интеграции (выдаётся один раз при подключении партнёра). IP вашего сервера должен быть в allowlist, иначе ответ 403 ip_not_allowed.

Быстрый старт

curl -sS -X POST https://int.a5x.pro/v1/clients \
  -H "Authorization: Bearer int_live_…" \
  -H "Content-Type: application/json" \
  -d '{
    "external_id": "crm-42",
    "name": "ООО Ромашка",
    "email": "ops@romashka.test"
  }'

Два ключа

У партнёра и у конечного клиента разные секреты и разные хосты.

ПолеТипОписание
int_live_…IntegrationСекрет партнёра. Только в Authorization: Bearer на int.a5x.pro. Клиенту не передавать.
sk_live_…Client API keyКлюч клиента. Приходит при создании, смене ключа или повторном включении. Authorization: Bearer или X-API-Key на s2t.a5x.pro (Speech и Public).

Как подключить клиента

  • Создайте клиента: POST /v1/clients с external_id и желательно email.
  • Сохраните api_key (sk_live_…) у себя — ключ показывается один раз.
  • Клиент (или ваш бэкенд) вызывает Speech / Public с этим ключом на s2t.a5x.pro.
  • Вход в кабинет из CRM: POST …/api/public/v1/session-link → откройте пользователю url (см. Public API).
  • Баланс и пополнение: payment-link, balance, balance/history — тоже Public API.

Поток

# 1. Integrations
POST https://int.a5x.pro/v1/clients
  → сохранить sk_live_…

# 2. Speech / Public (тот же sk_live_…)
POST https://s2t.a5x.pro/api/...
GET  https://s2t.a5x.pro/api/public/v1/balance

# 3. Вход в кабинет
POST https://s2t.a5x.pro/api/public/v1/session-link
  → редирект браузера на url (TTL ~60 с)

Создать или обновить клиента

POSThttps://int.a5x.pro/v1/clients

Идемпотентность по паре (integration, external_id). Если клиента ещё нет — создаётся (тариф, политика, баланс, api_key). Если уже есть — обновляются name / email; ключ не меняется, пока не передать rotate_key: true. Email лучше передавать всегда: без него недоступен вход в кабинет через session-link.

Параметры запроса

ПолеТипОписание
external_id*stringID клиента у вас (1–128 символов).
namestringОтображаемое имя клиента.
emailstring (email)Email для кабинета. Глобально уникален. Если занят другим аккаунтом — 422 email_taken.
widget_origin_overridestringOrigin виджета, если нужен свой.
rotate_keybooleanПри обновлении существующего клиента выпустить новый api_key (по умолчанию false).

Примеры запросов

curl -sS -X POST https://int.a5x.pro/v1/clients \
  -H "Authorization: Bearer int_live_…" \
  -H "Content-Type: application/json" \
  -d '{
    "external_id": "crm-42",
    "name": "ООО Ромашка",
    "email": "ops@romashka.test"
  }'

Примеры ответов

{
  "created": true,
  "tenant_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "client_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "external_id": "crm-42",
  "is_active": true,
  "balance_rub": 100,
  "api_key": "sk_live_…",
  "api_key_prefix": "sk_live_AbCdEfGh",
  "tariff": {
    "version_id": "11111111-2222-3333-4444-555555555555",
    "label": "Standard",
    "rates": [
      {
        "option_id": "speech.transcribe",
        "product": "speech",
        "unit": "ms",
        "name": "Транскрибация",
        "amount_rub": 0.0001,
        "llm_model": null
      }
    ]
  }
}

Коды ответов

HTTPerror.codeСитуация
401unauthorizedНет или неверный int_live_….
403ip_not_allowedIP не в allowlist или интеграция отключена.
422email_takenEmail уже занят другим аккаунтом A5X.
422validation_errorНекорректное тело (например, пустой external_id).

Если email уже занят (email_taken)

Email в A5X уникален глобально. Если у человека уже есть кабинет (сам зарегистрировался или через другого партнёра), POST /v1/clients с этим email вернёт 422 email_taken. Чужой аккаунт по email «подтянуть» нельзя.

  • Покажите в интерфейсе: аккаунт A5X с этим email уже есть.
  • Попросите пользователя вставить API-ключ из кабинета (https://app.a5x.pro → ключи API).
  • Сохраните этот sk_live_… у себя и дальше вызывайте Public / Speech как обычный ключ клиента.
  • Для этого пользователя не создавайте свой external_id в Integrations — или создайте без email / с другим email по вашей политике (без email session-link недоступен).
  • В ответе email_taken ключ не приходит — только если пользователь сам его даст.
{
  "error": {
    "code": "email_taken",
    "message": "Email is already used by another client",
    "details": { "email": "ops@romashka.test" }
  }
}

Статус клиента

GEThttps://int.a5x.pro/v1/clients/{external_id}

Текущее состояние клиента. Полный api_key не возвращается — только api_key_prefix, баланс, тариф и is_active.

Параметры запроса

ПолеТипОписание
external_id*string (path)ID клиента у вас.

Получить статус

curl -sS https://int.a5x.pro/v1/clients/crm-42 \
  -H "Authorization: Bearer int_live_…"

Успешный ответ (200)

{
  "tenant_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "client_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "external_id": "crm-42",
  "name": "ООО Ромашка",
  "email": "ops@romashka.test",
  "is_active": true,
  "balance_rub": 100,
  "api_key_prefix": "sk_live_AbCdEfGh",
  "tariff": {
    "version_id": "11111111-2222-3333-4444-555555555555",
    "label": "Standard",
    "rates": [
      {
        "option_id": "speech.transcribe",
        "product": "speech",
        "unit": "ms",
        "name": "Транскрибация",
        "amount_rub": 0.0001,
        "llm_model": null
      }
    ]
  },
  "created_at": "2026-07-23T12:00:00.000Z",
  "updated_at": "2026-07-23T12:00:00.000Z"
}

Коды ответов

HTTPerror.codeСитуация
401unauthorizedНет или неверный int_live_….
403ip_not_allowedIP не в allowlist.
404client_not_foundНет клиента с таким external_id.

Сменить API-ключ

POSThttps://int.a5x.pro/v1/clients/{external_id}/api-key/rotate

Старый sk_live_… сразу перестаёт работать. Новый ключ — один раз в ответе. Клиент должен быть активен.

Параметры запроса

ПолеТипОписание
external_id*string (path)ID клиента у вас.

Сменить ключ

curl -sS -X POST https://int.a5x.pro/v1/clients/crm-42/api-key/rotate \
  -H "Authorization: Bearer int_live_…"

Успешный ответ (200)

{
  "tenant_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "client_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "external_id": "crm-42",
  "api_key": "sk_live_…",
  "api_key_prefix": "sk_live_XyZaBcDe"
}

Коды ответов

HTTPerror.codeСитуация
401unauthorizedНет или неверный int_live_….
404client_not_foundКлиент не найден.
409client_inactiveКлиент отключён — сначала включите снова (reactivate).

Отключить клиента

POSThttps://int.a5x.pro/v1/clients/{external_id}/deactivate

Клиент становится is_active=false (API-ключи сохраняются). Speech отвечает 403 client_inactive. Чтение Public API (/v1/communications, list, speakers) и пополнение (/v1/balance, /v1/payment-link, /v1/session-link) остаются доступны. Если клиент долго остаётся на паузе, аккаунт и данные могут быть полностью удалены.

Параметры запроса

ПолеТипОписание
external_id*string (path)ID клиента у вас.

Отключить

curl -sS -X POST https://int.a5x.pro/v1/clients/crm-42/deactivate \
  -H "Authorization: Bearer int_live_…"

Успешный ответ (200)

{
  "tenant_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "client_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "external_id": "crm-42",
  "is_active": false
}

Коды ответов

HTTPerror.codeСитуация
401unauthorizedНет или неверный int_live_….
404client_not_foundКлиент не найден.

Включить клиента снова

POSThttps://int.a5x.pro/v1/clients/{external_id}/reactivate

Клиент снова активен. Выдаётся новый api_key (один раз) — после отключения старый ключ уже недействителен.

Параметры запроса

ПолеТипОписание
external_id*string (path)ID клиента у вас.

Включить снова

curl -sS -X POST https://int.a5x.pro/v1/clients/crm-42/reactivate \
  -H "Authorization: Bearer int_live_…"

Успешный ответ (200)

{
  "tenant_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "client_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "external_id": "crm-42",
  "is_active": true,
  "api_key": "sk_live_…",
  "api_key_prefix": "sk_live_QwErTyUi"
}

Коды ответов

HTTPerror.codeСитуация
401unauthorizedНет или неверный int_live_….
404client_not_foundКлиент не найден.

Формат ошибки

{
  "error": {
    "code": "email_taken",
    "message": "Email is already used by another client",
    "details": { "email": "ops@romashka.test" }
  }
}

Типичные коды

HTTPerror.codeСитуация
401unauthorizedНет или неверный секрет интеграции.
403ip_not_allowedIP не в allowlist или интеграция отключена.
404client_not_foundКлиент с таким external_id не найден.
409client_inactiveОперация требует активного клиента (например смена ключа).
422email_takenEmail уже занят другим аккаунтом A5X.
422validation_errorНекорректное тело запроса.

Рекомендации

  • Храните api_key в зашифрованном виде; после смены ключа или повторного включения сразу обновите его у себя.
  • Для входа в кабинет из CRM каждый раз запрашивайте свежий session-link (срок жизни короткий) — см. Public API.
  • На email_taken — попросите ключ у пользователя, не повторяйте запрос с тем же email.
  • Исходящий IP сервера должен быть в allowlist Integration; при плотном трафике с одного NAT уточните whitelist у A5X.
  • Для нагрузочной транскрибации лучше async / fileUrl, а не плотный sync — см. Speech.

Чеклист перед продом

  • Получен int_live_…, IP сервера в allowlist.
  • POST /v1/clients с external_id + email отрабатывает, api_key сохранён.
  • Запрос Speech / Public с sk_live_… проходит.
  • session-link открывает кабинет в браузере.
  • Есть UX на 422 email_taken (ввод ключа пользователем).
  • Понятны сценарии смены ключа, отключения и повторного включения.