Программный доступ к подключённым аккаунтам мессенджеров. Один API-ключ аккаунта работает со всеми вашими профилями; конкретный профиль выбирается через profile_id. Ниже — общие правила (аутентификация, ошибки, идемпотентность, webhook'и), а полная Swagger-документация по каждой платформе живёт на отдельных страницах.
Поддерживаемый production-путь для внешних систем: профиль в кабинете, API-ключ аккаунта, webhook URL для входящих событий и импорт базы контактов из CSV/выгрузки 1C.
Создайте или подключите профиль Telegram, WhatsApp или MAX.
Скопируйте profile_id из профиля и API-ключ в «Настройки → Интеграции».
Импортируйте базу телефонов/имён, чтобы контакты появились в адресной книге профиля.
Отправляйте сообщения через sync/async endpoints нужной платформы.
Подпишитесь на webhook'и messages, delivery, connection и проверяйте HMAC.
Импорт контактов из CSV
Кабинетный endpoint принимает JSON или CSV с колонками phone/Телефон, name/Имя, last_name/Фамилия и external_id/client_id для сверки с CRM/1C. Для MAX контакты сохраняются в messenger_contacts; для Telegram/WhatsApp — в общей адресной книге профиля.
Для ручной привязки сначала получите диалог через GET /api/v1/chats?profile_id=... и возьмите из ответа поле external_chat_id или legacy alias externalChatId. Именно это значение подставляется в URL как {chat_id}. Внутренний UUID строки диалога из кабинета сюда не передаётся. Телефон, имя и CRM/1C ID передаются только в JSON body.
Если MAX lookup вернул chat_id, это и есть внешний external_chat_id для PATCH. Если клиент написал первым, телефон можно запросить чат-ботом или привязать вручную. Ручная привязка доступна только для приватных чатов; группы и каналы вернут identity.private_chat_required.
MAX Direct не отдаёт полный список диалогов до синхронизации истории: чат появляется после входящего события, отправки сообщения или добавления контакта по телефону. Номер телефона MAX может быть недоступен, поэтому UI показывает phone, displayName или внешний ID — что реально отдала сессия.
3. Аутентификация
API-ключ аккаунта передаётся в HTTP-заголовке Authorization (без префикса Bearer). Для POST/PATCH/PUT передавайте profile_id в JSON body; для GET/DELETE — в query.
Ротировать или отозвать ключ можно в «Настройки → Интеграции». Старый ключ отзывается мгновенно. Все эндпоинты требуют, чтобы Postgres был основным хранилищем (SESSION_STORE=postgres).
Профиль не найден или принадлежит другому пользователю
auth.unavailable
503
API-режим выключен (mock store)
validation.*
400
Невалидное тело запроса
recipient.not_found
404
Чат с recipient не найден в профиле
idempotency.conflict
409
Тот же Idempotency-Key, но другое тело
internal
500
Внутренняя ошибка
5. Идемпотентность
Передайте заголовок Idempotency-Key с UUID-значением для безопасного повтора запроса. Если запрос с тем же ключом приходит повторно, возвращается кэшированный ответ. TTL — 24 часа.
Ручная привязка телефона, имени, CRM/1C ID и статуса к существующему приватному чату. Для групп, каналов, bot/unknown чатов возвращает identity.private_chat_required.
Path-параметр
{chat_id} — внешний идентификатор чата из поля external_chat_id ответа GET /api/v1/chats или из alias externalChatId. Для MAX это числовой MAX chat id, например 1820755; для WhatsApp — JID; для Telegram — внешний peer/chat id. Это не внутренний UUID диалога.
Тело
profile_id обязателен. Номер телефона передаётся в phone внутри body, а не в URL. Поля contact_name, crm_external_id и identity_status опциональны.
Формирует text/vcard из такой же CSV/JSON базы для POC с отдельным MAX-телефоном. Не пишет в БД; валидные дубли пропускаются, счётчики доступны в заголовкахX-Contact-Import-*.
recipient — это external_chat_id из существующего диалога. Чат должен быть открыт хотя бы один раз, чтобы появиться в системе. Создание чата по username — на дорожной карте.
GET /api/v1/profile/me
Информация о текущем профиле: статус авторизации, имя, телефон, юзернейм.
Постраничный список диалогов профиля. Поддерживает cursor-пагинацию и отдаёт сохранённую привязку клиента. Рекомендуемый внешний формат полей — snake_case; camelCase aliases оставлены для совместимости. Для последующей привязки клиента в PATCH /api/v1/chats/{chat_id}/identity используйте именно external_chat_id из этого ответа. Для приватных WhatsApp-чатов без сохранённой identity-привязки contact_phone дополнительно выводится из JID вида 79990000000@s.whatsapp.net, а для private @lid — из provider mapping lid → phone, если WhatsApp отдал его через contacts/history/share-phone или менеджер вручную привязал номер к LID-чату. Это fallback чтения, а не автоматическая запись в CRM identity.
Параметры
limit — 1..200, по умолчанию 50
cursor — opaque-строка из nextCursor предыдущего ответа
После регистрации URL мы отправляем POST-запрос на каждое выбранное событие. Подпись HMAC-SHA256 приходит в заголовке X-Wpcl-Signature: sha256=<hex>, тип события — в X-Wpcl-Event, идентификатор доставки — в X-Wpcl-Delivery.
Валидация подписи (Node.js)
import { createHmac, timingSafeEqual } from "node:crypto";
function verify(rawBody, signatureHeader, secret) {
const sig = signatureHeader.replace(/^sha256=/, "");
const expected = createHmac("sha256", secret).update(rawBody).digest("hex");
return timingSafeEqual(Buffer.from(sig, "hex"), Buffer.from(expected, "hex"));
}
На 2xx — доставлено. На 4xx (кроме 429) — failed без ретраев. На 5xx, 429 и timeout — до 6 попыток с экспоненциальным backoff: 30s, 60s, 120s, 240s, 480s, 960s.