Публичный API и вебхуки
REST API даёт вашей CRM, бэкенду сайта или собственному боту работать с лидами и диалогами meni.ge так же, как это делает панель: читать карточки, менять свойства, отправлять события, отвечать в диалогах. Вебхуки, наоборот, сами сообщают вашему серверу о новых лидах, событиях и сообщениях.
Что нужно для запуска#
| Что | Где |
|---|---|
| Роль | владелец аккаунта — ключ действует от его имени; сотрудники ключей не видят |
| Раздел | включённый чат (лиды и диалоги живут в нём) |
| Ключ | Интеграции → API и вебхуки → Ключи → Создать ключ |
| Адрес API | https://api.meni.ge/public-api/v1 |
| Справочник по методам | api.meni.ge/public-api/v1/docs |
| OpenAPI 3.1 | api.meni.ge/public-api/v1/openapi.json |
Шаг 1. Ключ и права#
- Откройте Интеграции и нажмите API и вебхуки в шапке страницы.
- На вкладке Ключи нажмите Создать ключ, введите название («CRM», «Бэкенд сайта», «Telegram-бот»).
- Выберите набор прав или отметьте права по одному, при нескольких точках — к каким точкам ключ допущен, и срок.
- Скопируйте секрет
cnk_…. Он показывается один раз: у нас хранится только его отпечаток (SHA-256).
| Право | Что даёт |
|---|---|
contacts:read |
список, поиск и карточка лида, свойства |
contacts:write |
менять свойства и теги, склеивать, удалять по запросу субъекта |
events:read |
лента событий лида |
events:write |
отправлять события (покупка, регистрация, любое своё) |
conversations:read |
диалоги и сообщения |
conversations:write |
ответ оператора, заметка, статус, ответственный, метки |
messages:send |
сообщение лиду в его последний диалог |
segments:read |
сохранённые сегменты и их участники |
Наборы: CRM / бэкенд (лиды, свойства, события, чтение диалогов и сегментов), Свой бот (читает лидов, отвечает в диалогах, пишет лидам), Только чтение, Всё.
- Права меняют права и точки ключа на лету — интеграция продолжает работать.
- Перевыпустить выдаёт новый секрет; старый перестаёт работать сразу, права и журнал остаются.
- Отозвать — сразу и навсегда, следующий запрос получит
401.
Ключ передаётся заголовком Authorization: Bearer cnk_… (или X-Api-Key: cnk_…). Храните его только на сервере — не в браузере и не в мобильном приложении.
Шаг 2. Первые запросы#
KEY=cnk_ваш_ключ
API=https://api.meni.ge/public-api/v1
# что умеет ключ: права, точки, лимит
curl -H "Authorization: Bearer $KEY" "$API/me"
# лиды, свежие сверху (20 на страницу)
curl -H "Authorization: Bearer $KEY" "$API/contacts?limit=20"
# поиск по имени, почте или телефону
curl -H "Authorization: Bearer $KEY" "$API/contacts?q=anna"
Ответ — всегда конверт:
{
"meta": { "status": 200, "requestId": "…", "nextCursor": "WyIyMDI2LTEwLTA0…" },
"data": { "total": 128, "contacts": [ { "id": "…", "status": "lead", "name": "Анна", "updatedAt": "2026-10-04T09:12:00Z" } ] }
}
Следующая страница — тот же запрос с cursor=<meta.nextCursor>; нет nextCursor — страниц больше нет. Ошибка — {"meta": {...}, "error": {"code": "…"}}.
Точка. Если ключу доступна одна точка, её указывать не нужно. Если несколько — добавьте location=<id точки> (список — GET /v1/locations), иначе ответ 400 location_required.
Свойства и события по вашему user_id. Не обязательно хранить наш id лида: добавьте ?by=user_id, и адресом станет ваш идентификатор пользователя. Лида с таким user_id ещё нет — мы его заведём.
# свойства: операции update_or_create, set_once, add, delete, append, union, exclude
curl -X POST -H "Authorization: Bearer $KEY" -H "Content-Type: application/json" \
-d '{"ops":[{"op":"update_or_create","key":"$email","value":"anna@example.com"},
{"op":"add","key":"orders","value":1},
{"op":"union","key":"interests","value":"yoga"}]}' \
"$API/contacts/u-1001/props?by=user_id"
# события пачкой (до 100), повтор с тем же id засчитывается один раз
curl -X POST -H "Authorization: Bearer $KEY" -H "Content-Type: application/json" \
-d '{"events":[{"id":"ord-5531","userId":"u-1001","name":"order_paid","props":{"sum":45,"currency":"GEL"}}]}' \
"$API/events"
# ответ в диалоге и смена статуса
curl -X POST -H "Authorization: Bearer $KEY" -H "Content-Type: application/json" \
-d '{"text":"Здравствуйте! Заказ передан курьеру."}' "$API/conversations/<id>/reply"
curl -X POST -H "Authorization: Bearer $KEY" -H "Content-Type: application/json" \
-d '{"status":"resolved"}' "$API/conversations/<id>/status"
Запись идёт через ту же очередь, что правки из панели: изменения применяются за секунды, а ответ на запись по user_id — 202 с pending. В карточке лида автор правки виден как «API: <название ключа>».
Методы#
| Метод | Что делает | Право |
|---|---|---|
GET /v1/me, GET /v1/locations |
ключ, права, точки | — |
GET /v1/contacts |
лиды: status (anon, lead, user), q, limit, cursor |
contacts:read |
GET /v1/contacts/{id} |
карточка: свойства, теги, сводка событий | contacts:read |
POST /v1/contacts/{id}/props |
свойства операциями (до 250) или {"props":{…}} |
contacts:write |
POST / DELETE /v1/contacts/{id}/tags |
теги лида | contacts:write |
POST /v1/contacts/merge |
склейка двух карточек: превью, затем "apply": true |
contacts:write |
POST /v1/contacts/{id}/erase |
удаление по запросу субъекта ("confirm": true) |
contacts:write |
GET /v1/contacts/{id}/events |
лента событий лида | events:read |
POST /v1/contacts/{id}/events, POST /v1/events |
события (до 100 за раз) | events:write |
GET /v1/contacts/{id}/conversations |
диалоги лида | conversations:read |
POST /v1/contacts/{id}/messages |
написать лиду в его последний диалог | messages:send |
GET /v1/conversations, /{id}, /{id}/messages |
диалоги и сообщения | conversations:read |
POST /v1/conversations/{id}/reply |
ответ оператора или заметка ("type": "note") |
conversations:write |
POST /v1/conversations/{id}/status, /assign, /tags |
статус, ответственный, метки | conversations:write |
GET /v1/segments, GET /v1/segments/{id}/contacts |
сегменты и их участники | segments:read |
Поля, примеры и коды ошибок каждого метода — в справочнике.
Шаг 3. Вебхуки#
Вебхуки настраиваются у точки: Чат → Настройки → Вебхуки — адрес https, события и секрет подписи. К событиям диалога (новый диалог, новое сообщение, статус, оценка, метки) добавились события лида:
| Событие | Когда приходит |
|---|---|
lead.created |
появился новый лид (контакт оставлен в чате, форме или заведён через API) |
lead.props_changed |
изменились свойства лида — список ключей в changedProps |
lead.event_tracked |
у лида событие; по умолчанию все ваши события без системных ($…), список имён задаётся полем «Какие события слать» |
message.goal_reached |
лид достиг цели сообщения (поп-ап, рассылка) |
{
"event": "lead.event_tracked",
"deliveryId": "WD…",
"at": "2026-10-04T09:12:03Z",
"webhookId": "…",
"locationId": "…",
"contact": { "id": "…", "status": "user", "userId": "u-1001", "props": { "orders": 3 }, "tags": ["vip"] },
"leadEvent": { "name": "order_paid", "at": "2026-10-04T09:12:00Z", "props": { "sum": 45 } }
}
Имя, почта и телефон лида попадают в тело, только если у вебхука включена галка «Передавать контакты гостя». Проверка подписи — HMAC-SHA256 тела секретом вебхука:
# заголовок X-Meni-Signature: sha256=<hex>
echo -n "$BODY" | openssl dgst -sha256 -hmac "$SECRET"
Ответьте 2xx за 5 секунд — иначе доставка повторится; после длинной серии неудач вебхук отключается, и это видно в настройках. Дубли отсекайте по deliveryId.
Ограничения#
- 60 запросов в минуту на ключ; сверх —
429с заголовкомRetry-After. Остаток — вX-RateLimit-*. - До 200 записей на страницу (по умолчанию 50), до 100 событий в пачке, до 250 операций со свойствами за запрос, до 30 тегов за раз.
- До 20 живых ключей на аккаунт.
- Журнал вызовов ключа хранится 30 дней: время, метод, шаблон пути (без id и тела), код ответа, длительность.
- События, отправленные через API, ложатся в карточку лида (лента, сводка, сегменты), но не в сырой журнал аналитики посещений.
- Написать лиду можно только в существующий диалог: нет диалога — ответ
409 no_conversation.
Устранение неполадок#
| Ответ | Что значит | Что делать |
|---|---|---|
401 api_key_missing / api_key_invalid |
ключа нет в запросе, либо он неверный, отозван или истёк | проверьте заголовок; при необходимости перевыпустите ключ |
403 scope_required |
у ключа нет нужного права | Права у ключа — добавьте право |
400 location_required |
ключу доступно несколько точек | добавьте location=<id> |
404 location_not_found |
точки нет среди точек ключа | сверьтесь с GET /v1/locations |
404 not_found |
лида или диалога нет | для своих id используйте ?by=user_id |
429 rate_limited |
больше 60 запросов в минуту | подождите Retry-After секунд, группируйте события пачками |
502 upstream_error |
временный сбой | повторите запрос позже |
Каждый запрос виден на вкладке Журнал вызовов — с кодом ответа и названием ключа.
Частые вопросы#
Можно ли вызывать API из браузера? Нет: ключ даёт доступ ко всем лидам точки. Вызывайте API со своего сервера.
Чем user_id отличается от id лида? id лида — наш идентификатор карточки. user_id — ваш идентификатор пользователя (номер в CRM, id аккаунта на сайте); с ?by=user_id карточку можно адресовать им.
Что будет при повторной отправке события? Событие с тем же id засчитывается один раз — можно смело повторять запрос при сетевой ошибке.
Нужен ли отдельный ключ на каждую точку? Нет: один ключ может работать с несколькими точками, точка выбирается параметром location.
Связанные разделы#
- Чат с гостями — диалоги, лиды и настройки вебхуков
- Заявки — единый входящий поток
- API и MCP своей АТС — отдельный API телефонии
- Интеграции