C cenaly.com
Почати безкоштовно

API та MCP своєї АТС

Ключі та права, REST API, MCP-сервер для Claude та Cursor, підключення ChatGPT і claude.ai через OAuth без ключа, приклади, ліміти та помилки

On this page 10

API і MCP власної АТС

Власна АТС Cenaly відкрита для ваших програм та ШІ-асистентів:

  • CRM, облікова система, власний сайт — REST API: журнал дзвінків, записи та розшифровки, дзвінок в один клік, додаткові, переадресація, правила дзвінків;
  • Claude Code, Claude Desktop, Cursor — віддалений MCP-сервер за ключем;
  • ChatGPT, claude.ai, Perplexity, Cursor і VS Code — той самий MCP-сервер без ключа: ви входите у свій обліковий запис і дозволяєте доступ (OAuth).

Усе працює від імені власника облікового запису і лише з правами, які він надав. Кожна зміна видна в журналі дій АТС із назвою ключа або додатка.

Адреси#

Що Адреса
REST API https://api.cenaly.com/pbx-api/v1
MCP-сервер (streamable HTTP) https://api.cenaly.com/pbx-api/mcp
Документація за методами api.cenaly.com/pbx-api/v1/docs
Опис OpenAPI 3.1 api.cenaly.com/pbx-api/v1/openapi.json
Метадані OAuth https://api.cenaly.com/.well-known/oauth-authorization-server/pbx-api

Ключ і права#

Ключ створює лише власник облікового запису: Телефонія → API і MCP → Ключі → Створити ключ. Співробітник із роллю «Адміністратор АТС» ключів не бачить — ключ діє від імені власника.

  • Ключ виду cpx_… показується один раз — одразу після створення, разом із готовими вставками для підключення. У нас зберігається лише його відбиток (SHA-256), відновити ключ неможливо — тільки випустити новий.
  • Ключ можна обмежити точками (інакше — усі точки, включно з майбутніми) і терміном (30, 90, 365 днів або безстроково).
  • «Права» змінюють права й точки ключа на льоту: інтеграції продовжують працювати, нові права діють із наступного запиту.
  • «Відкликати» — одразу й назавжди: наступний запит із цим ключем отримає 401.
  • Живих ключів і підключень — до 20 на обліковий запис.

Права вибираються готовим набором або галочками:

Право Що дає Набори
calls:read журнал дзвінків і картка дзвінка з маршрутом CRM, ШІ-асистент, лише читання, усе
recordings:read посилання на запис розмови (10 хвилин) і розшифровка CRM, ШІ-асистент, лише читання, усе
calls:dial дзвінок в один клік: спочатку дзвонить телефон співробітника, після відповіді АТС набирає номер CRM, ШІ-асистент, усе
extensions:read додаткові, групи, переадресація, «не турбувати» CRM, ШІ-асистент, лише читання, усе
extensions:write змінювати особисту переадресацію та «не турбувати» ШІ-асистент, усе
presence:read хто вільний, дзвонить, розмовляє ШІ-асистент, лише читання, усе
reports:read метрики кол-центру за період: рівень обслуговування, очікування, покинуті, AHT, FCR, CSAT, де втрачаємо дзвінки, розрізи за чергами, лініями, співробітниками лише читання, усе
routes:read номери, правила вхідних і вихідних, історія правил лише читання, усе
routes:write створювати, змінювати, видаляти й переставляти правила дзвінків, відкочувати з історії лише окремою галочкою
config:export вивантаження налаштувань АТС у форматі файлу лише окремою галочкою
config:import завантаження налаштувань із таблиць: попередній перегляд, потім застосування лише окремою галочкою
webhooks:write заводити, змінювати, перевіряти й видаляти вебхуки подій дзвінків лише окремою галочкою
daynight:write закрити точку до кінця доби або до дати, відкрити — те саме, що *28 з телефона лише окремою галочкою

Права, які щось змінюють або витрачають хвилини, у вікні позначені янтарним. Три останніх права не входять до жодного набору, навіть до «Усе» — їх можна дати лише усвідомлено, окремою галочкою.

ChatGPT, claude.ai, Perplexity, Cursor, VS Code: підключення без ключа#

Хмарні асистенти не вміють вставляти ключ у заголовок — вони підключають MCP-сервер через OAuth. Ключ створювати не потрібно.

claude.ai: Налаштування → Конектори → Додати свій конектор → вставте https://api.cenaly.com/pbx-api/mcp → Підключити.

ChatGPT: Налаштування → Додатки та конектори → Додатково → увімкніть режим розробника → Створити → вставте https://api.cenaly.com/pbx-api/mcp, автентифікація — OAuth.

Perplexity: Налаштування облікового запису → Конектори → «+ Свій конектор» → Віддалений → вставте https://api.cenaly.com/pbx-api/mcp, автентифікація — OAuth.

Cursor і VS Code: додайте віддалений (HTTP) MCP-сервер з адресою https://api.cenaly.com/pbx-api/mcp без заголовка з ключем — вікно входу відкриється в браузері. У Cursor: .cursor/mcp.json → {"mcpServers": {"cenaly-pbx": {"url": "https://api.cenaly.com/pbx-api/mcp"}}}; у VS Code: команда «MCP: Add Server» → HTTP.

Далі асистент відкриє вікно входу Cenaly. Після входу ви побачите:

  • хто просить доступ — додаток називається за адресою, куди повернеться відповідь: «Перевірений конектор · chatgpt.com» (так само — claude.ai, perplexity.ai, vscode.dev, Cursor), «Програма на цьому комп'ютері» або попередження «Незнайома адреса». Назва, яку надіслав додаток, показана дрібно — її може написати будь-хто;
  • права — позначено те, що просить додаток (якщо він просить «усе підряд», позначено набір «ШІ-асистент»); права «лише окремою галочкою» заздалегідь не позначаються ніколи;
  • точки — усі або вибрані.

«Дозволити» повертає вас до асистента, і він одразу бачить інструменти АТС. Підключення з'являється в Телефонія → API і MCP → Ключі рядком із міткою OAuth та адресою додатка — там само змінюються права й відкликається доступ. Повторне підключення того самого додатка оновлює його права, а не заводить друге підключення.

Дозволяти підключення може лише власник облікового запису.

Claude Code, Claude Desktop, Cursor: підключення за ключем#

Claude Code — однією командою:

claude mcp add --transport http telephony https://api.cenaly.com/pbx-api/mcp --header "Authorization: Bearer cpx_…"

Claude Desktop, Cursor (.cursor/mcp.json) та інші клієнти з файлом налаштувань:

{
  "mcpServers": {
    "telephony": {
      "type": "http",
      "url": "https://api.cenaly.com/pbx-api/mcp",
      "headers": { "Authorization": "Bearer cpx_…" }
    }
  }
}

Готові вставки з вашим ключем показуються одразу після створення ключа. ШІ-помічник бачить лише інструменти, дозволені ключем, і може відповісти на «хто сьогодні телефонував і не додзвонився», «передзвони цьому гостю з телефона Анни», «увімкни мені переадресацію на мобільний».

REST API#

Ключ — у заголовку Authorization: Bearer <ключ> (або X-Api-Key). Якщо в ключа одна точка, параметр location можна не передавати; якщо кілька — відповідь 400 location_required перелічить їх.

Метод Шлях Право Що робить
GET /v1/me — права, точки та ліміти ключа
GET /v1/locations — точки ключа та їхні АТС
GET /v1/calls calls:read журнал дзвінків: since, until, direction, status (answered, missed, ai), number, extension, limit до 100, cursor
GET /v1/calls/{id} calls:read дзвінок із маршрутом: яке правило спрацювало, чий телефон дзвонив, хто відповів
GET /v1/calls/{id}/recording recordings:read посилання на запис на 10 хвилин
GET /v1/calls/{id}/transcript recordings:read розшифрування та підсумок розмови
POST /v1/dial calls:dial дзвінок в один клік: { "extension": "101", "number": "+995555123456" }
GET /v1/dial/{commandId} calls:dial як проходить дзвінок в один клік
GET /v1/extensions extensions:read додаткові, групи, переадресація, «не турбувати»
PUT /v1/extensions/{ext}/forwarding extensions:write особиста переадресація додаткового
PUT /v1/extensions/{ext}/dnd extensions:write «не турбувати»: { "on": true }
GET /v1/presence presence:read хто вільний прямо зараз
GET /v1/metrics reports:read метрики кол-центру за період: from, to (місцеві дати точки YYYY-MM-DD, усталено — останні 7 днів), compare (prev, year, prev,year або порожньо), sections (metrics,loss,queues,lines,operators,directions,heatmap,daily), callbacks=true — ще й швидкість передзвону
GET /v1/routes routes:read номери, правила вхідних і вихідних
GET /v1/routes/history routes:read історія змін правил
POST, PUT, DELETE /v1/routes/inbound…, /v1/routes/outbound… routes:write правила дзвінків по одному: створити, змінити передані поля, видалити, переставити, відкотити
GET, POST /v1/config/export, /v1/config/import config:export, config:import налаштування у форматі файлу; завантаження — попередній перегляд, потім застосування
GET /v1/events calls:read події дзвінків точки за 7 днів (до 2000): since (id події або час), types, limit (до 500 за відповідь)
GET, POST, PATCH, DELETE /v1/webhooks… webhooks:write вебхуки: список, створити, змінити, видалити; …/rotate-secret, …/test, …/deliveries
GET, PUT /v1/open-closed routes:read, daynight:write чи зачинено і до коли; зачинити до кінця доби { "closed": true }, до дати { "closed": true, "until": "2026-10-05T09:00" } або відчинити

Повний опис полів — на сторінці документації та в OpenAPI.

Хто сьогодні телефонував і не додзвонився:

curl -H "Authorization: Bearer cpx_…" \
  "https://api.cenaly.com/pbx-api/v1/calls?status=missed&since=$(date -u +%Y-%m-%dT00:00:00Z)"

Передзвонити клієнту з телефона додаткового 101:

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"

Метрики за вересень із порівнянням із серпнем і вереснем минулого року — для своєї BI-панелі:

curl -H "Authorization: Bearer cpx_…" \
  "https://api.cenaly.com/pbx-api/v1/metrics?from=2026-09-01&to=2026-09-30&compare=prev,year"

У відповіді metrics — ті самі цифри, що на екрані Телефонія → Журнал дзвінків → Аналітика: вхідні, прийняті та пропущені, рівень обслуговування (поріг і мета — з налаштувань черги), середнє та максимальне очікування, частка покинутих без коротких, AHT, FCR, частка переведень і бота, CSAT. compare.prev і compare.year — ті самі поля за минулий період і за той самий період рік тому. Порівняння з минулим роком рахується для періодів до 400 днів.

Увімкнути переадресацію на мобільний, якщо співробітник не відповів за 15 секунд:

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#

Ті самі операції, що й у REST. Клієнт бачить лише інструменти, дозволені ключем або підключенням:

Інструменти Право
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

Сервер працює без сесій (streamable HTTP, JSON-RPC 2.0): initialize, tools/list, tools/call.

OAuth для розробників власних конекторів#

Сервер авторизації відповідає специфікації авторизації MCP — підійде будь-який клієнт, який її підтримує:

  1. Запит до MCP без токена отримує 401 із заголовком WWW-Authenticate: Bearer resource_metadata="https://api.cenaly.com/.well-known/oauth-protected-resource/pbx-api/mcp".
  2. Метадані ресурсу (RFC 9728) називають сервер авторизації — https://api.cenaly.com/pbx-api; його метадані (RFC 8414) — за адресою https://api.cenaly.com/.well-known/oauth-authorization-server/pbx-api (і …/pbx-api/.well-known/openid-configuration).
  3. Динамічна реєстрація клієнта (RFC 7591): POST /pbx-api/oauth/register. Адреса повернення — лише localhost / 127.0.0.1 (будь-який порт) або адреса відомого конектора (claude.ai, claude.com, chatgpt.com, chat.openai.com, vscode.dev, www.perplexity.ai, enterprise.perplexity.ai; у Cursor — ще рівно cursor://anysphere.cursor-mcp/oauth/callback). Спосіб входу клієнта — none (публічний клієнт), client_secret_post або client_secret_basic.
  4. Код авторизації з PKCE (лише S256): GET /pbx-api/oauth/authorize → вікно входу й згоди власника → повернення на вашу адресу з code, state та iss. Параметр resource — адреса MCP-сервера.
  5. Токени: POST /pbx-api/oauth/token. Код одноразовий і живе 2 хвилини (невірний code_verifier його гасить); токен доступу — 1 година; токен оновлення — 90 днів, під час кожного оновлення видається новий, попередній перестає працювати.
  6. Відкликання: POST /pbx-api/oauth/revoke (RFC 7009) гасить підключення цілком — як «Відкликати» у вікні «API і MCP».

Токен доступу приймається всюди, де ключ: і в MCP, і в REST, з правами й точками, які дозволив власник.

Ліміти та помилки#

  • На ключ або підключення: 120 запитів за хвилину і 20 000 за добу (REST і MCP разом).
  • Дзвінок у клік — окремо: 10 за хвилину і 300 за добу.
  • Журнал — до 100 дзвінків за запит; у журналі АТС точки — останні 400 дзвінків за 90 днів.
Код Помилка Що робити
401 api_key_missing, api_key_invalid ключа немає, його відкликано або він минув; токен OAuth минув — оновіть його
403 scope_required у ключа немає права — додайте його в «Права»
400 location_required у ключа кілька точок — передайте location
404 location_not_found точки немає або ключ обмежено іншими точками
429 rate_limited ліміт вичерпано, повторіть за Retry-After секунд

Події дзвінків#

У реальному часі — вебхуки АТС: Телефонія → API і MCP → Вебхуки або POST /v1/webhooks ключем із правом webhooks:write. На вашу https-адресу за секунди надходить POST на кожну подію: call.started (розпочався: напрямок, хто, куди, лінія), call.ringing (у кого дзвонить — по одному на кожен телефон), call.answered (хто відповів), call.transferred (хто і кому перевів), call.ended (підсумок, тривалість, розмова, хто відповів). Вебхук можна обмежити точками та типами подій.

{ "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": "Анна" } } }

Підпис — заголовок X-Cenaly-Signature: t=<час unix>,v1=<HMAC-SHA256 від "t.тіло" секретом вебхука>. Перерахуйте, порівняйте за сталий час і відхиліть t, старший за 5 хвилин. Секрет whsec_… показується один раз; «Новий секрет» гасить попередній одразу.

Доставка — дайте відповідь 2xx за 10 секунд. Інакше повторюємо з паузами 10 с, 30 с, 2, 5, 10, 15 і 15 хвилин (8 спроб, близько години); повтор несе той самий id — за ним відкидайте дублі. Журнал доставок (код відповіді, час, спроба) — у вікні вебхука та GET /v1/webhooks/{id}/deliveries; «Перевірити» надсилає службовий webhook.ping. Адреса 3 доби підряд не прийняла жодної доставки — вебхук вимикається сам: власнику надходить лист, у вікні «Вебхуки» — позначка «Вимкнено автоматично» і кнопка «Увімкнути» (або PATCH /v1/webhooks/{id} з { "enabled": true }).

Без власного сервера — та сама стрічка опитуванням: GET /v1/events?since=<id останньої події> або інструмент MCP get_call_events (події точки за останні 7 днів, до 2000; за відповідь — до 500, more: true — гортайте далі тим самим since).

Після обробки запису — дзвінок із розшифровкою та розбором надходить вебхуком джерела «Вебхук» у розділі «Дзвінки».

«Відкрито / закрито» — PUT /v1/open-closed з { "closed": true } закриває точку до кінця доби (як *28 з телефону: дзвінки йдуть правилами «поза годинами»), false — відкриває; GET показує, чи закрито і ким. З "until" — закрито до цього моменту (не далі 30 днів), потім відкриється само: час без зміщення (2026-10-05T09:00) читається в поясі точки; false знімає і його. Потрібна увімкнена галка «Закрити кодом *28» у маршрутизації (інакше 409).

Безпека#

  • Ключ показується один раз і зберігається в нас лише відбитком; ключ, що витік, відкликається однією кнопкою.
  • OAuth-підключення дозволяє лише власник, і видно, на яку адресу йде доступ; дозволене підключення можна обмежити правами та точками і відкликати будь-якої миті.
  • Номери телефонів — персональні дані ваших клієнтів: давайте права на журнал і записи лише тим інтеграціям, яким вони справді потрібні.
  • Усі зміни за ключем або підключенням — у журналі дій АТС із назвою ключа або додатка.
Was this article helpful?