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?