सार्वजनिक 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"
5 सेकंड में 2xx जवाब दें — वरना डिलीवरी दोहराई जाएगी; लंबी नाकामी की श्रृंखला के बाद वेबहुक बंद हो जाता है, और यह सेटिंग्स में दिखता है। दोहराव deliveryId से छाँटें।
सीमाएँ#
- प्रति कुंजी 60 अनुरोध प्रति मिनट; इससे ज़्यादा पर —
Retry-Afterहेडर के साथ429। शेष —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 पैरामीटर से चुनी जाती है।
संबंधित अनुभाग#
- मेहमानों से चैट — बातचीत, लीड और वेबहुक सेटिंग्स
- अनुरोध — एक ही इनबॉक्स प्रवाह
- अपने PBX का API और MCP — टेलीफ़ोनी का अलग API
- एकीकरण