OmniGate
Документация · API v1 ← На сайт

API и Webhook OmniGate Один REST API и единый формат webhook для WhatsApp, Telegram, MAX, VK, Instagram — и для вашего собственного канала: чата на сайте или мобильного приложения. Подключите канал в кабинете или по API — принимайте и отправляйте сообщения программно.

OmniGate нормализует все мессенджеры к одному формату. Вы создаёте сессию на канал, OmniGate присылает входящие на ваш webhook, а исходящие вы шлёте одним и тем же запросом POST /api/v1/messages — независимо от канала.

Telegram и MAX поддерживают два режима подключения: личный аккаунт и официальный бот по токену (см. параметры каналов). Для салонов есть готовая интеграция с YCLIENTS — уведомления о записи без единой строки кода.

Базовый URL

https://omnigate.website

Все запросы — по HTTPS. Тело запросов и ответы — в формате application/json (UTF-8). Размер тела запроса — до 2 МБ.

Подключение каналов (скан QR, ввод SMS-кода, облачный пароль 2FA) удобнее всего выполнять в личном кабинете — там это пошаговый визард. Через API доступны те же действия, если вы автоматизируете подключение.

Авторизация

Запросы к API авторизуются ключом в заголовке X-API-Key. Поддерживается и форма Authorization: Bearer <ключ>.

Где взять ключ

  1. Войдите в личный кабинет → раздел API-ключи.
  2. Нажмите Создать ключ. Полный ключ показывается один раз — сразу сохраните его.
  3. В списке остаётся только префикс ключа. Потерянный ключ нельзя восстановить — отзовите его и создайте новый.
Заголовок авторизации
X-API-Key: og_live_xxxxxxxxxxxxxxxxxxxxxxxx
Ключ без ограничений даёт полный доступ к вашим сессиям и сообщениям. Храните его в переменных окружения на сервере и никогда не вставляйте в код фронтенда или публичные репозитории. Скомпрометированный ключ отзовите в кабинете.

Если ключ не передан — 401 «нужен X-API-Key». Если ключ неверный или отозван — 401 «неверный или отозванный API-ключ».

Права ключа

При создании ключа можно отметить только те права, которые нужны интеграции. Это полезно, когда ключ уходит подрядчику, стороннему сервису или ИИ-агенту: такой ключ сможет, например, читать переписку, но не отправлять сообщения и не удалять каналы.

ПравоЧто открывает
sessions:readПросмотр каналов: GET /api/v1/sessions, GET /api/v1/sessions/{id}.
sessions:writeСоздание, изменение и удаление каналов, вход по коду: POST, PATCH, DELETE /api/v1/sessions…
messages:readИстория переписки: GET /api/v1/messages.
messages:sendОтправка сообщений и файлов: POST /api/v1/messages, POST /api/v1/messages/upload.
messages:inboundПриём входящих из своего канала: POST /api/v1/messages/inbound.
events:readПоток новых сообщений в реальном времени: GET /api/v1/events (SSE).
webhook:readНастройки вебхука и журнал доставок: GET /api/v1/webhook, GET /api/v1/webhook/deliveries.
webhook:writeСмена адреса и секрета, тест и повтор доставки: PUT /api/v1/webhook, POST /api/v1/webhook/rotate, /test, /deliveries/{id}/retry.
webchat:readСписок виджетов веб-чата и код вставки: GET /api/v1/webchat.
webchat:writeСоздание, настройка и удаление виджетов: POST, PATCH, DELETE /api/v1/webchat…
account:readТариф, лимиты и текущий расход: GET /api/v1/account.
Ключ с ограниченными правами не попадёт на эндпоинт, для которого право ещё не заведено — ответ будет 403. Ключ без ограничений («полный доступ») работает везде, включая новые эндпоинты.

Если у ключа нет нужного права, приходит 403, а в теле — какое право требуется и какие есть у ключа:

403 — не хватает права
{
  "ok": false,
  "error": "у ключа нет права «messages:send» — выпустите ключ с этим правом в кабинете",
  "scope": "messages:send",
  "scopes": ["sessions:read", "messages:read"]
}
Права можно изменить в кабинете в любой момент — кнопка Права в списке ключей. Сам ключ при этом не меняется, перевыпускать и менять его в коде не нужно. Ключи, созданные до появления прав, работают как раньше — у них полный доступ.

Журнал обращений

Каждый запрос к /api/v1 попадает в журнал: время, ключ, метод и путь, код ответа и длительность. Журнал виден в кабинете рядом со списком ключей — по нему удобно понять, какая интеграция получила 403 или 429 и когда ключ использовался в последний раз. Записи хранятся 30 дней.

Термины и сущности

ТерминЧто это
Канал (channel)Мессенджер: whatsapp, telegram, max, vk, instagram.
Сессия (session)Подключённый аккаунт канала. У сессии есть id (UUID), status и опциональный webhookUrl. Все сообщения идут через конкретную сессию.
chatIdИдентификатор диалога/собеседника внутри канала — куда отправлять ответ. Формат зависит от канала (см. ниже).
Входящее (inbound)Сообщение от собеседника. OmniGate сохраняет его и, если задан webhookUrl, доставляет POST-запросом на ваш сервер.
Исходящее (outbound)Сообщение, которое вы отправляете через POST /api/v1/messages.
WebhookВаш HTTPS-эндпоинт, на который OmniGate присылает входящие сообщения в реальном времени.
API-ключСекрет для авторизации запросов. Привязан к вашему аккаунту, видит только ваши сессии.
Главное правило: чтобы ответить собеседнику, возьмите sessionId и chatId прямо из входящего webhook и передайте их в POST /api/v1/messages. Не нужно вычислять идентификаторы вручную.

Быстрый старт за 5 шагов

  1. Получите API-ключ в кабинете (раздел «API-ключи»).
  2. Подключите канал: в кабинете отсканируйте QR (WhatsApp/Telegram) или введите номер и код (MAX). Дождитесь статуса connected.
  3. Укажите webhookUrl сессии — ваш HTTPS-адрес для входящих.
  4. Примите тестовое сообщение: напишите на подключённый аккаунт — OmniGate пришлёт его на ваш webhook.
  5. Ответьте через POST /api/v1/messages, используя sessionId и chatId из webhook.
Отправить первое сообщение — curl
curl -X POST https://omnigate.website/api/v1/messages \
  -H "X-API-Key: og_live_xxx" \
  -H "Content-Type: application/json" \
  -d '{
    "sessionId": "1f1d…uuid",
    "chatId": "79991234567",
    "text": "Привет из OmniGate!"
  }'

Подключение каналов

Сессия — это подключённый аккаунт. Создать её можно из кабинета (рекомендуется для входа по QR/коду) или через API.

POSTСоздать сессию

POST/api/v1/sessions
ПолеТипОписание
channel обязательноstringОдин из: whatsapp, telegram, max, vk, instagram, webchat. Для своего сайта или приложения принимаются псевдонимы site, web, custom, widget — все они создают канал webchat (см. мост своего канала).
credentials опц.objectПараметры доступа канала (см. таблицу). Для WhatsApp/Telegram — пустой объект (вход по QR).
webhookUrl опц.stringHTTPS-адрес для входящих. Можно задать позже. Если не задан — сообщения только сохраняются в истории.
Запрос
POST /api/v1/sessions
X-API-Key: og_live_xxx

{
  "channel": "max",
  "credentials": { "phone": "79991234567" },
  "webhookUrl": "https://your-crm.ru/hook?token=SECRET"
}
Ответ 200
{
  "ok": true,
  "session": {
    "id": "1f1d…uuid",
    "channel": "max",
    "status": "awaiting_code",
    "webhookUrl": "https://your-crm.ru/hook?token=SECRET",
    "hasCredentials": true,
    "createdAt": 1750000000000
  }
}

Дальше действуйте по status: для WhatsApp/Telegram опрашивайте сессию и сканируйте QR, для MAX — отправьте SMS-код (см. вход по коду).

Лимит активных каналов зависит от тарифа. При его превышении — 402 с описанием лимита. Обновить тариф можно в кабинете.

Параметры каналов

КаналcredentialsКак входит
WhatsApp{}Скан QR из приложения: Настройки → Связанные устройства. Статус qrconnected.
Telegram личный{}Личный аккаунт (userbot). Скан QR: Настройки → Устройства → Подключить устройство. Возможен шаг пароля 2FA.
Telegram бот{ "botToken": "123456:AA…" }Официальный бот. Токен от @BotFather. Подключается сразу, без QR и без телефона. Пишет только тем, кто сам первым написал боту.
MAX личный{ "phone": "7999…" }Личный аккаунт по номеру. SMS-код, затем (если включён) облачный пароль 2FA.
MAX бот{ "botToken": "..." }Официальный бот. Токен от @MasterBot. Подключается сразу по токену.
VK{ "groupId": "...", "accessToken": "..." }Сообщество. Токен с правами на сообщения из настроек сообщества. Подключается сразу.
Instagram{ "igId": "...", "pageAccessToken": "..." }Через Meta (бизнес-аккаунт + страница Facebook). Подключается сразу.
Свой сайт / приложение webchat{} — сервер сгенерирует самКонтейнер для собственного источника сообщений. Учётные данные (в т.ч. publicKey) выдаёт OmniGate; присланные в запросе — игнорируются. Оформление задаётся полями title, color, welcome, webchatEnabled в корне тела запроса. Подключается сразу. См. мост своего канала.
Личный аккаунт vs бот. Личные аккаунты (WhatsApp, Telegram-QR, MAX-телефон) пишут от вашего номера и могут инициировать диалог. Боты (Telegram/MAX по токену, VK, Instagram) подключаются мгновенно по токену, но, как правило, отвечают только тем, кто написал первым. Для Telegram канал один — telegram; режим выбирается наличием botToken в credentials.

Статусы сессии и вход по коду

Узнать текущее состояние и QR можно в любой момент:

GET/api/v1/sessions/{id}

Ответ: { ok, session, qr }, где qr — data-URL картинки (для WhatsApp/Telegram, пока требуется скан).

statusЗначение
createdЗапись создана, ещё не запускалась.
connectingИдёт подключение.
qrНужно отсканировать QR (вернётся в поле qr).
awaiting_codeОжидается код подтверждения (MAX — SMS-код).
awaiting_passwordОжидается облачный пароль 2FA (MAX/Telegram).
connectedГотово принимать и отправлять сообщения.
disconnectedОтключено.
errorОшибка подключения. Создайте сессию заново.

POSTПодтвердить вход по коду

POST/api/v1/sessions/{id}/code

Передайте code (SMS-код) и, если аккаунт защищён двухфакторным паролем, далее — password. Нужно передать code или password.

Шаг 1 — SMS-код
POST /api/v1/sessions/1f1d…/code
{ "code": "12345" }

// если включена 2FA, ответ вернёт status: "awaiting_password"
Шаг 2 — облачный пароль 2FA
POST /api/v1/sessions/1f1d…/code
{ "password": "мой_облачный_пароль" }

// при успехе status станет "connected"

DELETEОстановить и удалить сессию

DELETE/api/v1/sessions/{id}

Останавливает подключение и удаляет сессию. Ответ: { ok: true }.


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

Единый эндпоинт для всех каналов. Текст или медиа — в одном запросе.

POST/api/v1/messages
ПолеТипОписание
sessionId обязательноstringID подключённой сессии (статус connected).
chatId обязательноstringКому отправить. Проще всего — взять из входящего webhook (см. формат).
text текст*stringТекст сообщения. Обязателен, если нет mediaUrl.
mediaUrl медиа*stringПубличный URL файла. Включает режим отправки медиа.
kind опц.stringТип медиа: photo (по умолчанию) или document.
caption опц.stringПодпись к медиа.

* Нужно передать либо text, либо mediaUrl.

Текст

POST /api/v1/messages
{
  "sessionId": "1f1d…uuid",
  "chatId": "79991234567",
  "text": "Ваш заказ №1024 готов к выдаче 📦"
}

Медиа (фото / документ)

POST /api/v1/messages
{
  "sessionId": "1f1d…uuid",
  "chatId": "79991234567",
  "mediaUrl": "https://cdn.your-crm.ru/invoice-1024.pdf",
  "kind": "document",
  "caption": "Счёт на оплату"
}

Ответ

200 — успех / 502 — ошибка канала
// 200
{ "ok": true, "messageId": "a1b2c3" }

// 502 — провайдер не принял сообщение
{ "ok": false, "error": "описание причины" }
Отправка учитывается в месячном лимите тарифа. При превышении — 402 с описанием лимита.

Формат chatId по каналам

КаналchatId
MAXID чата (число) или номер телефона собеседника (79991234567 / +7…) — OmniGate сам найдёт диалог.
WhatsAppНомер телефона собеседника в международном формате без «+».
TelegramID диалога/пользователя из входящего сообщения.
VKID пользователя VK.
InstagramID пользователя Instagram (из входящего).
Свой сайт / приложение webchatИдентификатор собеседника задаёте вы сами — любая строка до 120 символов (client-42, crm-user-77, e-mail, ID из вашей базы). Он и станет ключом диалога в истории и в amoCRM. Виджет на сайте выдаёт свои ID вида v-ab12cd…; при работе через API повторять этот формат не нужно.
Самый надёжный способ — копировать chatId из поля chatId входящего webhook и использовать его как есть для ответа.

Мост своего канала: свой сайт или приложение

Не все диалоги приходят из мессенджеров. Чат на вашем сайте, мобильное приложение, виджет в личном кабинете, форма обратной связи, любая внешняя платформа — всё это можно завести в OmniGate как обычный канал. Тогда переписка с такими собеседниками попадает в ту же историю, в тот же кабинет, в те же вебхуки и в то же зеркало amoCRM, что и WhatsApp или Telegram. Никакого отдельного кода под каждый источник — один и тот же формат входящих и исходящих.

Работает это в три шага: создать канал-контейнер, класть в него входящие и отвечать обычной отправкой.

Шаг 1. Создать канал

Тот же POST /api/v1/sessions, только channelsite (псевдонимы web, custom, widget; каноническое имя канала — webchat). Учётные данные генерирует сервер, передавать нечего. Канал подключается сразу, без QR и кодов: status сразу connected.

Запрос
POST /api/v1/sessions
X-API-Key: og_live_xxx

{
  "channel": "site",
  "title": "Чат на сайте",
  "webchatEnabled": false,
  "webhookUrl": "https://your-crm.ru/hook?token=SECRET"
}
Ответ 200
{
  "ok": true,
  "session": {
    "id": "255a385c…uuid",
    "channel": "webchat",
    "status": "connected",
    "publicKey": "wc_1fb0a677ee9c308ce7cc76da",
    "embed": "<script>…</script>"
  }
}
Что вернулосьЗачем
session.idСерверный идентификатор канала. Его вы подставляете в sessionId при приёме и отправке сообщений по API-ключу. Секретный — только для вашего бэкенда.
publicKeyПубличный ключ виджета (wc_…). Нужен, только если вы ставите на сайт готовый виджет OmniGate: им авторизуются браузерные ручки /webchat/:publicKey/…. Если пишете свой фронт и ходите через API — он вам не понадобится.
embedГотовый <script> для вставки на страницу — тот же виджет одной строкой.
publicKey отдаётся ровно один раз — в ответе на создание канала. Дальше credentials из API вырезаются, и увидеть ключ можно только в кабинете. Сохраните его сразу, если планируете ставить виджет.
"webchatEnabled": false — если вы не используете виджет OmniGate, а шлёте сообщения со своего бэкенда. Это выключает браузерное окно чата, но не ломает канал: приём по API, история, вебхуки и amoCRM продолжают работать как обычно.

Шаг 2. Класть входящие

Каждое сообщение вашего пользователя отправляйте на эту ручку — она серверная, авторизуется вашим X-API-Key.

POST/api/v1/messages/inbound
ПолеОписание
sessionId обяз.ID канала-контейнера из шага 1.
chatId обяз.Идентификатор собеседника у вас — любая строка до 120 символов (по нему потом отвечаете и по нему же группируется диалог).
textТекст входящего, до 4000 символов. Обязателен, если нет mediaUrl.
fromNameИмя отправителя (показывается в кабинете и amoCRM), до 80 символов.
from опц.Технический идентификатор отправителя. По умолчанию равен chatId.
mediaUrl, mediaKindПубличная ссылка на вложение и его тип (photo/video/document).
webhook опц.false — не доставлять это входящее на ваш webhookUrl. Синоним: deliverWebhook. Подробнее — в примечании ниже.
Пример: зафиксировать входящее
curl -X POST https://omnigate.website/api/v1/messages/inbound \
  -H 'X-API-Key: ВАШ_КЛЮЧ' -H 'Content-Type: application/json' \
  -d '{"sessionId":"<id>","chatId":"client-42","text":"Здравствуйте!","fromName":"Иван"}'

// 200
{ "ok": true, "chatId": "client-42" }

Дальше сообщение идёт по тому же конвейеру, что и входящее из мессенджера: попадает в историю, живьём появляется в кабинете, зеркалится в amoCRM (если у канала включено «Зеркалить в amoCRM» и amoCRM подключён по OAuth) и доставляется на ваш webhookUrl — с подписью, SSRF-проверкой и ретраями (до 6 попыток: 2, 4, 8, 16, 32 секунды).

Когда отключать вебхук. Если входящие вам присылает та же ваша система, которая слушает webhookUrl, доставлять их обратно бессмысленно — она получит эхо собственного сообщения. В этом случае добавьте в тело "webhook": false: всё остальное (история, кабинет, amoCRM) отработает как обычно, вебхук просто не будет поставлен в очередь. Вебхук нужен в обратной ситуации — когда сообщения кладёт один сервис (например, фронт сайта), а обрабатывает их другой.

Шаг 3. Отвечать

Ответ оператора или вашего бота — обычный POST /api/v1/messages с тем же sessionId и chatId. Исходящее тоже логируется и зеркалится в amoCRM, и — если посетитель сидит в виджете — мгновенно доезжает до него по SSE. Всю переписку можно поднять через GET /api/v1/messages.

Две двери для входящих — и когда какая. Публичная ручка виджета POST /webchat/:publicKey/message вызывается прямо из браузера посетителя, поэтому ограничена 30 сообщениями в минуту с одного IP и требует chatId строго вида v-…. Серверная POST /api/v1/messages/inbound ходит с вашего бэкенда по API-ключу, попадает под общий лимит 120 запросов в минуту на ключ и принимает произвольный chatId — можно сразу класть свой ID пользователя из CRM или базы. Если у вас есть собственный бэкенд, используйте вторую.

Полный двусторонний мост: ответы менеджера из amoCRM → в ваш канал

Чтобы ответы, написанные менеджером внутри amoCRM, доходили до вашего получателя, задайте у канала Webhook доставки (кабинет → карточка канала → «Вебхук и детали» → «Webhook доставки», либо PATCH /api/v1/sessions/:id { "deliveryWebhookUrl": "https://..." }). OmniGate будет POST-ить туда каждый ответ менеджера — с подписью и ретраями (до 6 попыток) — а вы доставите его своему пользователю.

Что придёт на Webhook доставки
POST https://ваш-адрес/delivery   // подпись: X-OmniGate-Signature (как у входящих)
{
  "event": "outgoing", "direction": "out", "source": "amocrm",
  "sessionId": "<id>", "chatId": "client-42",
  "text": "Ответ менеджера", "timestamp": 1789300000000
}

Итого полный цикл кастомного канала: входящее → POST /api/v1/messages/inbound (в amoCRM); ваш ответ → POST /api/v1/messages (в amoCRM); ответ менеджера из amoCRM → на ваш Webhook доставки. Обе стороны видны в amoCRM, и переписка ходит в обе стороны.

Приём сообщений (Webhook)

Если у сессии задан webhookUrl, каждое входящее сообщение OmniGate доставляет на этот адрес POST-запросом с телом application/json. Формат единый для всех каналов.

Формат входящего

ПолеТипОписание
channelstringКанал, откуда сообщение.
sessionIdstringID сессии. Используйте его для ответа.
chatIdstringДиалог/собеседник — куда отвечать.
fromstringОтправитель (id / телефон / username).
textstring | nullТекст сообщения (null, если только вложение).
attachmentsarrayВложения: [{ type, url? }]. Может отсутствовать.
timestampnumberВремя получения, Unix-время в миллисекундах.
rawobjectИсходный payload канала «как есть» — на случай, если нужны специфичные поля.
Пример входящего на ваш webhook
POST https://your-crm.ru/hook?token=SECRET
Content-Type: application/json

{
  "channel": "whatsapp",
  "sessionId": "1f1d…uuid",
  "chatId": "79991234567",
  "from": "79991234567",
  "text": "Здравствуйте! Заказ ещё актуален?",
  "attachments": [],
  "timestamp": 1750000000000,
  "raw": { /* исходные данные канала */ }
}

Требования к вашему эндпоинту

  • Принимайте POST с телом JSON, отвечайте кодом 2xx (например, 200).
  • Отвечайте быстро — таймаут запроса 10 секунд. Тяжёлую обработку выносите в очередь, а webhook просто подтверждайте.
  • Эндпоинт должен быть доступен по HTTPS.

Повторные попытки

Если ваш сервер ответил не-2xx или не ответил за 10 с, OmniGate повторит доставку с нарастающей задержкой — до 6 попыток: через 2, 4, 8, 16 и 32 секунды. После исчерпания попыток сообщение остаётся в истории (его можно забрать через GET /api/v1/messages).

Подпись запроса (проверка подлинности)

Каждая доставка подписана. Заголовки запроса:

ЗаголовокОписание
X-OmniGate-TimestampUnix-время отправки в миллисекундах.
X-OmniGate-Signaturesha256=<hex> — HMAC-SHA256 от строки timestamp + "." + body, ключ — ваш секрет подписи (раздел «Webhook» кабинета).
X-OmniGate-DeliveryУникальный ID доставки — используйте для идемпотентности при повторах.
Node.js — проверка подписи
const crypto = require('crypto');

function verify(req, rawBody, secret) {
  const ts = req.headers['x-omnigate-timestamp'];
  const sig = req.headers['x-omnigate-signature'] || '';
  const want = 'sha256=' + crypto.createHmac('sha256', secret)
    .update(ts + '.' + rawBody).digest('hex');
  return crypto.timingSafeEqual(Buffer.from(sig), Buffer.from(want));
}
Дополнительно. Можно также добавить в webhookUrl секретный токен в query-строке (например ?token=SECRET) и проверять его на своей стороне — это работает и без проверки HMAC.

Как обновить webhookUrl

Адрес задаётся при создании сессии (webhookUrl) или меняется в кабинете в настройках канала.

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

GET/api/v1/messages?sessionId={id}&limit=50&before={ts}
ПараметрОписание
sessionId опц.Фильтр по сессии. Без него — по всем вашим сессиям.
limit опц.Сколько вернуть. По умолчанию 50, максимум 200.
before опц.Курсор пагинации: вернуть записи старше этого created_at (мс).
Ответ — отсортировано от новых к старым
{
  "ok": true,
  "messages": [
    {
      "id": 9012,
      "session_id": "1f1d…uuid",
      "direction": "in",        // in — входящее, out — исходящее
      "chat_id": "79991234567",
      "body": "Заказ ещё актуален?",
      "created_at": 1750000000000
    }
  ]
}
История хранится ограниченное время и периодически очищается (ретеншн). Для долгого хранения сохраняйте сообщения у себя при получении на webhook.

Все эндпоинты

База: https://omnigate.website. Авторизация — X-API-Key (кроме служебных webhook-приёмников).

Машиночитаемое описание API — /openapi.json (OpenAPI 3.1): импортируется в Postman и Insomnia, из него генерируются клиенты, его же читают ИИ-агенты. Краткая выжимка для языковых моделей — /llms.txt.
МетодПутьНазначение
POST/api/v1/sessionsСоздать сессию канала
GET/api/v1/sessionsСписок сессий со статистикой
GET/api/v1/sessions/{id}Статус сессии + QR
PATCH/api/v1/sessions/{id}Вебхуки канала, зеркало в amoCRM, ИИ-агент
POST/api/v1/sessions/{id}/codeПодтвердить код / пароль 2FA
POST/api/v1/sessions/{id}/resolveНайти chatId по @username (личный Telegram)
DEL/api/v1/sessions/{id}Остановить и удалить сессию
POST/api/v1/messagesОтправить сообщение (текст/медиа)
POST/api/v1/messages/uploadЗагрузить файл (base64) и отправить
POST/api/v1/messages/inboundПринять входящее из своего канала (мост)
GET/api/v1/messagesИстория сообщений
GET/api/v1/eventsПоток новых сообщений в реальном времени (SSE)
GET/api/v1/webhookАдрес вебхука и секрет подписи
PUT/api/v1/webhookЗадать или очистить адрес ({ "url": … })
POST/api/v1/webhook/rotateПеревыпустить секрет подписи
POST/api/v1/webhook/testОтправить тестовый подписанный запрос
GET/api/v1/webhook/deliveriesЖурнал доставок вебхука
POST/api/v1/webhook/deliveries/{id}/retryПовторить доставку
GET/api/v1/webchatВиджеты веб-чата и код вставки
POST/api/v1/webchatСоздать виджет веб-чата
PATCH/api/v1/webchat/{id}Настроить виджет (заголовок, цвет, приветствие)
DEL/api/v1/webchat/{id}Удалить виджет
GET/api/v1/accountТариф, лимиты и расход за месяц
POST/mcpТот же API для ИИ-агентов по Model Context Protocol
Ручки /webhook, /webchat, /events и /account работают от лица владельца ключа — они возвращают и меняют данные того аккаунта, которому ключ выдан.

MCP для ИИ-агентов

Тот же API открыт по Model Context Protocol: если ваш агент или ИИ-ассистент умеет подключать MCP-серверы, писать обёртки над curl не нужно — он сам увидит список инструментов, их параметры и подсказки, когда какой применять.

Три точки входа для агента

Агенту достаточно один раз показать одну из трёх машиночитаемых точек входа. Дальше вы пишете обычными словами — «отправь Анне, что заказ собран», — а он сам решает, какой запрос сделать.

Что дать агентуАдресКому подходит
MCP-сервер (самое удобное)https://omnigate.website/mcpClaude Desktop, Cursor, Cline, VS Code Copilot, n8n — любой клиент с поддержкой MCP
Выжимка для ИИ, текстом/llms.txtАгент без MCP, но с доступом в интернет: ChatGPT, Gemini, свой агент на LangChain
Спека OpenAPI 3.1/openapi.jsonPostman и Insomnia, генераторы клиентов, разработчик, который пишет интеграцию руками
Ключ во всех трёх случаях один и тот жеX-API-Key из раздела «API» в кабинете. Агенту выдавайте отдельный ключ с минимальными правами (обычно хватает sessions:read, messages:read, messages:send), а не тот, которым живёт ваш бэкенд. Права меняются у уже выпущенного ключа — перевыпускать его и править конфиг агента не нужно, а отзыв ключа отрубает агенту доступ мгновенно.
POST/mcp
ПараметрЗначение
Адресhttps://omnigate.website/mcp
ТранспортStreamable HTTP — одно JSON-RPC 2.0 сообщение в теле POST, ответ обычным application/json
Авторизациятот же заголовок X-API-Key (принимается и Authorization: Bearer)
Версии протокола2025-11-25, 2025-06-18, 2025-03-26
Методыinitialize, ping, tools/list, tools/call
Лимит240 JSON-RPC запросов в минуту на аккаунт

Подключение клиента

Имена полей у разных клиентов немного отличаются, но смысл один — адрес и заголовок с ключом:

конфигурация MCP-клиента
{
  "mcpServers": {
    "omnigate": {
      "type": "http",
      "url": "https://omnigate.website/mcp",
      "headers": { "X-API-Key": "og_live_xxxxxxxxxxxxxxxxxxxxxxxx" }
    }
  }
}

Инструменты

22 инструмента — по одному на каждый эндпоинт /api/v1:

ГруппаИнструменты
Каналыchannels_list, channel_get, channel_create, channel_update, channel_delete, channel_resolve_username, channel_submit_login_code
Сообщенияmessages_history, message_send, message_send_file, message_receive
Вебхукwebhook_get, webhook_set, webhook_rotate_secret, webhook_test, webhook_deliveries, webhook_delivery_retry
Веб-чатwebchat_widgets_list, webchat_widget_create, webchat_widget_update, webchat_widget_delete
Аккаунтaccount_get
tools/call — отправить сообщение
POST /mcp
X-API-Key: og_live_xxxxxxxxxxxxxxxxxxxxxxxx
Content-Type: application/json

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "message_send",
    "arguments": {
      "sessionId": "3f2b8c1e-0f4a-4b7d-9a2e-1c5d6e7f8a90",
      "chatId": "79991234567",
      "text": "Здравствуйте! Заказ уже в пути."
    }
  }
}

Обычные команды вместо технических

Перезапустите клиент и проверьте подключение первой же фразой — «покажи, какие инструменты OmniGate тебе доступны». Агент ответит списком (channels_list, message_send, messages_history и остальные), и дальше технические слова не нужны:

  • Какие у меня подключены каналы и все ли в порядке?
  • Напиши в WhatsApp на 79991234567: «Заказ собран, привезём завтра до 12».
  • Покажи последние 20 сообщений из телеграм-канала поддержки.
  • Куда сейчас уходят входящие? Переключи вебхук на https://мой-сервис.ru/hook.
  • Сколько сообщений я израсходовал в этом месяце и сколько каналов оплачено?
  • Создай виджет чата для сайта с заголовком «Чем помочь?» и синим цветом.

Две вещи стоит сказать агенту заранее — это экономит круг переписки. chatId не выдумывать: это идентификатор собеседника внутри канала, и брать его нужно из истории сообщений, из входящего вебхука или через channel_resolve_username. Канал должен быть connected: если статус другой, пусть агент сначала посмотрит канал — там может ждать QR-код на пересканирование.

Агент без MCP — одна стартовая фраза

Если ваш клиент MCP не умеет, но умеет ходить в интернет и делать HTTP-запросы, хватит одного стартового сообщения. Скопируйте его целиком и подставьте свой ключ:

стартовое сообщение для агента без MCP
Прочитай https://omnigate.website/llms.txt — это описание API сервиса OmniGate,
через который у меня подключены мессенджеры. Мой ключ: og_live_xxxxxxxxxxxxxxxxxxxxxxxx,
передавай его заголовком X-API-Key. Дальше выполняй мои просьбы про сообщения
и каналы через этот API. Если запрос вернёт ошибку — прочитай текст ошибки,
там по-русски написано, что делать. chatId не выдумывай: бери его из истории
сообщений или из входящего вебхука.

/llms.txt — короткая выжимка того же, что на этой странице: с чего начать, что такое канал и chatId, все эндпоинты, лимиты, права ключа и формат входящего вебхука. Агент прочитает её один раз и дальше будет составлять запросы сам; команды ему пишутся те же, что выше.

Чего агент сделать не сможет

И это намеренно: выпускать новые API-ключи (ключ, выпускающий ключи, обходит любые ограничения прав), менять тариф и платить, заходить в админку, проходить OAuth amoCRM и YCLIENTS. Всё это остаётся за человеком в кабинете. Ещё два ограничения — секрет подписи вебхука и поток событий — описаны ниже.

Что стоит учесть

  • Права работают точно так же. Инструмент выполняется от лица владельца ключа тем же кодом, что и REST, поэтому права ключа, лимиты тарифа и рейт-лимит действуют идентично. Обойти их через MCP нельзя.
  • tools/list уже отфильтрован по правам вашего ключа: чего в списке нет — того ключу не разрешили. Вызовы попадают в тот же журнал обращений с пометкой mcp: перед путём.
  • Отказ сервиса — не ошибка протокола. Нехватка прав, лимит тарифа, недоступный мессенджер приходят как обычный результат с isError: true и текстом на русском, в котором сказано, что делать. Ошибкой JSON-RPC отвечают только нарушения протокола: -32602 — неизвестный инструмент, -32601 — неизвестный метод, -32700 — не разобрать тело.
  • Секрет подписи вебхука через MCP не выдаётся. webhook_get возвращает hasSecret и последние 4 символа — контекст агента слишком легко утекает. Полный секрет — в кабинете или запросом GET /api/v1/webhook.
  • SSE-потока среди инструментов нет — поток не укладывается в один вызов. Вместо /api/v1/events опрашивайте messages_history.
Полное описание /mcp есть и в /openapi.json, и в выжимке для языковых моделей /llms.txt.

Коды ошибок

HTTPКогда
400Неверные параметры запроса (нет обязательных полей, неизвестный канал).
401Нет ключа, либо ключ неверный/отозванный.
402Превышен лимит тарифа (каналы или сообщения за месяц). Обновите тариф.
403У ключа нет права на эту операцию. В теле — scope (какое право нужно) и scopes (какие есть у ключа).
404Сессия не найдена или принадлежит другому аккаунту.
413Сообщение длиннее 4000 символов.
429Слишком часто: 120 запросов в минуту на аккаунт (для публичных ручек виджета — 30 сообщений в минуту с одного IP). В ответе — поле retryAfter и заголовок Retry-After в секундах.
502Сообщение не принято каналом (см. поле error в ответе).

Тело ответа при ошибке всегда содержит { "ok": false, "error": "…" }.

Готовая интеграция: amoCRM

OmniGate подключается к amoCRM как чат-канал: входящие из мессенджеров появляются в чатах amoCRM (раздел «Беседы» / «Неразобранное»), ответы менеджеров уходят клиенту обратно в тот же мессенджер. Программировать ничего не нужно — интеграция включается из кабинета.

Подключение

  • Кабинет → раздел amoCRM → кнопка «Подключить через amoCRM» → войдите в свой amoCRM и нажмите «Разрешить».
  • Подключение выполняется под администратором аккаунта amoCRM и занимает меньше минуты.

Воронки: куда падают заявки

Для каждого канала (номера) можно выбрать свою воронку — новые обращения будут создавать «Неразобранное» именно в ней:

  • в разделе amoCRM кабинета — блок «Куда падают заявки» со списком всех каналов;
  • или в карточке канала: «Вебхук и детали» → «Воронка amoCRM».

Если воронка не выбрана — обращения идут в воронку по умолчанию.

Что зеркалится

  • Входящие текстовые сообщения клиентов — в чат amoCRM.
  • Ответы встроенного ИИ-агента — тоже видны в чате amoCRM (как исходящие).
  • Ответ менеджера из карточки amoCRM — доставляется клиенту в мессенджер.
  • Зеркалирование можно выключить для отдельного канала (галочка в карточке канала).
ИИ-агент и webhookUrl. Встроенный ИИ-агент поддержки отвечает только в каналах без заданного webhookUrl. Если у канала настроен вебхук — считается, что отвечает ваша внешняя система (через POST /api/v1/messages), и встроенный агент молчит.

Готовая интеграция: YCLIENTS

Для салонов и студий, работающих в YCLIENTS, подключение делается без кода — прямо в кабинете. OmniGate сам ловит события записи и рассылает клиентам уведомления и напоминания через любой ваш подключённый канал (WhatsApp, Telegram, MAX, VK).

Как это работает

  1. Устанавливаете приложение OmniGate из маркетплейса YCLIENTS (или привязываете филиал вручную по его ID и user-токену).
  2. В кабинете выбираете, через какой канал (сессию) отправлять сообщения клиентам филиала.
  3. Включаете нужные типы уведомлений и задаёте свои шаблоны текста. Готово — сообщения уходят автоматически.

Типы уведомлений

ТипКогда отправляется
Создание записиКлиент записался — сразу подтверждение с датой, услугой и мастером.
Изменение записиПеренос даты/времени или услуги — уведомление об изменениях.
Отмена записиЗапись удалили или отменили — сообщение об отмене.
Напоминание «до»За N часов до визита (настраивается) — напоминание прийти.
Сообщение «после»Через N часов после визита — благодарность/просьба об отзыве.

Шаблоны

Каждый тип уведомления — это свой шаблон с подстановками. Доступные переменные:

ПеременнаяЗначение
{client}Имя клиента
{date}Дата визита
{time}Время визита
{service}Название услуги
{master}Имя мастера
{company}Название филиала
Пример шаблона
{client}, вы записаны на «{service}» к мастеру {master}
{date} в {time}. Ждём вас в «{company}»!
Ничего кодить не нужно. Интеграция YCLIENTS настраивается в личном кабинете: филиалы, канал отправки, типы уведомлений и шаблоны. REST API из этой документации нужен, только если вы хотите свою логику поверх сообщений.
Один филиал YCLIENTS привязывается к одному аккаунту OmniGate. Если филиал уже подключён к другому аккаунту, привязка вернёт ошибку 409.

Примеры интеграции

Node.js — webhook-приёмник и авто-ответ

Express
import express from 'express';
const app = express(); app.use(express.json());

const API = 'https://omnigate.website';
const KEY = process.env.OMNIGATE_KEY;

app.post('/hook', async (req, res) => {
  // 1) проверяем секрет из query-строки
  if (req.query.token !== process.env.HOOK_SECRET) return res.sendStatus(403);

  // 2) сразу подтверждаем приём (важно — до тяжёлой логики)
  res.sendStatus(200);

  const { sessionId, chatId, text } = req.body;
  if (!text) return;

  // 3) отвечаем тем же диалогом
  await fetch(`${API}/api/v1/messages`, {
    method: 'POST',
    headers: { 'X-API-Key': KEY, 'Content-Type': 'application/json' },
    body: JSON.stringify({ sessionId, chatId, text: `Вы написали: ${text}` })
  });
});

app.listen(8080);

Python — отправка сообщения

requests
import requests

requests.post(
    "https://omnigate.website/api/v1/messages",
    headers={"X-API-Key": "og_live_xxx"},
    json={
        "sessionId": "1f1d…uuid",
        "chatId": "79991234567",
        "text": "Заявка принята, менеджер свяжется с вами.",
    },
    timeout=30,
)

Сценарий для CRM

Типовая интеграция с amoCRM / Битрикс24 / YCLIENTS:

  1. Входящее с webhook создаёт/находит сделку или клиента по from / chatId.
  2. Текст сообщения добавляется в карточку как примечание.
  3. Ответ менеджера из CRM уходит обратно через POST /api/v1/messages с тем же sessionId и chatId.
  4. Шаблонные уведомления (статус заказа, запись на услугу) шлются тем же эндпоинтом по событию в CRM.