Integration API

Унифицированный REST-интерфейс для интеграции вашего space с внешними системами: лиды, чаты, вебхуки. Один формат, единый ключ, scope-based доступ.

⚠️ Используете старый /v1/live-chat/admin/*?

Endpoints, описанные в предыдущей версии документации (Chat API), объединены в единый Integration API под префиксом /v1/integration/*. Старые URL продолжают работать для обратной совместимости, но новые интеграции делайте сразу на новый surface.

→ Что изменилось и как мигрировать

Аутентификация

Все запросы к Integration API подписываются заголовком X-API-Key. Формат ключа: wi_live_<random>.

GET /v1/integration/leads
X-API-Key: wi_live_aBcDeF0123456789...
Content-Type: application/json

Ключ выпускается в Панели управления → Интеграции → API-ключи. При создании выбираются scope'ы (см. ниже) и привязка к space.

Ключ показывается полностью только при создании. Храните его в защищённом storage (env, secrets manager). Не передавайте в клиентском коде/публичных репозиториях.

Scopes

Каждый ключ имеет набор разрешений (scopes). На уровне маршрута проверяется требуемый scope; при отсутствии — 403 Forbidden.

ScopeРазрешения
leads:readЧтение лидов: GET /v1/integration/leads, GET /v1/integration/leads/{id}
leads:writeСоздание/обновление лидов: POST, PATCH /v1/integration/leads*
slotus:readКалендари, ресурсы, услуги, брони, availability: GET /v1/integration/slotus/*
slotus:writeСоздание брони + lifecycle (confirm / complete / no-show / cancel / reschedule): POST, PATCH /v1/integration/slotus/bookings*
webhooks:manageУправление вебхуками — все методы /v1/integration/webhooks*
chats:read резервЗарезервирован для чтения чатов. Сейчас chats-эндпоинты доступны без scope-проверки (back-compat).
chats:write резервЗарезервирован для отправки сообщений / закрытия диалогов.
При нехватке scope ответ содержит поле required_scope, чтобы интегратор мог обработать ошибку программно.

Base URL и host binding

Каждое пространство (space) имеет собственный поддомен:

https://{space_name}.api.wispace.ru

Например, для пространства sigmamotors:

https://sigmamotors.api.wispace.ru/v1/integration/leads

Ключ привязан к одному space. Запрос с ключом, выписанным под space-A, пришедший на хост space-B, отклоняется с 403 Forbidden.

Ошибки

КодОписание
200Успешный запрос
201Ресурс создан
400Невалидный запрос (ошибка валидации)
401Нет/невалидный API-ключ
403Недостаточно scope либо ключ выписан под другой space
404Ресурс не найден
429Превышен rate limit
5xxОшибка backend / proxy

Тело ошибки:

{
  "error": "insufficient_scope",
  "required_scope": "leads:write"
}

Rate Limits

Per-key лимит, по умолчанию 60 запросов/минуту (настраивается на ключ). Единый лимит на все методы.

Заголовки ответа:

ЗаголовокОписание
X-RateLimit-LimitМаксимум запросов в окне (минута)
X-RateLimit-RemainingОсталось запросов в текущем окне
Retry-AfterСекунд до сброса лимита (только при 429)

Companies (справочник)

Внутри одного space может жить несколько компаний (platform.company). Например, у дилерского холдинга один space на всю группу и отдельные компании на каждый дилер-центр (Toyota Архангельск, Чанган Аксель, Аутлет Авто Вилледж и т.д.).

Чтобы фильтровать чаты или лиды по конкретной компании — нужно знать её id. Этот endpoint возвращает справочник всех компаний space-а.

Список компаний

GET /v1/integration/companies
ПараметрТипОписание
limitint1–200, по умолчанию 50
offsetintСмещение для пагинации
// Ответ
{
  "data": [
    {
      "id": 7,
      "uid": "94f55dc0-eb35-43cc-9ef2-4fc21e7fa4ba",
      "name": "toyota_tsentr_arhangel_sk",
      "title": "Тойота Центр Архангельск",
      "is_active": true,
      "legal_address": "г. Архангельск, ул. Папанина, 21",
      "phone": "78182420000",
      "email": "",
      "company_type": 1,
      "parent_company": null
    },
    {
      "id": 8,
      "uid": "0356a6d9-7e99-4fab-b376-f246ca11d50a",
      "name": "changan_tsentr_aksel",
      "title": "Чанган Центр Аксель",
      "is_active": true,
      "legal_address": "г. Архангельск, ул. Папанина, 23"
    }
  ],
  "pagination": { "total": 16, "limit": 50, "offset": 0 }
}
Поле id (integer) используется как ?company_id=... в фильтрах /chats и /leads. Сохраните карту id ↔ внутренний идентификатор вашей CRM один раз и используйте при роутинге событий.

Leads (лиды)

Доступ к WiLeads-проекту space'а. CRUD-операции над лидами для интеграции с CRM, рекламными кабинетами, лендингами.

Список лидов leads:read

GET /v1/integration/leads
ПараметрТипОписание
limitint1–200, по умолчанию 50
offsetintСмещение для пагинации
statusstringUID статуса (LST entry)
manager_idintФильтр по назначенному менеджеру
company_idintФильтр по компании (см. /companies)
// Ответ
{
  "data": [
    {
      "id": 4271,
      "uid": "d1a2b3c4-...",
      "name": "Иван Петров",
      "phone": "+79001234567",
      "email": "ivan@example.com",
      "status": "new",
      "manager_id": 12,
      "company_id": 3,
      "source": "ya-direct-changan",
      "utm": { "utm_source": "yandex", "utm_campaign": "changan-uni-k" },
      "created_date": "2026-04-15T10:00:00Z",
      "modified_date": "2026-04-15T10:05:00Z"
    }
  ],
  "total": 142,
  "limit": 50,
  "offset": 0
}

Создать лид leads:write

POST /v1/integration/leads

Обязателен либо phone, либо email (желательно оба).

// Тело запроса
{
  "name": "Иван Петров",
  "phone": "+79001234567",
  "email": "ivan@example.com",
  "status": "new",
  "manager_id": 12,
  "source": "ya-direct-changan",
  "utm": {
    "utm_source": "yandex",
    "utm_medium": "cpc",
    "utm_campaign": "changan-uni-k"
  }
}

Получить лид leads:read

GET /v1/integration/leads/{id}

Обновить лид leads:write

PATCH /v1/integration/leads/{id}

Частичное обновление. Поля, не переданные в body, остаются без изменений.

Chats (чаты)

Доступ к диалогам онлайн-чата (Commy Me). По умолчанию endpoint возвращает диалоги всего space-а — всех компаний, которые в нём заведены.

Если в вашем space живёт несколько компаний (см. /companies) и нужно получить чаты только одной — передайте ?company_id=.... Без этого параметра вы увидите смешанный поток.
Write-операции (POST messages, take) требуют заголовок X-Operator-Profile-Id — ID сотрудника (profile.id integer, видно в Resisto Panel → Команда → Сотрудники), от чьего имени выполняется действие. Один API-ключ space-а может действовать от имени любого сотрудника этого space-а (slack-style on-behalf-of). Чтение (GET /chats, /messages, /stats) — без него.

Список диалогов

GET /v1/integration/chats
ПараметрТипОписание
company_idintФильтр по компании (id из /companies). Без этого — все компании space-а.
department_idintФильтр по отделу.
org_profile_iduuidАльтернатива company_id — UUID профиля в wi-streams (1:1 с компанией). Используйте только если уже знаете UUID; обычно проще через company_id.
statestringqueue / operator / closed
limitint1–200, по умолчанию 20
offsetintСмещение для пагинации
// Ответ
{
  "data": [
    {
      "id": "d1a2b3c4-...",
      "state": "operator",
      "org_profile_id": "e0fb1b21-...",
      "guest_session": {
        "display_name": "Иван",
        "phone": "+79001234567",
        "visitor_id": "d2c338ce-..."
      },
      "operator_id": "878a22ff-...",
      "page_url": "https://axsel-arh.ru/",
      "created_at": "2026-04-27T12:21:39Z",
      "updated_at": "2026-04-28T12:22:45Z",
      "closed_at": null,
      "closed_reason": null
    }
  ],
  "total": 42,
  "limit": 20,
  "offset": 0
}

org_profile_id в ответе — UUID профиля в wi-streams. Соответствует одной компании. Если хотите узнать company_id по UUID — этого endpoint нет, но соответствие стабильно: первый раз вызовите /companies + /chats?company_id=N и сопоставьте на своей стороне.

Сводная статистика

GET /v1/integration/chats/stats

Получить диалог

GET /v1/integration/chats/{id}

История сообщений

GET /v1/integration/chats/{id}/messages
// Ответ
{
  "data": [
    {
      "id": "05ddacf2-d892-...",
      "dialog_id": "d89375ec-4195-...",
      "sender_type": "system",
      "content": "Вы в очереди. Оператор скоро подключится.",
      "created_at": "2026-04-29T08:31:46Z"
    },
    {
      "id": "08ccfafb-3440-...",
      "dialog_id": "d89375ec-4195-...",
      "sender_type": "guest",
      "content": "Здравствуйте",
      "created_at": "2026-04-29T08:33:55Z"
    },
    {
      "id": "0a4c77ab-0dc5-...",
      "dialog_id": "d89375ec-4195-...",
      "sender_type": "operator",
      "sender_id": "40cf7d6f-732c-...",
      "content": "Здравствуйте!",
      "created_at": "2026-04-29T08:34:46Z"
    }
  ],
  "total": 4,
  "limit": 20,
  "offset": 0
}

sender_type: guest / operator / system / bot. sender_id заполняется только для operator и bot; для guest/system отсутствует.

Отправить сообщение

POST /v1/integration/chats/{id}/messages

Сообщение публикуется от лица конкретного сотрудника. Его ID передаётся в заголовке X-Operator-Profile-Id — как в Slack on-behalf-of-style: один API-ключ может писать от имени любого сотрудника в space-е, не нужно выпускать ключ на каждого менеджера.

ЗаголовокТипОписание
X-API-KeystringВаш ключ wi_live_…
X-Operator-Profile-IdintegerОбязательный. ID сотрудника (profile.id) от чьего имени публикуется сообщение. Видно в Resisto Panel → Команда → Сотрудники возле каждого сотрудника.
Content-Typestringapplication/json
// Тело запроса
{
  "content": "Добрый день! Да, UNI-K в наличии."
}
// Ответ 201 Created
{
  "id": "111ad1d7-53d9-...",
  "dialog_id": "d89375ec-4195-...",
  "sender_type": "operator",
  "sender_id": "40cf7d6f-732c-...",
  "content": "Добрый день! Да, UNI-K в наличии.",
  "created_at": "2026-04-29T10:48:39Z"
}

В response поле sender_id сейчас возвращает внутренний UUID. В будущей версии API оно будет sender_profile_id (integer), соответствующий тому же сотруднику.

Без X-Operator-Profile-Id endpoint вернёт 401. Это специально — все сообщения должны быть атрибутированы конкретному сотруднику (для UI чата клиента, для аудита, для метрик SLA).
Legacy: старые интеграции могут передавать вместо X-Operator-Profile-Id заголовок X-Operator-ID (UUID оператора в commy.users). Этот формат поддерживается для back-compat, но deprecated — новые интеграции делайте через X-Operator-Profile-Id.

Запуск сценария в диалоге (/bot#<id>)

Если в теле сообщения передан текст вида /bot#<scenario_id>, endpoint POST messages не публикует его как обычное сообщение, а вместо этого предлагает гостю сценарий (форма / квиз / товарная витрина) — как если бы оператор нажал «Отправить сценарий» в админке.

// Тело запроса
{
  "content": "/bot#42"
}

В ответ — system-сообщение, которое появится в ленте оператора и истории чата:

{
  "sender_type": "system",
  "content": "Оператор отправил сценарий «Контакты»",
  ...
}

Гость не увидит строку /bot#42 в чате — параллельно с system-сообщением сервер шлёт WS-event scenario_offered, SDK гостя инлайн-рендерит сценарий (карточку формы, квиза, витрины товаров — в зависимости от scenario_type).

Как узнать scenario_id: в Панели управления → WiHooks → Сценарии возле каждого сценария. У сценариев должен быть включён флаг «Доступен оператору» (available_to_operator: true) — иначе попытка /bot# вернёт 403.
Multi-brand холдинги: если в вашем space живёт несколько WiHooks-проектов (по одному на сайт/бренд) с пересекающимися локальными scenario.id, система автоматически выбирает scenario из проекта, к которому привязан диалог — через company_id компании-владельца чата (org_profile). Никаких дополнительных параметров от интегратора не требуется.

Закрыть диалог

POST /v1/integration/chats/{id}/close

Принять диалог в работу

POST /v1/integration/chats/{id}/take

Назначает сотрудника на диалог. Так же как POST messages, требует заголовок X-Operator-Profile-Id — ID того сотрудника, который «берёт» диалог.

// Запрос (тело пустое)
POST /v1/integration/chats/{id}/take
X-API-Key: wi_live_...
X-Operator-Profile-Id: 5

Slotus (бронирование)

Slotus — продукт бронирования услуг space-а: календари, ресурсы (мастера/посты), услуги, брони. Через Integration API можно строить в своей системе виджет онлайн-записи, синхронизировать брони с CRM, отмечать факт визита и ловить весь lifecycle через webhooks. Скоупы: slotus:read — чтение справочников и availability, slotus:write — создание брони и lifecycle (confirm / complete / no-show / cancel / reschedule).

Календари slotus:read

GET/v1/integration/slotus/calendars
GET/v1/integration/slotus/calendars/{id}

Возвращает все календари space-а. Поле calendar_type =3 означает resource-based календарь (один слот может обслуживать N броней одновременно — по числу свободных ресурсов). schedule — JSON-массив правил рабочих часов и обедов с day_of_week 0..6.

Свободные слоты slotus:read

GET/v1/integration/slotus/calendars/{id}/availability
ПараметрТипОписание
date_fromiso8601Начало окна (включительно)
date_toiso8601Конец окна (исключительно)
resource_idintОпц. — слоты только этого ресурса
{
  "calendar_id": 7,
  "timezone": "Europe/Moscow",
  "slot_duration": 60,
  "calendar_type": "resource",
  "total_capacity": 4,
  "resources": [
    { "id": 39, "title": "Мастер №1", "capacity": 1 }
  ],
  "slots": [
    {
      "start_time": "2026-05-04T09:00:00+00:00",
      "end_time": "2026-05-04T10:00:00+00:00",
      "is_available": true,
      "total_remaining": 3,
      "available_resources": [
        { "id": 39, "title": "Мастер №1", "remaining": 1 }
      ]
    }
  ]
}
Учитывает: schedule (working_hours / break правила), booking_buffer, существующие брони статусов pending/confirmed, calendar_event блокировки, capacity каждого ресурса. Resource-based слот доступен, если хотя бы у одного ресурса есть свободная capacity.

Ресурсы и услуги slotus:read

GET/v1/integration/slotus/resources
GET/v1/integration/slotus/resources/{id}
GET/v1/integration/slotus/resources/{id}/availability
GET/v1/integration/slotus/services

Справочники LST slotus:read

GET/v1/integration/slotus/booking-statuses

pending, confirmed, cancelled, completed, no_show, waitlist.

GET/v1/integration/slotus/visit-outcomes

Опциональный список итогов визита (LST WiLeads) — нужен при POST /complete?visit_outcome=.... Если WiLeads не активирован в space — endpoint вернёт пустой массив, бронь всё равно можно завершить.

Список броней slotus:read

GET/v1/integration/slotus/bookings
ПараметрТипОписание
companyintФильтр по компании
calendarintФильтр по календарю
resourceintФильтр по ресурсу
date_fromiso8601Начало периода
date_toiso8601Конец периода
statusstringpending/confirmed/...
limitint1..200, default 50
offsetintdefault 0

Создать бронь slotus:write

POST/v1/integration/slotus/bookings
{
  "calendar_id": 7,
  "start_time": "2026-05-04T09:00:00Z",
  "end_time": "2026-05-04T10:00:00Z",
  "title": "Тех. обслуживание",
  "contact": {
    "full_name": "Иван Петров",
    "phone": "+79991234567",
    "email": "ivan@example.com"
  },
  "create_visit": true
}

contact дедуплится через WiLeads (если он активирован в space): существующий контакт по phone/email будет переиспользован, новый — создан. create_visit: true запускает full WiLeads-funnel — lead → contact-merge → offline_visit с visit.booking=id брони. Связь visit↔booking опциональна, включается этим флагом или настройками WiHooks-сценария.

Если у календаря/ресурса есть привязка к внешней системе (Wintera 1C у дилеров) — бронь автоматически уходит туда, поле external_sync.data.external_id возвращается в ответе и записывается в booking.external_ref_id для двунаправленной синхронизации.

Конфликт слота → 409 + поле policy (hard_block | auto_suggest | notify_admin | waitlist). При auto_suggest в ответе будут suggested_slots; при waitlist бронь создаётся со статусом waitlist и автоматически промоутится в pending, когда основная бронь отменяется.

Lifecycle брони slotus:write

POST/v1/integration/slotus/bookings/{id}/confirm
POST/v1/integration/slotus/bookings/{id}/complete

Опциональные query: visit_outcome=<lst_id>, notes=<текст> — пробрасываются в связанный offline_visit при его наличии.

POST/v1/integration/slotus/bookings/{id}/no-show

Отдельный путь от cancel: клиент пропал после подтверждения. Опц. query: reason=<...>.

POST/v1/integration/slotus/bookings/{id}/cancel

Опц. query: reason=<...>.

POST/v1/integration/slotus/bookings/{id}/reschedule
{
  "new_start": "2026-05-05T10:00:00Z",
  "new_end": "2026-05-05T11:00:00Z",
  "resource_id": 39
}
Каждая lifecycle-операция: (1) меняет booking_status; (2) синкает связанные offline_visit'ы (confirmed→confirmed, completed→completed, …) — связь опциональна; (3) пушит external action в Wintera 1C, если у брони есть integration_uid+external_ref_id; (4) публикует webhook event booking.<state> с tenant-фильтром (только подписки этого space-а получат событие).

Reverse-query визитов slotus:read

GET/v1/integration/slotus/bookings/{id}/visits

Какие offline_visit привязаны к брони (по visit.booking = id). Пустой массив = бронь без визита — это нормальный кейс для броней, созданных без флага create_visit.

Webhooks

Подписка на события space'а — лиды, чаты, диалоги. Запрос с подписью HMAC-SHA256 отправляется на ваш сервер при каждом событии.

Зарегистрировать вебхук webhooks:manage

POST /v1/integration/webhooks
{
  "url": "https://your-server.com/webhooks/resisto",
  "event_types": [
    "live_chat.message.created",
    "live_chat.dialog.closed"
  ],
  "secret": "your-shared-hmac-secret",
  "is_active": true
}
Поле secret используется для подписи payload (см. Проверка подписи). Передаётся только при создании/обновлении — в ответах не возвращается, есть только флаг secret_set: true.

Список вебхуков webhooks:manage

GET /v1/integration/webhooks

Получить вебхук webhooks:manage

GET /v1/integration/webhooks/{id}

Обновить вебхук webhooks:manage

PATCH /v1/integration/webhooks/{id}

Частичное обновление: меняйте URL, секрет, типы событий или активность.

Удалить вебхук webhooks:manage

DELETE /v1/integration/webhooks/{id}

Test-доставка webhooks:manage

POST /v1/integration/webhooks/{id}/test

Отправляет на ваш URL тестовый payload — удобно для отладки HMAC-проверки и сетевого доступа.

История доставок webhooks:manage

GET /v1/integration/webhooks/{id}/deliveries

Лог последних доставок: статус, HTTP-код ответа вашего сервера, длительность, тело payload. Для отладки upstream-проблем у клиента.

Справочник event_types webhooks:manage

GET /v1/integration/webhooks/event-types

Возвращает массив доступных в текущей версии типов событий.

Типы событий

СобытиеОписание
Live Chat
live_chat.dialog.createdСоздан новый диалог
live_chat.dialog.operator_joinedОператор присоединился к диалогу
live_chat.dialog.closedДиалог закрыт
live_chat.message.createdНовое сообщение в диалоге
Slotus (бронирование)
booking.createdСоздана новая бронь (admin или public/SDK)
booking.confirmedБронь подтверждена (POST /confirm)
booking.cancelledБронь отменена (с reason в payload)
booking.completedБронь завершена (клиент пришёл, услуга оказана)
booking.no_showКлиент не пришёл (отдельный путь от cancel)
booking.rescheduledБронь перенесена на другое время
WiLeads (лиды)
lead.createdСоздан новый лид
lead.updatedЛюбое изменение лида
lead.convertedЛид сконвертирован (deal/sale)
WiLeads (визиты)
visit.createdСоздан offline_visit (вручную или привязан к брони)
visit.completedВизит получил completed (синк из booking.completed когда привязан)
visit.no_showВизит получил no_show
Streams (служебные)
message.createdСообщение в стриме
message.deletedСообщение удалено
stream.createdСоздан стрим
stream.deletedСтрим удалён
user.joinedПользователь присоединился
user.leftПользователь вышел

Пример payload для booking.confirmed:

{
  "id": "evt_",
  "type": "booking.confirmed",
  "timestamp": "2026-05-04T10:15:00Z",
  "data": {
    "space_uid": "",
    "entity_id": 2381,
    "schema": "booking",
    "action": "updated",
    "data": { "event": "booking_confirmed", "synced_visits": 1 },
    "emitted_at": "2026-05-04T10:15:00Z"
  }
}

Tenant isolation: подписки фильтруются по space-у владельца ключа — webhook одного space-а никогда не получит события другого, даже если оба интегратора подписаны на один и тот же event_type.

Формат webhook-запроса (на примере live_chat.message.created):

{
  "event": "live_chat.message.created",
  "event_id": "evt-uuid-...",
  "timestamp": "2026-04-29T08:33:55Z",
  "data": {
    "dialog_id": "d89375ec-4195-...",
    "message_id": "08ccfafb-3440-...",
    "sender_type": "guest",
    "sender_id": "40cf7d6f-...",
    "content": "Здравствуйте",
    "org_profile_id": "6233240b-e206-...",
    "created_at": "2026-04-29T08:33:55Z"
  }
}

data — плоский объект со всеми полями сообщения и контекстом диалога. org_profile_id позволяет смаппить событие на конкретную компанию через /companies + /chats?company_id= — соответствие org_profile_idcompany_id стабильно. sender_id присутствует только когда sender_type = operator или bot.

Проверка подписи

Каждый webhook-запрос подписывается секретом, заданным при регистрации вебхука. Подпись передаётся в заголовке:

X-Commy-Signature: sha256=abc123...

Алгоритм: HMAC-SHA256(secret, raw_body).

Проверка (Node.js)

const crypto = require('crypto');

function verify(rawBody, signature, secret) {
  const expected = 'sha256=' +
    crypto.createHmac('sha256', secret)
      .update(rawBody)
      .digest('hex');
  return crypto.timingSafeEqual(
    Buffer.from(signature),
    Buffer.from(expected)
  );
}

// Express-обработчик
app.post('/webhooks/resisto', express.raw({ type: 'application/json' }), (req, res) => {
  const sig = req.headers['x-commy-signature'];
  if (!verify(req.body, sig, process.env.WEBHOOK_SECRET)) {
    return res.status(401).end();
  }
  const event = JSON.parse(req.body.toString());
  // ...обработка...
  res.status(200).end();
});

Проверка (Python)

import hmac, hashlib

def verify(raw_body: bytes, signature: str, secret: str) -> bool:
    expected = 'sha256=' + hmac.new(
        secret.encode(), raw_body, hashlib.sha256
    ).hexdigest()
    return hmac.compare_digest(signature, expected)
Используйте константно-временное сравнение (timingSafeEqual / compare_digest) — не ===, чтобы исключить timing attack.

OpenAPI spec

Машиночитаемый контракт API доступен публично (без auth) и принимается Swagger UI / Redoc / Postman / oas-tooling-ом:

GET https://{space}.api.wispace.ru/v1/integration/openapi.yaml
GET https://{space}.api.wispace.ru/v1/integration/openapi.json

Спека автоматически собирается из исходного кода wi-spaces — всегда соответствует реально задеплоенным маршрутам.

Миграция со старого API

Если вы интегрировались по старой документации (Chat API, префикс /v1/live-chat/admin/*), переход на Integration API сводится к следующим заменам.

1. Префикс URL

// Было
GET /v1/live-chat/admin/dialogs?org_profile_id=...

// Стало
GET /v1/integration/chats

org_profile_id в query-параметрах больше не нужен — система автоматически скопит запрос по space'у ключа.

Важное изменение поведения (apr 2026): до апреля 2026 прокси автоподставлял org_profile_id = первого профиля в space'е, и интеграция фактически видела чаты только одной компании (даже если в space'е их несколько). Теперь по умолчанию возвращаются диалоги всех компаний space-а. Если вы полагались на прежнее поведение (один поток = одна компания) — добавьте ?company_id=... в свои запросы. Список ваших company_idGET /v1/integration/companies.

2. Формат API-ключа

БылоСтало
sk_live_…wi_live_…

Старые ключи продолжают работать; новые выпускаются с префиксом wi_live_.

3. Подпись webhook'ов

// Было
X-Webhook-Signature: sha256=...

// Стало
X-Commy-Signature: sha256=...

Алгоритм тот же — HMAC-SHA256 от тела запроса с вашим секретом.

4. Тело отправки сообщения

Без изменений — поле content (string) как было, так и осталось:

{ "content": "Текст сообщения" }

В прошлой версии этой страницы ошибочно фигурировало поле text и массив attachments — таких полей нет, бэк их игнорирует. Используйте только content.

5. Имена webhook-событий

Старое имяНовое / актуальное
live_chat.operator.joinedlive_chat.dialog.operator_joined
live_chat.dialog.updatedудалено — состояние читайте через GET /chats/{id}
live_chat.guest.typingудалено — typing-events идут только через WebSocket виджета, не через webhook

Остальные события сохранили названия: live_chat.dialog.created, live_chat.dialog.closed, live_chat.message.created.

6. Rate limit

БылоСтало
100 GET / 30 POST в минуту60 RPM единый, настраивается per-key
X-RateLimit-Reset (unix ts)Retry-After (секунды)

7. Webhook event_types

// Было — поле "events"
{ "events": ["live_chat.message.created"] }

// Стало — поле "event_types"
{ "event_types": ["live_chat.message.created"] }

8. Обратная совместимость

Старые URL /v1/live-chat/admin/* доступны для существующих интеграций как deprecated-surface. Новые интеграции делайте сразу на /v1/integration/* — этот surface развивается и обогащается scope'ами и новыми ресурсами.

Вопросы по миграции — в Telegram @team_resisto или на winwin@resisto.tech.