Публічний API і вебхуки
REST API дає вашій CRM, бекенду сайту або власному боту працювати з лідами та діалогами cenaly.com так само, як це робить панель: читати картки, змінювати властивості, надсилати події, відповідати в діалогах. Вебхуки, навпаки, самі повідомляють вашому серверу про нові ліди, події та повідомлення.
Що потрібно для запуску#
| Що | Де |
|---|---|
| Роль | власник облікового запису — ключ діє від його імені; співробітники ключів не бачать |
| Розділ | увімкнений чат (ліди та діалоги живуть у ньому) |
| Ключ | Інтеграції → API і вебхуки → Ключі → Створити ключ |
| Адреса API | https://api.cenaly.com/public-api/v1 |
| Довідник за методами | api.cenaly.com/public-api/v1/docs |
| OpenAPI 3.1 | api.cenaly.com/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.cenaly.com/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 телефонії
- Інтеграції