Öz ATS-nizin API və MCP-si
Öz ATS-niz Cenaly proqramlarınız və AI köməkçiləriniz üçün açıqdır:
- CRM, uçot sistemi, öz saytınız — REST API: zəng jurnalı, yazılar və transkriptlər, kliklə zəng, daxili nömrələr, yönləndirmə, zəng qaydaları;
- Claude Code, Claude Desktop, Cursor — açar ilə uzaq MCP serveri;
- ChatGPT, claude.ai, Perplexity, Cursor və VS Code — həmin MCP serveri açar olmadan: siz öz hesabınıza daxil olur və girişə icazə verirsiniz (OAuth).
Hər şey hesab sahibinin adından və yalnız onun verdiyi hüquqlarla işləyir. Hər dəyişiklik ATS-in əməliyyat jurnalında açarın və ya tətbiqin adı ilə görünür.
Ünvanlar#
| Nə | Ünvan |
|---|---|
| REST API | https://api.cenaly.com/pbx-api/v1 |
| MCP serveri (streamable HTTP) | https://api.cenaly.com/pbx-api/mcp |
| Metodlar üzrə sənədləşmə | api.cenaly.com/pbx-api/v1/docs |
| OpenAPI 3.1 təsviri | api.cenaly.com/pbx-api/v1/openapi.json |
| OAuth metadataları | https://api.cenaly.com/.well-known/oauth-authorization-server/pbx-api |
Açar və hüquqlar#
Açarı yalnız hesab sahibi yaradır: Telefoniya → API və MCP → Açarlar → Açar yarat. «ATS administratoru» rollu əməkdaş açarları görmür — açar hesab sahibinin adından işləyir.
cpx_…formalı açar bir dəfə göstərilir — yaradıldıqdan dərhal sonra, qoşulma üçün hazır yapışdırmalarla birlikdə. Bizdə yalnız onun barmaq izi (SHA-256) saxlanılır, açarı bərpa etmək mümkün deyil — yalnız yenisini buraxmaq olar.- Açarı filiallarla (əks halda — gələcəklər də daxil olmaqla bütün filiallar) və müddətlə (30, 90, 365 gün və ya müddətsiz) məhdudlaşdırmaq olar.
- «Hüquqlar» açarın hüquqlarını və filiallarını dərhal dəyişir: inteqrasiya işləməyə davam edir, yeni hüquqlar növbəti sorğudan qüvvəyə minir.
- «Ləğv et» — dərhal və birdəfəlik: bu açarla növbəti sorğu 401 alacaq.
- Canlı açarlar və qoşulmalar — hesab başına 20-yə qədər.
Hüquqlar hazır dəstlə və ya işarələrlə seçilir:
| Hüquq | Nə verir | Dəstlər |
|---|---|---|
calls:read |
zəng jurnalı və marşrutu olan zəng kartı | CRM, AI köməkçisi, yalnız oxuma, hamısı |
recordings:read |
söhbətin yazısına keçid (10 dəqiqə) və transkript | CRM, AI köməkçisi, yalnız oxuma, hamısı |
calls:dial |
kliklə zəng: əvvəlcə əməkdaşın telefonu zəng çalır, cavabdan sonra ATS nömrəni yığır | CRM, AI köməkçisi, hamısı |
extensions:read |
daxili nömrələr, qruplar, yönləndirmə, «narahat etmə» | CRM, AI köməkçisi, yalnız oxuma, hamısı |
extensions:write |
şəxsi yönləndirməni və «narahat etmə»ni dəyişmək | AI köməkçisi, hamısı |
presence:read |
kim boşdur, zəng çalır, danışır | AI köməkçisi, yalnız oxuma, hamısı |
reports:read |
dövr üzrə kol-mərkəz metrikləri: xidmət səviyyəsi, gözləmə, atılmış zənglər, AHT, FCR, CSAT, zəngləri harada itiririk, növbələr, xətlər, əməkdaşlar üzrə bölgülər | yalnız oxuma, hamısı |
routes:read |
nömrələr, daxil olan və çıxan qaydalar, qaydaların tarixçəsi | yalnız oxuma, hamısı |
routes:write |
zəng qaydalarını yaratmaq, dəyişmək, silmək və yenidən sıralamaq, tarixçədən geri qaytarmaq | yalnız ayrı işarə ilə |
config:export |
ATS parametrlərinin fayl formatında ixracı | yalnız ayrı işarə ilə |
config:import |
parametrlərin cədvəllərdən yüklənməsi: önizləmə, sonra tətbiq | yalnız ayrı işarə ilə |
webhooks:write |
zəng hadisələrinin vebhuklarını yaratmaq, dəyişmək, yoxlamaq və silmək | yalnız ayrı işarə ilə |
daynight:write |
filialı günün sonuna və ya müəyyən tarixə qədər bağlamaq, açmaq — telefondan *28 ilə eynidir |
yalnız ayrı işarə ilə |
Nəyisə dəyişən və ya dəqiqə xərcləyən hüquqlar pəncərədə kəhrəbayı rənglə işarələnir. Son üç hüquq heç bir dəstə, hətta «Hamısı»na da daxil deyil — onları yalnız şüurlu şəkildə, ayrı işarə ilə vermək olar.
ChatGPT, claude.ai, Perplexity, Cursor, VS Code: açar olmadan qoşulma#
Bulud köməkçiləri açarı başlığa yapışdıra bilmir — onlar MCP serverini OAuth ilə qoşur. Açar yaratmaq lazım deyil.
claude.ai: Parametrlər → Konnektorlar → Öz konnektorunu əlavə et → https://api.cenaly.com/pbx-api/mcp ünvanını yapışdırın → Qoşul.
ChatGPT: Parametrlər → Tətbiqlər və konnektorlar → Əlavə → developer rejimini aktivləşdirin → Yarat → https://api.cenaly.com/pbx-api/mcp ünvanını yapışdırın, autentifikasiya — OAuth.
Perplexity: Hesab parametrləri → Konnektorlar → «+ Öz konnektorum» → Uzaq → https://api.cenaly.com/pbx-api/mcp ünvanını yapışdırın, autentifikasiya — OAuth.
Cursor və VS Code: https://api.cenaly.com/pbx-api/mcp ünvanlı uzaq (HTTP) MCP serverini açar başlığı olmadan əlavə edin — giriş pəncərəsi brauzerdə açılacaq. Cursor-da: .cursor/mcp.json → {"mcpServers": {"cenaly-pbx": {"url": "https://api.cenaly.com/pbx-api/mcp"}}}; VS Code-da: «MCP: Add Server» əmri → HTTP.
Sonra köməkçi Cenaly giriş pəncərəsini açacaq. Girişdən sonra görəcəksiniz:
- kim giriş istəyir — tətbiq cavabın qayıdacağı ünvana görə adlanır: «Yoxlanılmış konnektor · chatgpt.com» (eyni qaydada — claude.ai, perplexity.ai, vscode.dev, Cursor), «Bu kompüterdəki proqram» və ya «Tanımadıq ünvan» xəbərdarlığı. Tətbiqin göndərdiyi ad kiçik hərflərlə göstərilir — onu hər kəs yaza bilər;
- hüquqlar — tətbiqin istədiyi işarələnir (əgər o, «hər şeyi» istəyirsə, «AI köməkçisi» dəsti işarələnir); «yalnız ayrı işarə ilə» hüquqlar heç vaxt əvvəlcədən işarələnmir;
- filiallar — hamısı və ya seçilmişlər.
«İcazə ver» sizi köməkçiyə qaytarır və o, dərhal ATS alətlərini görür. Qoşulma Telefoniya → API və MCP → Açarlar bölməsində OAuth nişanı və tətbiqin ünvanı olan sətir kimi görünür — orada da hüquqlar dəyişdirilir və giriş ləğv edilir. Həmin tətbiqin təkrar qoşulması onun hüquqlarını yeniləyir, ikinci qoşulma yaratmır.
Qoşulmalara yalnız hesab sahibi icazə verə bilər.
Claude Code, Claude Desktop, Cursor: açar ilə qoşulma#
Claude Code — bir əmrlə:
claude mcp add --transport http telephony https://api.cenaly.com/pbx-api/mcp --header "Authorization: Bearer cpx_…"
Claude Desktop, Cursor (.cursor/mcp.json) və parametrlər faylı olan digər klientlər:
{
"mcpServers": {
"telephony": {
"type": "http",
"url": "https://api.cenaly.com/pbx-api/mcp",
"headers": { "Authorization": "Bearer cpx_…" }
}
}
}
Açarınızla hazır şablonlar açar yaradıldıqdan dərhal sonra göstərilir. AI köməkçisi yalnız açarın icazə verdiyi alətləri görür və «bu gün kim zəng edib və cavab ala bilməyib», «Annanın telefonundan bu qonağa zəng et», «mənə mobil nömrəyə yönləndirməni işə sal» kimi sorğulara cavab verə bilər.
REST API#
Açar Authorization: Bearer <açar> başlığında (və ya X-Api-Key). Açarın bir filialı varsa, location parametrini ötürmək lazım deyil; bir neçə varsa, 400 location_required cavabı onları sadalayacaq.
| Metod | Yol | İcazə | Nə edir |
|---|---|---|---|
| GET | /v1/me |
— | açarın icazələri, filialları və limitləri |
| GET | /v1/locations |
— | açarın filialları və onların ATS-i |
| GET | /v1/calls |
calls:read |
zəng jurnalı: since, until, direction, status (answered, missed, ai), number, extension, limit 100-ə qədər, cursor |
| GET | /v1/calls/{id} |
calls:read |
marşrutu ilə zəng: hansı qayda işə düşdü, kimin telefonu zəng çaldı, kim cavab verdi |
| GET | /v1/calls/{id}/recording |
recordings:read |
yazıya 10 dəqiqəlik keçid |
| GET | /v1/calls/{id}/transcript |
recordings:read |
söhbətin transkripti və yekunu |
| POST | /v1/dial |
calls:dial |
bir kliklə zəng: { "extension": "101", "number": "+995555123456" } |
| GET | /v1/dial/{commandId} |
calls:dial |
bir kliklə zəngin gedişatı |
| GET | /v1/extensions |
extensions:read |
daxili nömrələr, qruplar, yönləndirmə, «narahat etmə» |
| PUT | /v1/extensions/{ext}/forwarding |
extensions:write |
daxili nömrənin şəxsi yönləndirməsi |
| PUT | /v1/extensions/{ext}/dnd |
extensions:write |
«narahat etmə»: { "on": true } |
| GET | /v1/presence |
presence:read |
hazırda kim boşdur |
| GET | /v1/metrics |
reports:read |
dövr üzrə çağrı mərkəzinin metrikləri: from, to (filialın yerli tarixləri YYYY-MM-DD, standart — son 7 gün), compare (prev, year, prev,year və ya boş), sections (metrics,loss,queues,lines,operators,directions,heatmap,daily), callbacks=true — həmçinin geri zəng sürəti |
| GET | /v1/routes |
routes:read |
nömrələr, daxil olan və gedən zəng qaydaları |
| GET | /v1/routes/history |
routes:read |
qayda dəyişikliklərinin tarixçəsi |
| POST, PUT, DELETE | /v1/routes/inbound…, /v1/routes/outbound… |
routes:write |
zəng qaydaları bir-bir: yaratmaq, ötürülən sahələri dəyişmək, silmək, yerini dəyişmək, geri qaytarmaq |
| GET, POST | /v1/config/export, /v1/config/import |
config:export, config:import |
parametrlər fayl formatında; yükləmə — önizləmə, sonra tətbiq |
| GET | /v1/events |
calls:read |
filialın 7 günlük zəng hadisələri (2000-ə qədər): since (hadisə id-si və ya vaxt), types, limit (bir cavabda 500-ə qədər) |
| GET, POST, PATCH, DELETE | /v1/webhooks… |
webhooks:write |
vebhuklar: siyahı, yaratmaq, dəyişmək, silmək; …/rotate-secret, …/test, …/deliveries |
| GET, PUT | /v1/open-closed |
routes:read, daynight:write |
bağlıdır və nə vaxta qədər; günün sonuna qədər bağlamaq { "closed": true }, tarixə qədər { "closed": true, "until": "2026-10-05T09:00" } və ya açmaq |
Sahələrin tam təsviri — sənədləşmə səhifəsində və OpenAPI-də.
Bu gün kim zəng edib və cavab ala bilməyib:
curl -H "Authorization: Bearer cpx_…" \
"https://api.cenaly.com/pbx-api/v1/calls?status=missed&since=$(date -u +%Y-%m-%dT00:00:00Z)"
Müştəriyə 101 daxili nömrəsindən geri zəng etmək:
curl -X POST -H "Authorization: Bearer cpx_…" -H "Content-Type: application/json" \
-d '{"extension":"101","number":"+995555123456"}' "https://api.cenaly.com/pbx-api/v1/dial"
Sentyabr metrikləri, avqust və keçən ilin sentyabrı ilə müqayisədə — öz BI paneliniz üçün:
curl -H "Authorization: Bearer cpx_…" \
"https://api.cenaly.com/pbx-api/v1/metrics?from=2026-09-01&to=2026-09-30&compare=prev,year"
Cavabda metrics — Telefoniya → Zəng jurnalı → Analitika ekranındakı eyni rəqəmlər: daxil olan, qəbul edilən və buraxılan, xidmət səviyyəsi (hədd və hədəf — növbə parametrlərindən), orta və maksimum gözləmə, qısalaraq bitməyənlərsiz imtina payı, AHT, FCR, yönləndirmə və bot payı, CSAT. compare.prev və compare.year — keçən dövr və bir il əvvəlki eyni dövr üzrə eyni sahələr. Keçən il ilə müqayisə 400 günə qədər olan dövrlər üçün hesablanır.
Əgər əməkdaş 15 saniyə ərzində cavab verməyibsə, mobil nömrəyə yönləndirməni işə salmaq:
curl -X PUT -H "Authorization: Bearer cpx_…" -H "Content-Type: application/json" \
-d '{"forward":{"noAnswer":{"kind":"number","number":"+995599000111"},"noAnswerSec":15}}' \
"https://api.cenaly.com/pbx-api/v1/extensions/101/forwarding"
MCP alətləri#
REST ilə eyni əməliyyatlar. Müştəri yalnız açar və ya qoşulma ilə icazə verilmiş alətləri görür:
| Alətlər | Hüquq |
|---|---|
list_locations |
— |
list_calls, get_call |
calls:read |
get_call_recording, get_call_transcript |
recordings:read |
call_number, get_dial_status |
calls:dial |
list_extensions |
extensions:read |
set_forwarding, set_do_not_disturb |
extensions:write |
get_presence |
presence:read |
get_call_metrics |
reports:read |
list_routes, list_route_history |
routes:read |
save_inbound_rule, delete_inbound_rule, move_inbound_rule, save_outbound_rule, delete_outbound_rule, move_outbound_rule, set_outbound_calls, restore_route_version |
routes:write |
export_config |
config:export |
import_config |
config:import |
get_call_events |
calls:read |
list_webhooks, save_webhook, delete_webhook, rotate_webhook_secret, test_webhook, list_webhook_deliveries |
webhooks:write |
get_open_closed |
routes:read |
set_open_closed |
daynight:write |
Server sessiyasız işləyir (streamable HTTP, JSON-RPC 2.0): initialize, tools/list, tools/call.
Öz konnektorlarınız üçün OAuth#
Avtorizasiya serveri MCP avtorizasiya spesifikasiyasına uyğundur — onu dəstəkləyən istənilən müştəri yararlıdır:
- Tokensiz MCP sorğusu
WWW-Authenticate: Bearer resource_metadata="https://api.cenaly.com/.well-known/oauth-protected-resource/pbx-api/mcp"başlığı ilə 401 alır. - Resurs metadataları (RFC 9728) avtorizasiya serverini göstərir —
https://api.cenaly.com/pbx-api; onun metadataları (RFC 8414) isəhttps://api.cenaly.com/.well-known/oauth-authorization-server/pbx-apiünvanındadır (və…/pbx-api/.well-known/openid-configuration). - Müştərinin dinamik qeydiyyatı (RFC 7591):
POST /pbx-api/oauth/register. Qayıtma ünvanı — yalnızlocalhost/127.0.0.1(istənilən port) və ya tanınmış konnektorun ünvanı (claude.ai, claude.com, chatgpt.com, chat.openai.com, vscode.dev, www.perplexity.ai, enterprise.perplexity.ai; Cursor üçün əlavə olaraq dəqiqcursor://anysphere.cursor-mcp/oauth/callback). Müştərinin giriş üsulu —none(publik müştəri),client_secret_postvə yaclient_secret_basic. - PKCE ilə avtorizasiya kodu (yalnız
S256):GET /pbx-api/oauth/authorize→ sahibin giriş və razılıq pəncərəsi →code,statevəissilə ünvanınıza qayıdış.resourceparametri — MCP serverinin ünvanı. - Tokenlər:
POST /pbx-api/oauth/token. Kod birdəfəlikdir və 2 dəqiqə yaşayır (yanlışcode_verifieronu söndürür); giriş tokeni — 1 saat; yeniləmə tokeni — 90 gün, hər yeniləmədə yeni token verilir, əvvəlkisi işləməyi dayandırır. - Ləğv:
POST /pbx-api/oauth/revoke(RFC 7009) qoşulmanı tamamilə söndürür — «API və MCP» pəncərəsindəki «Ləğv et» kimi.
Giriş tokeni açarın qəbul edildiyi hər yerdə qəbul olunur: həm MCP-də, həm REST-də, sahibin icazə verdiyi hüquqlar və filiallarla.
Limitlər və xətalar#
- Açar və ya qoşulma üzrə: dəqiqədə 120 sorğu və gündə 20 000 (REST və MCP birlikdə).
- Kliklə zəng — ayrıca: dəqiqədə 10 və gündə 300.
- Jurnal — sorğu başına 100 zəngə qədər; filialın ATS jurnalında — son 90 günün son 400 zəngi.
| Kod | Xəta | Nə etməli |
|---|---|---|
| 401 | api_key_missing, api_key_invalid |
açar yoxdur, ləğv edilib və ya vaxtı keçib; OAuth tokeninin vaxtı keçib — onu yeniləyin |
| 403 | scope_required |
açarın hüququ yoxdur — onu «Hüquqlar» bölməsinə əlavə edin |
| 400 | location_required |
açarın bir neçə filialı var — location ötürün |
| 404 | location_not_found |
filial yoxdur və ya açar başqa filiallarla məhdudlaşdırılıb |
| 429 | rate_limited |
limit tükənib, Retry-After saniyə sonra təkrar edin |
Zəng hadisələri#
Real vaxtda — ATS vebhukları: Telefoniya → API və MCP → Vebhuklar və ya webhooks:write hüququ olan açarla POST /v1/webhooks. Sizin https ünvanınıza hər hadisə üçün saniyələr içində POST gəlir: call.started (başladı: istiqamət, kim, hara, xətt), call.ringing (kimdə zəng çalır — hər telefon üçün bir dənə), call.answered (kim cavab verdi), call.transferred (kim və kimə yönləndirdi), call.ended (nəticə, müddət, söhbət, kim cavab verdi). Vebhuku filiallara və hadisə növlərinə görə məhdudlaşdırmaq olar.
{ "id": "1727771234.56:2", "type": "call.answered", "createdAt": "2026-10-01T10:00:05Z",
"locationId": "…", "webhookId": "wh_…", "attempt": 1,
"data": { "callId": "1727771234.56", "seq": 2, "direction": "inbound",
"from": { "number": "+995555123456" }, "party": { "extension": "101", "name": "Анна" } } }
İmza — X-Cenaly-Signature: t=<unix vaxtı>,v1=<vebhuk sirri ilə "t.gövdə" üzərindən HMAC-SHA256> başlığı. Yenidən hesablayın, sabit vaxtda müqayisə edin və 5 dəqiqədən köhnə t-ni rədd edin. whsec_… sirri bir dəfə göstərilir; «Yeni sirr» əvvəlkini dərhal ləğv edir.
Çatdırılma — 10 saniyə ərzində 2xx cavabı verin. Əks halda 10 san, 30 san, 2, 5, 10, 15 və 15 dəqiqə fasilələrlə təkrar edirik (8 cəhd, təxminən bir saat); təkrar eyni id-ni daşıyır — onunla dublikatları ayırd edin. Çatdırılma jurnalı (cavab kodu, vaxt, cəhd) — vebhuk pəncərəsində və GET /v1/webhooks/{id}/deliveries; «Yoxla» xidməti webhook.ping göndərir. Ünvan 3 sutka ardıcıl heç bir çatdırılmanı qəbul etməyib — vebhuk özü sönür: sahibinə məktub gəlir, «Vebhuklar» pəncərəsində — «Avtomatik söndürülüb» qeydi və «Yandır» düyməsi (və ya { "enabled": true } ilə PATCH /v1/webhooks/{id}).
Öz serveriniz olmadan — eyni lent sorğu ilə: GET /v1/events?since=<son hadisənin id-si> və ya MCP aləti get_call_events (filialın son 7 gün üzrə hadisələri, 2000-ə qədər; cavabda — 500-ə qədər, more: true — həmin since ilə davam edin).
Yazı emal edildikdən sonra — transkripsiya və təhlillə zəng «Zənglər» bölməsində «Vebhuk» mənbəyinin vebhuku ilə gəlir.
«Açıq / bağlı» — { "closed": true } ilə PUT /v1/open-closed filialı günün sonuna qədər bağlayır (telefondan *28 kimi: zənglər «iş saatlarından kənar» qaydaları ilə gedir), false — açır; GET bağlı olub-olmadığını və kim tərəfindən bağlandığını göstərir. "until" ilə — həmin ana qədər bağlıdır (30 gündən çox olmamaqla), sonra özü açılacaq: yerdəyişməsiz vaxt (2026-10-05T09:00) filialın saat qurşağında oxunur; false onu da götürür. Marşrutlaşdırmada «*28 kodu ilə bağla» işarəsi aktiv olmalıdır (əks halda 409).
Təhlükəsizlik#
- Açar bir dəfə göstərilir və bizdə yalnız barmaq izi kimi saxlanılır; sızmış açar bir düymə ilə ləğv edilir.
- OAuth bağlantısına yalnız sahib icazə verir və girişin hansı ünvana getdiyi görünür; icazə verilmiş bağlantını hüquqlar və filiallarla məhdudlaşdırmaq və istənilən vaxt ləğv etmək olar.
- Telefon nömrələri müştərilərinizin şəxsi məlumatlarıdır: jurnal və yazılara hüquqları yalnız onlara həqiqətən ehtiyacı olan inteqrasiyalara verin.
- Açar və ya bağlantı üzrə bütün dəyişikliklər — açarın və ya tətbiqin adı ilə ATS əməliyyat jurnalındadır.