C cenaly.com
Започни бесплатно

Јавен API и вебхуци

Клучеви со привилегии, REST API за потенцијални клиенти, својства, настани, разговори и сегменти, вебхуци за нови потенцијални клиенти и настани — со curl примери

On this page 9

Јавен 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. Клуч и права#

  1. Отворете Интеграции и кликнете API и вебхуци во заглавието на страницата.
  2. На јазичето Клучеви кликнете Создај клуч, внесете име („CRM“, „Бекенд на сајтот“, „Telegram-бот“).
  3. Изберете збир на права или означете права едно по едно, при повеќе локации — на кои локации клучот е дозволен, и рок.
  4. Копирајте ја тајната 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.

Поврзани раздели#

Was this article helpful?