Javni API i vebhukovi
REST API omogućava vašem CRM-u, backendu sajta ili sopstvenom botu da radi sa lidovima i dijalozima cenaly.com isto kao što to radi panel: čita kartice, menja svojstva, šalje događaje, odgovara u dijalozima. Vebhukovi, obrnuto, sami obaveštavaju vaš server o novim lidovima, događajima i porukama.
Šta je potrebno za pokretanje#
| Šta | Gde |
|---|---|
| Uloga | vlasnik naloga — ključ deluje u njegovo ime; zaposleni ne vide ključeve |
| Odeljak | uključen čet (lidovi i dijalozi žive u njemu) |
| Ključ | Integracije → API i vebhukovi → Ključevi → Kreiraj ključ |
| Adresa API-ja | https://api.cenaly.com/public-api/v1 |
| Priručnik za metode | api.cenaly.com/public-api/v1/docs |
| OpenAPI 3.1 | api.cenaly.com/public-api/v1/openapi.json |
Korak 1. Ključ i prava#
- Otvorite Integracije i kliknite na API i vebhukovi u zaglavlju stranice.
- Na kartici Ključevi kliknite na Kreiraj ključ, unesite naziv („CRM“, „Backend sajta“, „Telegram-bot“).
- Izaberite skup prava ili označite prava jedno po jedno, pri više lokacija — kojim lokacijama je ključ dozvoljen, i rok.
- Kopirajte tajni ključ
cnk_…. On se prikazuje samo jednom: kod nas se čuva samo njegov otisak (SHA-256).
| Pravo | Šta daje |
|---|---|
contacts:read |
lista, pretraga i kartica lida, svojstva |
contacts:write |
menjanje svojstava i oznaka, spajanje, brisanje na zahtev subjekta |
events:read |
tok događaja lida |
events:write |
slanje događaja (kupovina, registracija, bilo koji svoj) |
conversations:read |
dijalozi i poruke |
conversations:write |
odgovor operatera, beleška, status, odgovorno lice, oznake |
messages:send |
poruka lidu u njegov poslednji dijalog |
segments:read |
sačuvani segmenti i njihovi članovi |
Skupovi: CRM / backend (lidovi, svojstva, događaji, čitanje dijaloga i segmenata), Sopstveni bot (čita lidove, odgovara u dijalozima, piše lidovima), Samo čitanje, Sve.
- Prava menjaju prava i lokacije ključa u letu — integracija nastavlja da radi.
- Ponovo izdaj izdaje novi tajni ključ; stari odmah prestaje da radi, prava i dnevnik ostaju.
- Opozovi — odmah i zauvek, sledeći zahtev će dobiti
401.
Ključ se prosleđuje zaglavljem Authorization: Bearer cnk_… (ili X-Api-Key: cnk_…). Čuvajte ga samo na serveru — ne u pregledaču i ne u mobilnoj aplikaciji.
Korak 2. Prvi zahtevi#
KEY=cnk_ваш_ключ
API=https://api.cenaly.com/public-api/v1
# šta ključ ume: prava, lokacije, limit
curl -H "Authorization: Bearer $KEY" "$API/me"
# lidovi, najnoviji prvi (20 po stranici)
curl -H "Authorization: Bearer $KEY" "$API/contacts?limit=20"
# pretraga po imenu, imejlu ili telefonu
curl -H "Authorization: Bearer $KEY" "$API/contacts?q=anna"
Odgovor je uvek koverat:
{
"meta": { "status": 200, "requestId": "…", "nextCursor": "WyIyMDI2LTEwLTA0…" },
"data": { "total": 128, "contacts": [ { "id": "…", "status": "lead", "name": "Анна", "updatedAt": "2026-10-04T09:12:00Z" } ] }
}
Sledeća stranica — isti zahtev sa cursor=<meta.nextCursor>; nema nextCursor — nema više stranica. Greška — {"meta": {...}, "error": {"code": "…"}}.
Lokacija. Ako ključu je dostupna jedna lokacija, nju nije potrebno navoditi. Ako ih je više — dodajte location=<id lokacije> (lista — GET /v1/locations), inače odgovor 400 location_required.
Svojstva i događaji po vašem user_id. Nije obavezno čuvati naš id lida: dodajte ?by=user_id, i adresa će postati vaš identifikator korisnika. Lida sa takvim user_id još nema — mi ćemo ga zavesti.
# svojstva: operacije 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"
# događaji u paketu (do 100), ponavljanje sa istim id računa se jednom
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"
# odgovor u dijalogu i promena statusa
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"
Upis ide kroz isti red kao i izmene iz panela: promene se primenjuju za nekoliko sekundi, a odgovor na upis po user_id — 202 sa pending. U kartici lida autor izmene je vidljiv kao „API: <naziv ključa>“.
Metode#
| Metoda | Šta radi | Pravo |
|---|---|---|
GET /v1/me, GET /v1/locations |
ključ, prava, lokacije | — |
GET /v1/contacts |
lidovi: status (anon, lead, user), q, limit, cursor |
contacts:read |
GET /v1/contacts/{id} |
kartica: svojstva, oznake, pregled događaja | contacts:read |
POST /v1/contacts/{id}/props |
svojstva operacijama (do 250) ili {"props":{…}} |
contacts:write |
POST / DELETE /v1/contacts/{id}/tags |
oznake lida | contacts:write |
POST /v1/contacts/merge |
spajanje dve kartice: pregled, zatim "apply": true |
contacts:write |
POST /v1/contacts/{id}/erase |
brisanje na zahtev subjekta ("confirm": true) |
contacts:write |
GET /v1/contacts/{id}/events |
traka događaja lida | events:read |
POST /v1/contacts/{id}/events, POST /v1/events |
događaji (do 100 odjednom) | events:write |
GET /v1/contacts/{id}/conversations |
razgovori lida | conversations:read |
POST /v1/contacts/{id}/messages |
pisanje lidu u njegov poslednji razgovor | messages:send |
GET /v1/conversations, /{id}, /{id}/messages |
razgovori i poruke | conversations:read |
POST /v1/conversations/{id}/reply |
odgovor operatera ili beleška ("type": "note") |
conversations:write |
POST /v1/conversations/{id}/status, /assign, /tags |
status, odgovorno lice, oznake | conversations:write |
GET /v1/segments, GET /v1/segments/{id}/contacts |
segmenti i njihovi članovi | segments:read |
Polja, primeri i kodovi grešaka za svaku metodu — u priručniku.
Korak 3. Vebhukovi#
Vebhukovi se podešavaju na lokaciji: Čet → Podešavanja → Vebhukovi — adresa https, događaji i tajna za potpis. Događajima razgovora (novi razgovor, nova poruka, status, ocena, oznake) dodati su događaji lida:
| Događaj | Kada stiže |
|---|---|
lead.created |
pojavio se novi lid (kontakt ostavljen u četu, formi ili unet preko API-ja) |
lead.props_changed |
promenila su se svojstva lida — lista ključeva u changedProps |
lead.event_tracked |
lid ima događaj; podrazumevano svi vaši događaji bez sistemskih ($…), lista imena se zadaje poljem „Koje događaje slati“ |
message.goal_reached |
lid je dostigao cilj poruke (pop-ap, slanje) |
{
"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 } }
}
Ime, imejl i telefon lida dospevaju u telo samo ako je kod vebhuka uključena kvačica „Prenositi kontakte gosta“. Provera potpisa — HMAC-SHA256 tela tajnom vebhuka:
# заголовок X-Meni-Signature: sha256=<hex>
echo -n "$BODY" | openssl dgst -sha256 -hmac "$SECRET"
Odgovorite 2xx u roku od 5 sekundi — inače će se dostava ponoviti; posle duge serije neuspeha vebhuk se isključuje, i to je vidljivo u podešavanjima. Duplikate odsecajte po deliveryId.
Ograničenja#
- 60 zahteva u minuti po ključu; preko toga —
429sa zaglavljemRetry-After. Ostatak — uX-RateLimit-*. - Do 200 zapisa po stranici (podrazumevano 50), do 100 događaja u paketu, do 250 operacija sa svojstvima po zahtevu, do 30 oznaka odjednom.
- Do 20 živih ključeva po nalogu.
- Dnevnik poziva ključa čuva se 30 dana: vreme, metoda, šablon putanje (bez id-a i tela), kod odgovora, trajanje.
- Događaji poslati preko API-ja dospevaju u karticu lida (traka, pregled, segmenti), ali ne u sirovi dnevnik analitike poseta.
- Lidu se može pisati samo u postojeći razgovor: nema razgovora — odgovor
409 no_conversation.
Rešavanje problema#
| Odgovor | Šta znači | Šta raditi |
|---|---|---|
401 api_key_missing / api_key_invalid |
ključa nema u zahtevu, ili je neispravan, opozvan ili istekao | proverite zaglavlje; po potrebi izdajte ključ ponovo |
403 scope_required |
ključ nema potrebno pravo | Prava kod ključa — dodajte pravo |
400 location_required |
ključu je dostupno nekoliko lokacija | dodajte location=<id> |
404 location_not_found |
lokacije nema među lokacijama ključa | uporedite sa GET /v1/locations |
404 not_found |
lida ili razgovora nema | za svoje id-jeve koristite ?by=user_id |
429 rate_limited |
više od 60 zahteva u minuti | sačekajte Retry-After sekundi, grupišite događaje u pakete |
502 upstream_error |
privremeni zastoj | ponovite zahtev kasnije |
Svaki zahtev je vidljiv na kartici Dnevnik poziva — sa kodom odgovora i nazivom ključa.
Česta pitanja#
Može li se API pozivati iz pregledača? Ne: ključ daje pristup svim lidovima lokacije. Pozivajte API sa svog servera.
Čime se user_id razlikuje od id-a lida? id lida — naš identifikator kartice. user_id — vaš identifikator korisnika (broj u CRM-u, id naloga na sajtu); sa ?by=user_id kartica može da se adresira njime.
Šta se dešava pri ponovnom slanju događaja? Događaj sa istim id računa se jednom — možete slobodno da ponovite zahtev pri mrežnoj grešci.
Da li je potreban poseban ključ za svaku lokaciju? Ne: jedan ključ može da radi sa nekoliko lokacija, lokacija se bira parametrom location.
Povezani odeljci#
- Čet sa gostima — razgovori, lidovi i podešavanja vebhukova
- Prijave — jedinstveni ulazni tok
- API i MCP sopstvene centrale — poseban API telefonije
- Integracije