Openbare API en webhooks
De REST API laat uw CRM, de backend van uw website of uw eigen bot werken met leads en gesprekken van cenaly.com, net zoals het paneel dat doet: kaarten lezen, eigenschappen wijzigen, gebeurtenissen verzenden, antwoorden in gesprekken. Webhooks daarentegen melden uw server zelf nieuwe leads, gebeurtenissen en berichten.
Wat u nodig hebt om te starten#
| Wat | Waar |
|---|---|
| Rol | accounteigenaar — de sleutel werkt namens hem; medewerkers zien geen sleutels |
| Sectie | ingeschakelde chat (leads en gesprekken leven daarin) |
| Sleutel | Integraties → API en webhooks → Sleutels → Sleutel aanmaken |
| API-adres | https://api.cenaly.com/public-api/v1 |
| Methodereferentie | api.cenaly.com/public-api/v1/docs |
| OpenAPI 3.1 | api.cenaly.com/public-api/v1/openapi.json |
Stap 1. Sleutel en rechten#
- Open Integraties en klik op API en webhooks boven aan de pagina.
- Klik op het tabblad Sleutels op Sleutel aanmaken en voer een naam in („CRM”, „Backend van de website”, „Telegram-bot”).
- Kies een rechtenpakket of vink rechten afzonderlijk aan, en bij meerdere vestigingen — tot welke vestigingen de sleutel toegang heeft, en de looptijd.
- Kopieer het geheim
cnk_…. Het wordt één keer getoond: bij ons wordt alleen de vingerafdruk (SHA-256) bewaard.
| Recht | Wat het geeft |
|---|---|
contacts:read |
lijst, zoeken en kaart van de lead, eigenschappen |
contacts:write |
eigenschappen en tags wijzigen, samenvoegen, verwijderen op verzoek van de betrokkene |
events:read |
gebeurtenissenfeed van de lead |
events:write |
gebeurtenissen verzenden (aankoop, registratie, elke eigen gebeurtenis) |
conversations:read |
gesprekken en berichten |
conversations:write |
antwoord van de operator, notitie, status, verantwoordelijke, labels |
messages:send |
bericht aan de lead in zijn laatste gesprek |
segments:read |
opgeslagen segmenten en hun deelnemers |
Pakketten: CRM / backend (leads, eigenschappen, gebeurtenissen, gesprekken en segmenten lezen), Eigen bot (leest leads, antwoordt in gesprekken, schrijft naar leads), Alleen lezen, Alles.
- Rechten wijzigen de rechten en vestigingen van de sleutel direct — de integratie blijft werken.
- Opnieuw uitgeven geeft een nieuw geheim; het oude werkt onmiddellijk niet meer, rechten en logboek blijven behouden.
- Intrekken — onmiddellijk en voorgoed, het volgende verzoek krijgt
401.
De sleutel wordt doorgegeven via de header Authorization: Bearer cnk_… (of X-Api-Key: cnk_…). Bewaar hem alleen op de server — niet in de browser en niet in de mobiele app.
Stap 2. Eerste verzoeken#
KEY=cnk_uw_sleutel
API=https://api.cenaly.com/public-api/v1
# wat de sleutel kan: rechten, vestigingen, limiet
curl -H "Authorization: Bearer $KEY" "$API/me"
# leads, nieuwste bovenaan (20 per pagina)
curl -H "Authorization: Bearer $KEY" "$API/contacts?limit=20"
# zoeken op naam, e-mail of telefoon
curl -H "Authorization: Bearer $KEY" "$API/contacts?q=anna"
Het antwoord is altijd een envelop:
{
"meta": { "status": 200, "requestId": "…", "nextCursor": "WyIyMDI2LTEwLTA0…" },
"data": { "total": 128, "contacts": [ { "id": "…", "status": "lead", "name": "Анна", "updatedAt": "2026-10-04T09:12:00Z" } ] }
}
De volgende pagina is hetzelfde verzoek met cursor=<meta.nextCursor>; geen nextCursor — dan zijn er geen pagina's meer. Fout — {"meta": {...}, "error": {"code": "…"}}.
Vestiging. Als de sleutel toegang heeft tot één vestiging, hoeft u die niet op te geven. Bij meerdere — voeg location=<id van de vestiging> toe (lijst — GET /v1/locations), anders volgt het antwoord 400 location_required.
Eigenschappen en gebeurtenissen op uw user_id. U hoeft ons lead-id niet te bewaren: voeg ?by=user_id toe en uw gebruikersidentificatie wordt het adres. Bestaat er nog geen lead met dat user_id — dan maken we die aan.
# eigenschappen: bewerkingen 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"
# gebeurtenissen in een batch (tot 100), herhaling met hetzelfde id telt één keer
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"
# antwoord in het gesprek en statuswijziging
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"
Het schrijven gaat via dezelfde wachtrij als wijzigingen uit het paneel: wijzigingen worden binnen seconden toegepast, en het antwoord op een schrijfactie op user_id is 202 met pending. Op de leadkaart is de auteur van de wijziging te zien als „API:
Methoden#
| Methode | Wat het doet | Recht |
|---|---|---|
GET /v1/me, GET /v1/locations |
sleutel, rechten, vestigingen | — |
GET /v1/contacts |
leads: status (anon, lead, user), q, limit, cursor |
contacts:read |
GET /v1/contacts/{id} |
kaart: eigenschappen, tags, samenvatting van gebeurtenissen | contacts:read |
POST /v1/contacts/{id}/props |
eigenschappen via bewerkingen (max. 250) of {"props":{…}} |
contacts:write |
POST / DELETE /v1/contacts/{id}/tags |
tags van de lead | contacts:write |
POST /v1/contacts/merge |
twee kaarten samenvoegen: voorbeeld, daarna "apply": true |
contacts:write |
POST /v1/contacts/{id}/erase |
verwijderen op verzoek van de betrokkene ("confirm": true) |
contacts:write |
GET /v1/contacts/{id}/events |
gebeurtenissenfeed van de lead | events:read |
POST /v1/contacts/{id}/events, POST /v1/events |
gebeurtenissen (max. 100 per keer) | events:write |
GET /v1/contacts/{id}/conversations |
gesprekken van de lead | conversations:read |
POST /v1/contacts/{id}/messages |
de lead schrijven in zijn laatste gesprek | messages:send |
GET /v1/conversations, /{id}, /{id}/messages |
gesprekken en berichten | conversations:read |
POST /v1/conversations/{id}/reply |
antwoord van de operator of een notitie ("type": "note") |
conversations:write |
POST /v1/conversations/{id}/status, /assign, /tags |
status, verantwoordelijke, labels | conversations:write |
GET /v1/segments, GET /v1/segments/{id}/contacts |
segmenten en hun deelnemers | segments:read |
Velden, voorbeelden en foutcodes van elke methode staan in de naslag.
Stap 3. Webhooks#
Webhooks worden per vestiging ingesteld: Chat → Instellingen → Webhooks — adres https, gebeurtenissen en het ondertekeningsgeheim. Naast de gespreksgebeurtenissen (nieuw gesprek, nieuw bericht, status, beoordeling, labels) zijn er nu ook leadgebeurtenissen:
| Gebeurtenis | Wanneer deze binnenkomt |
|---|---|
lead.created |
er is een nieuwe lead (contact achtergelaten in de chat, het formulier of aangemaakt via de API) |
lead.props_changed |
de eigenschappen van de lead zijn gewijzigd — lijst met sleutels in changedProps |
lead.event_tracked |
de lead heeft een gebeurtenis; standaard al uw gebeurtenissen zonder systeemgebeurtenissen ($…), de lijst met namen stelt u in met het veld „Welke gebeurtenissen versturen” |
message.goal_reached |
de lead heeft het doel van het bericht bereikt (pop-up, mailing) |
{
"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 } }
}
Naam, e-mail en telefoon van de lead komen alleen in de body als bij de webhook het vakje „Contactgegevens van de gast doorgeven” is aangevinkt. Ondertekening controleren doet u met HMAC-SHA256 over de body met het webhookgeheim:
# заголовок X-Meni-Signature: sha256=<hex>
echo -n "$BODY" | openssl dgst -sha256 -hmac "$SECRET"
Antwoord met 2xx binnen 5 seconden — anders wordt de levering herhaald; na een lange reeks mislukkingen wordt de webhook uitgeschakeld, en dat is zichtbaar in de instellingen. Filter duplicaten op deliveryId.
Beperkingen#
- 60 verzoeken per minuut per sleutel; daarboven
429met de headerRetry-After. Het restant staat inX-RateLimit-*. - Max. 200 records per pagina (standaard 50), max. 100 gebeurtenissen per batch, max. 250 bewerkingen op eigenschappen per verzoek, max. 30 tags per keer.
- Max. 20 actieve sleutels per account.
- Het aanroepenlogboek van een sleutel wordt 30 dagen bewaard: tijd, methode, padsjabloon (zonder id en body), responscode, duur.
- Gebeurtenissen die via de API worden verzonden, komen in de leadkaart terecht (feed, samenvatting, segmenten), maar niet in het ruwe logboek van de bezoekersanalyses.
- De lead schrijven kan alleen in een bestaand gesprek: geen gesprek — respons
409 no_conversation.
Problemen oplossen#
| Respons | Wat het betekent | Wat te doen |
|---|---|---|
401 api_key_missing / api_key_invalid |
de sleutel ontbreekt in het verzoek, of is onjuist, ingetrokken of verlopen | controleer de header; geef de sleutel zo nodig opnieuw uit |
403 scope_required |
de sleutel heeft niet het vereiste recht | Rechten bij de sleutel — voeg het recht toe |
400 location_required |
de sleutel heeft toegang tot meerdere vestigingen | voeg location=<id> toe |
404 location_not_found |
de vestiging hoort niet bij de vestigingen van de sleutel | controleer met GET /v1/locations |
404 not_found |
de lead of het gesprek bestaat niet | gebruik voor uw eigen id's ?by=user_id |
429 rate_limited |
meer dan 60 verzoeken per minuut | wacht Retry-After seconden, groepeer gebeurtenissen in batches |
502 upstream_error |
tijdelijke storing | herhaal het verzoek later |
Elk verzoek is zichtbaar op het tabblad Aanroepenlogboek — met de responscode en de naam van de sleutel.
Veelgestelde vragen#
Kan ik de API vanuit de browser aanroepen? Nee: de sleutel geeft toegang tot alle leads van de vestiging. Roep de API aan vanaf uw eigen server.
Waarin verschilt user_id van het id van de lead? Het id van de lead is onze identificatie van de kaart. user_id is uw identificatie van de gebruiker (nummer in het CRM, id van het account op de site); met ?by=user_id kunt u de kaart daarmee aanspreken.
Wat gebeurt er bij het opnieuw verzenden van een gebeurtenis? Een gebeurtenis met hetzelfde id wordt één keer geteld — u kunt het verzoek bij een netwerkfout gerust herhalen.
Is er een aparte sleutel per vestiging nodig? Nee: één sleutel kan met meerdere vestigingen werken, de vestiging kiest u met de parameter location.
Gerelateerde secties#
- Chat met gasten — gesprekken, leads en webhookinstellingen
- Aanvragen — één gezamenlijke inkomende stroom
- API en MCP van uw eigen telefooncentrale — aparte telefonie-API
- Integraties