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

Платформа поддерживает интеграцию с внешними системами: импорт контактов по API, автоматический экспорт лидов в CRM (amoCRM, Битрикс24) и получение уведомлений через webhook. На этой странице описаны технические детали каждого механизма.

Для партнёров. Если вы управляете клиентскими организациями Войслаб как партнёр, используйте отдельное Партнёрское API с PDF-контрактом и OpenAPI-спецификацией.

Загрузка контактов по API

Для автоматической загрузки контактов из внешней системы (CRM, формы, таблицы) создайте интеграцию типа «Загрузка контактов по API» на вкладке «Интеграции» в базе контактов. Платформа сгенерирует уникальный URL — на него нужно отправлять POST-запросы с контактами.

Запрос

POST https://voicelabs.ru/api/v1/upload-contacts/{token}
Content-Type: application/json

Параметр {token} — уникальный ключ доступа, который отображается при создании интеграции. Аутентификация не требуется — токен в URL является единственным идентификатором.

Тело запроса

JSON-массив объектов. Каждый объект — один контакт:

[
  {
    "phone": "+79001234567",
    "name": "Иванов Иван",
    "company": "ООО Ромашка",
    "city": "Москва"
  },
  {
    "phone": "+79007654321",
    "name": "Петрова Мария"
  },
  {
    "phone": "89005551234"
  }
]
ПолеТипОписание
phonestringОбязательное. Номер телефона в любом формате — система автоматически нормализует в E.164 (например, +79001234567) и всегда сохраняет как основное поле контакта
namestring Имя контакта. Всегда сохраняется как основное поле контакта и доступно в роботе через плейсхолдер {name}
любое другоеstring Дополнительные параметры (до 128 символов ключ, до 1000 символов значение). Ключи phone и name зарезервированы и не попадают сюда. Остальные поля доступны через плейсхолдеры {ключ}

Все дополнительные поля контакта сохраняются как есть и затем автоматически передаются в webhook в объекте contactFields. Зарезервированные поля phone и name не дублируются в contactFields, потому что они уже хранятся в основных полях контакта. Отдельной фильтрации по названиям или значениям сейчас нет, поэтому не передавайте в пользовательских полях чувствительные данные, если не готовы отправлять их во внешние системы.

Ограничения

  • Максимум 10 000 контактов за один запрос
  • Дубликаты номеров (уже существующих в базе или повторяющихся в запросе) пропускаются
  • Невалидные номера пропускаются (система поддерживает российские мобильные номера)
  • Нечисловые значения полей конвертируются в строку

Ответ

HTTP 200 OK

{
  "totalReceived": 3,
  "imported": 2,
  "skipped": 1
}
ПолеТипОписание
totalReceivedintВсего контактов получено в запросе
importedintУспешно импортировано
skippedintПропущено (дубликаты, невалидные номера, пустые значения)

Коды ответов

200Запрос обработан, результат в теле ответа
400Ошибка валидации: пустой массив, более 10 000 контактов, некорректный JSON
404Интеграция не найдена, неактивна или удалена

Пример (cURL)

curl -X POST https://voicelabs.ru/api/v1/upload-contacts/ВАШ_ТОКЕН \
  -H "Content-Type: application/json" \
  -d '[{"phone": "+79001234567", "name": "Иванов Иван", "company": "ООО Ромашка"}]'

Пример (Python)

import requests

url = "https://voicelabs.ru/api/v1/upload-contacts/ВАШ_ТОКЕН"
contacts = [
    {"phone": "+79001234567", "name": "Иванов Иван", "company": "ООО Ромашка"},
    {"phone": "+79007654321", "name": "Петрова Мария"}
]

response = requests.post(url, json=contacts)
print(response.json())
# {"totalReceived": 2, "imported": 2, "skipped": 0}

Интеграция с amoCRM

Платформа умеет автоматически создавать сделки и контакты в amoCRM при достижении цели звонка, а также импортировать контакты из amoCRM для обзвона.

Подключение

1

Создайте интеграцию — на вкладке «Интеграции» в базе контактов нажмите «Добавить» и выберите тип «amoCRM».

2

Укажите поддомен — часть URL вашего аккаунта amoCRM. Например, если ваш аккаунт https://mycompany.amocrm.ru, введите mycompany.

3

Получите долгосрочный токен в amoCRM: откройте амоМаркет (иконка в левом боковом меню), справа вверху нажмите на кнопку «...», затем «+ Создать интеграцию», выберите «+ Создать Внешняя интеграция», сконфигурируйте интеграцию и сгенерируйте долгосрочный токен. Вставьте его в поле «Токен».

4

Проверьте подключение — нажмите кнопку «Тест подключения». Система проверит доступ к аккаунту и покажет результат.

Импорт контактов из amoCRM

Если включён переключатель «Импорт контактов», платформа предоставит URL для вебхука. Настройте его в amoCRM:

1

Откройте амоМаркет (иконка в левом боковом меню amoCRM).

2

Справа вверху нажмите на кнопку «+ WebHooks».

3

Вставьте URL из настроек интеграции в поле адреса вебхука и отметьте событие «Создание контакта».

Также можно использовать Salesbot — настройте в нём отправку POST-запроса на этот же URL при нужном триггере.

Экспорт лидов в amoCRM

Если включён переключатель «Экспорт лидов», при достижении цели звонка платформа автоматически создаст в amoCRM:

  • Новую сделку с названием, включающим имя или номер контакта
  • Новый контакт с телефонным номером
  • Примечание к сделке с названием кампании, транскрипцией диалога и ссылкой на запись звонка

Экспорт работает через очередь с автоматическими повторными попытками (до 5 раз с увеличивающимся интервалом). Статус последней отправки и ошибки отображаются в настройках интеграции.

Интеграция с Битрикс24

Платформа умеет автоматически создавать лиды в Битрикс24 при достижении цели звонка. Интеграция работает через входящий вебхук Битрикс24 — для настройки не нужны приложения или OAuth.

Подключение

1

Создайте интеграцию — на вкладке «Интеграции» в базе контактов нажмите «Добавить» и выберите тип «Битрикс24».

2

Создайте входящий вебхук в Битрикс24: откройте ПриложенияРазработчикам, вкладка «Готовые сценарии»Другое«Входящий вебхук». В разделе «Настройка прав» отметьте CRM и нажмите «Сохранить».

3

Скопируйте URL вебхука целиком (он будет вида: https://mycompany.bitrix24.ru/rest/1/abc123secret/) и вставьте его в поле «URL вебхука» в настройках интеграции.

4

Проверьте подключение — нажмите кнопку «Тест подключения». Система проверит доступ к порталу и покажет результат.

Экспорт лидов в Битрикс24

Если включён переключатель «Экспорт лидов», при достижении цели звонка платформа автоматически создаст в CRM:

  • Новый лид с названием, номером телефона, именем контакта и транскрипцией разговора
  • Комментарий в таймлайне с транскрипцией диалога и ссылкой на запись звонка

Экспорт работает через очередь с автоматическими повторными попытками (до 5 раз с увеличивающимся интервалом). Статус последней отправки и ошибки отображаются в настройках интеграции.

Webhook-уведомления

Webhook — это один из каналов уведомлений. При каждом подходящем звонке платформа отправляет HTTP POST-запрос на указанный URL с полными данными о звонке в формате JSON.

Базовые поля звонка передаются всегда. Если у контакта были дополнительные пользовательские поля из импорта, они приходят в объекте contactFields. Поле transcript передаётся только если в настройках webhook включена опция «Передавать полную транскрипцию разговора».

HTTP-запрос

POST https://your-server.com/webhook HTTP/1.1
Content-Type: application/json
X-Webhook-Event: lead.goal_achieved
X-Webhook-Id: 3fa85f97-6e93-4c3a-aab1-8cb9d1a1d8f5
X-Webhook-Signature: sha256=a1b2c3d4e5f6...
ЗаголовокОписание
X-Webhook-Event Тип события: lead.goal_achieved (цель достигнута), call.completed (звонок завершён) или test (тестовый запрос)
X-Webhook-IdУникальный идентификатор отправки (UUID) — используйте для идемпотентности
X-Webhook-Signature HMAC-SHA256 подпись тела запроса (если настроен секретный ключ). Формат: sha256=<hex>

JSON-тело запроса

{
  "callId": "3fa85f97-6e93-4c3a-aab1-8cb9d1a1d8f5",
  "organizationName": "Моя компания",
  "callListId": "d1a2b3c4-5678-9012-abcd-ef3456789012",
  "callListName": "Обзвон клиентов",
  "callListItemId": "e5f6a7b8-9012-3456-cdef-123456789abc",
  "phoneE164": "+79001234567",
  "contactName": "Иванов Иван",
  "status": "GoalAchieved",
  "isGoalAchieved": true,
  "goalSummary": "Клиент согласился на встречу",
  "goalConversationResume": "Обсудили условия. Встреча назначена на завтра в 14:00",
  "contactFields": {
    "company": "ООО Ромашка",
    "city": "Москва"
  },
  "transcript": "Робот: Добрый день, удобно говорить?\nКлиент: Да, пару минут есть.\nРобот: Тогда коротко расскажу...",
  "durationSeconds": 125,
  "recordingUrl": "https://voicelabs.ru/public/recordings/3fa85f97.wav",
  "calledAtUtc": "2026-04-04T10:30:45Z"
}
ПолеТипОписание
callIdstring (UUID)Идентификатор звонка
organizationNamestringНазвание организации
callListIdstring (UUID)Идентификатор базы контактов
callListNamestring | nullНазвание базы контактов
callListItemIdstring (UUID)Идентификатор контакта в базе
phoneE164stringНомер телефона в формате E.164, например +79001234567
contactNamestring | nullИмя контакта (если задано)
statusstringСтатус звонка (см. таблицу ниже)
isGoalAchievedbooleantrue — цель достигнута
goalSummarystring | nullКраткий результат (заполняется при достижении цели)
goalConversationResumestring | nullРазвёрнутое резюме разговора, автоматически сформированное системой
contactFieldsobject | null Пользовательские поля контакта из импорта. Поле появляется только если у контакта есть дополнительные параметры. Все значения передаются без дополнительной фильтрации.
transcriptstring | null Полная транскрипция разговора одним текстом. Поле появляется только если для webhook включена опция передачи транскрипции.
durationSecondsintДлительность звонка в секундах
recordingUrlstring | nullСсылка на запись разговора (если доступна)
calledAtUtcstring (ISO 8601)Время звонка в UTC

Статусы звонка

GoalAchievedЦель достигнута
CallLaterПерезвонить позже
NotInterestedНе интересно
HungUpСбросил
NegativeНегатив
NoAnswerКлиент не ответил
VoicemailСработал автоответчик
SilenceКлиент молчал или не дал распознаваемого ответа
ErrorЗвонок завершился ошибкой обработки

Initiated — технический промежуточный статус активного звонка; в webhook payload он не отправляется.

Проверка подписи (HMAC-SHA256)

Если при создании webhook-уведомления указан секретный ключ, каждый запрос подписывается алгоритмом HMAC-SHA256. Подпись передаётся в заголовке X-Webhook-Signature в формате sha256=<hex>.

Алгоритм проверки:

  • Возьмите тело запроса как строку (raw body)
  • Вычислите HMAC-SHA256(body, secret) — результат в lowercase hex
  • Сравните с подписью из заголовка (без префикса sha256=)

Пример проверки (Node.js)

const crypto = require('crypto');

function verifySignature(rawBody, secret, signatureHeader) {
  const expected = crypto
    .createHmac('sha256', secret)
    .update(rawBody)
    .digest('hex');
  const received = signatureHeader.replace('sha256=', '');
  return crypto.timingSafeEqual(
    Buffer.from(expected), Buffer.from(received)
  );
}

Пример проверки (Python)

import hmac, hashlib

def verify_signature(raw_body: bytes, secret: str, signature_header: str) -> bool:
    expected = hmac.new(
        secret.encode(), raw_body, hashlib.sha256
    ).hexdigest()
    received = signature_header.replace("sha256=", "")
    return hmac.compare_digest(expected, received)

Таймаут и повторные попытки

Платформа ожидает ответ от вашего сервера не более 10 секунд. При получении HTTP-ответа с кодом 2xx запрос считается доставленным. При любой другой ошибке (код 4xx/5xx, таймаут, ошибка подключения) система выполнит повторную попытку.