C cenaly.com
Mulai gratis

API dan MCP untuk PBX mandiri

Kunci dan hak akses, REST API, server MCP untuk Claude dan Cursor, menghubungkan ChatGPT dan claude.ai via OAuth tanpa kunci, contoh, limit, dan eror

11 min read Demo panel admin
On this page 10

API dan MCP untuk PBX Anda

PBX Cenaly Anda terbuka untuk program dan Asisten AI Anda:

  • CRM, sistem akuntansi, situs web Anda — REST API: log panggilan, rekaman dan transkripsi, panggilan sekali klik, ekstensi, pengalihan, aturan panggilan;
  • Claude Code, Claude Desktop, Cursor — server MCP jarak jauh dengan kunci;
  • ChatGPT, claude.ai, Perplexity, Cursor dan VS Code — server MCP yang sama tanpa kunci: Anda masuk ke Akun Anda dan mengizinkan akses (OAuth).

Semuanya berjalan atas nama pemilik Akun dan hanya dengan hak yang ia berikan. Setiap perubahan terlihat di log tindakan PBX dengan nama kunci atau Aplikasi.

Alamat#

Apa Alamat
REST API https://api.cenaly.com/pbx-api/v1
Server MCP (streamable HTTP) https://api.cenaly.com/pbx-api/mcp
Dokumentasi metode api.cenaly.com/pbx-api/v1/docs
Deskripsi OpenAPI 3.1 api.cenaly.com/pbx-api/v1/openapi.json
Metadata OAuth https://api.cenaly.com/.well-known/oauth-authorization-server/pbx-api

Kunci dan hak#

Kunci hanya dibuat oleh pemilik Akun: Telefoni → API dan MCP → Kunci → Buat kunci. Karyawan dengan peran "Administrator PBX" tidak dapat melihat kunci — kunci berlaku atas nama pemilik.

  • Kunci berformat cpx_… ditampilkan satu kali — tepat setelah dibuat, bersama sisipan siap pakai untuk koneksi. Kami hanya menyimpan sidik jarinya (SHA-256), kunci tidak dapat dipulihkan — hanya bisa menerbitkan yang baru.
  • Kunci dapat dibatasi berdasarkan Cabang (jika tidak — semua Cabang, termasuk yang akan datang) dan masa berlaku (30, 90, 365 hari atau tanpa batas).
  • "Hak" mengubah hak dan Cabang kunci secara langsung: Integrasi tetap berjalan, hak baru berlaku mulai permintaan berikutnya.
  • "Cabut" — langsung dan selamanya: permintaan berikutnya dengan kunci ini akan mendapat 401.
  • Kunci dan koneksi aktif — hingga 20 per Akun.

Hak dipilih dengan set siap pakai atau centang:

Hak Apa yang diberikan Set
calls:read log panggilan dan kartu panggilan dengan rute CRM, Asisten AI, hanya baca, semua
recordings:read tautan ke Rekaman percakapan (10 menit) dan transkripsi CRM, Asisten AI, hanya baca, semua
calls:dial panggilan sekali klik: telepon karyawan berdering lebih dulu, setelah dijawab PBX menekan Nomor CRM, Asisten AI, semua
extensions:read ekstensi, grup, pengalihan, "jangan ganggu" CRM, Asisten AI, hanya baca, semua
extensions:write mengubah pengalihan pribadi dan "jangan ganggu" Asisten AI, semua
presence:read siapa yang bebas, sedang menelepon, sedang berbicara Asisten AI, hanya baca, semua
reports:read metrik call center per periode: tingkat layanan, waktu tunggu, panggilan terputus, AHT, FCR, CSAT, di mana panggilan hilang, rincian per antrean, saluran, karyawan hanya baca, semua
routes:read Nomor, aturan panggilan masuk dan keluar, riwayat aturan hanya baca, semua
routes:write membuat, mengubah, menghapus dan menyusun ulang aturan panggilan, mengembalikan dari riwayat hanya dengan centang terpisah
config:export ekspor pengaturan PBX dalam format file hanya dengan centang terpisah
config:import impor pengaturan dari tabel: pratinjau, lalu penerapan hanya dengan centang terpisah
webhooks:write membuat, mengubah, menguji dan menghapus webhook peristiwa panggilan hanya dengan centang terpisah
daynight:write menutup Cabang hingga akhir hari atau hingga tanggal tertentu, membuka — sama seperti *28 dari telepon hanya dengan centang terpisah

Hak yang mengubah sesuatu atau menghabiskan menit ditandai kuning di jendela. Tiga hak terakhir tidak termasuk dalam set mana pun, bahkan "Semua" — hanya dapat diberikan secara sadar, dengan centang terpisah.

ChatGPT, claude.ai, Perplexity, Cursor, VS Code: koneksi tanpa kunci#

Asisten cloud tidak dapat menyisipkan kunci ke header — mereka menghubungkan server MCP melalui OAuth. Kunci tidak perlu dibuat.

claude.ai: Pengaturan → Konektor → Tambah konektor Anda → tempel https://api.cenaly.com/pbx-api/mcp → Hubungkan.

ChatGPT: Pengaturan → Aplikasi dan konektor → Lanjutan → aktifkan mode pengembang → Buat → tempel https://api.cenaly.com/pbx-api/mcp, autentikasi — OAuth.

Perplexity: Pengaturan Akun → Konektor → "+ Konektor Anda" → Jarak jauh → tempel https://api.cenaly.com/pbx-api/mcp, autentikasi — OAuth.

Cursor dan VS Code: tambahkan server MCP jarak jauh (HTTP) dengan alamat https://api.cenaly.com/pbx-api/mcp tanpa header kunci — jendela masuk akan terbuka di browser. Di Cursor: .cursor/mcp.json → {"mcpServers": {"cenaly-pbx": {"url": "https://api.cenaly.com/pbx-api/mcp"}}}; di VS Code: perintah "MCP: Add Server" → HTTP.

Selanjutnya asisten akan membuka jendela masuk Cenaly. Setelah masuk Anda akan melihat:

  • siapa yang meminta akses — Aplikasi dinamai berdasarkan alamat tempat respons akan dikembalikan: "Konektor terverifikasi · chatgpt.com" (begitu juga — claude.ai, perplexity.ai, vscode.dev, Cursor), "Program di komputer ini" atau peringatan "Alamat tidak dikenal". Nama yang dikirim Aplikasi ditampilkan kecil — siapa pun bisa menulisnya;
  • hak — yang ditandai adalah yang diminta Aplikasi (jika ia meminta "semuanya", set "Asisten AI" yang ditandai); hak "hanya dengan centang terpisah" tidak pernah ditandai sebelumnya;
  • Cabang — semua atau yang dipilih.

"Izinkan" mengembalikan Anda ke asisten, dan ia langsung melihat alat PBX. Koneksi muncul di Telefoni → API dan MCP → Kunci sebagai baris dengan label OAuth dan alamat Aplikasi — di sana juga hak diubah dan akses dicabut. Menghubungkan ulang Aplikasi yang sama memperbarui haknya, bukan membuat koneksi kedua.

Hanya pemilik Akun yang dapat mengizinkan koneksi.

Claude Code, Claude Desktop, Cursor: koneksi dengan kunci#

Claude Code — satu perintah:

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

Claude Desktop, Cursor (.cursor/mcp.json) dan klien lain dengan berkas pengaturan:

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

Sisipan siap pakai dengan kunci Anda ditampilkan segera setelah kunci dibuat. Asisten AI hanya melihat alat yang diizinkan oleh kunci, dan dapat menjawab “siapa yang menelepon hari ini dan tidak terjawab”, “telepon balik tamu ini dari telepon Anna”, “aktifkan pengalihan ke ponsel untuk saya”.

REST API#

Kunci — di header Authorization: Bearer <ключ> (atau X-Api-Key). Jika kunci Anda memiliki satu cabang, parameter location tidak perlu dikirim; jika beberapa — respons 400 location_required akan mencantumkannya.

Metode Jalur Hak Fungsinya
GET /v1/me — hak, cabang, dan limit kunci
GET /v1/locations — cabang kunci dan PBX-nya
GET /v1/calls calls:read jurnal panggilan: since, until, direction, status (answered, missed, ai), number, extension, limit hingga 100, cursor
GET /v1/calls/{id} calls:read panggilan dengan rute: aturan mana yang berlaku, telepon siapa yang berdering, siapa yang menjawab
GET /v1/calls/{id}/recording recordings:read tautan ke rekaman selama 10 menit
GET /v1/calls/{id}/transcript recordings:read transkrip dan ringkasan percakapan
POST /v1/dial calls:dial panggilan sekali klik: { "extension": "101", "number": "+995555123456" }
GET /v1/dial/{commandId} calls:dial status panggilan sekali klik
GET /v1/extensions extensions:read ekstensi, grup, pengalihan, “jangan ganggu”
PUT /v1/extensions/{ext}/forwarding extensions:write pengalihan pribadi ekstensi
PUT /v1/extensions/{ext}/dnd extensions:write “jangan ganggu”: { "on": true }
GET /v1/presence presence:read siapa yang tersedia saat ini
GET /v1/metrics reports:read metrik call center per periode: from, to (tanggal lokal cabang YYYY-MM-DD, bawaan — 7 hari terakhir), compare (prev, year, prev,year atau kosong), sections (metrics,loss,queues,lines,operators,directions,heatmap,daily), callbacks=true — juga kecepatan panggilan balik
GET /v1/routes routes:read nomor, aturan panggilan masuk dan keluar
GET /v1/routes/history routes:read riwayat perubahan aturan
POST, PUT, DELETE /v1/routes/inbound…, /v1/routes/outbound… routes:write aturan panggilan satu per satu: buat, ubah bidang yang dikirim, hapus, urutkan ulang, kembalikan
GET, POST /v1/config/export, /v1/config/import config:export, config:import pengaturan dalam format berkas; unggah — pratinjau, lalu terapkan
GET /v1/events calls:read peristiwa panggilan cabang selama 7 hari (hingga 2000): since (id peristiwa atau waktu), types, limit (hingga 500 per respons)
GET, POST, PATCH, DELETE /v1/webhooks… webhooks:write webhook: daftar, buat, ubah, hapus; …/rotate-secret, …/test, …/deliveries
GET, PUT /v1/open-closed routes:read, daynight:write apakah tutup dan sampai kapan; tutup hingga akhir hari { "closed": true }, hingga tanggal { "closed": true, "until": "2026-10-05T09:00" } atau buka

Deskripsi lengkap bidang — di halaman dokumentasi dan di OpenAPI.

Siapa yang menelepon hari ini dan tidak terjawab:

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

Telepon balik klien dari telepon ekstensi 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"

Metrik September dengan perbandingan Agustus dan September tahun lalu — untuk panel BI Anda sendiri:

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

Dalam respons metrics — angka yang sama seperti di layar Telefoni → Jurnal Panggilan → Analitik: panggilan masuk, diterima dan terlewat, tingkat layanan (ambang dan target — dari pengaturan antrean), rata-rata dan maksimum waktu tunggu, proporsi yang dibatalkan tanpa panggilan singkat, AHT, FCR, proporsi pengalihan dan bot, CSAT. compare.prev dan compare.year — bidang yang sama untuk periode sebelumnya dan periode yang sama setahun lalu. Perbandingan dengan tahun lalu dihitung untuk periode hingga 400 hari.

Aktifkan pengalihan ke ponsel jika karyawan tidak menjawab dalam 15 detik:

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"

Alat MCP#

Operasi yang sama seperti REST. Klien hanya melihat alat yang diizinkan oleh kunci atau koneksi:

Alat Hak
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 berjalan tanpa sesi (streamable HTTP, JSON-RPC 2.0): initialize, tools/list, tools/call.

OAuth untuk pengembang konektor sendiri#

Server otorisasi mengikuti spesifikasi otorisasi MCP — klien apa pun yang mendukungnya dapat digunakan:

  1. Permintaan ke MCP tanpa token menerima 401 dengan header WWW-Authenticate: Bearer resource_metadata="https://api.cenaly.com/.well-known/oauth-protected-resource/pbx-api/mcp".
  2. Metadata sumber daya (RFC 9728) menyebutkan server otorisasi — https://api.cenaly.com/pbx-api; metadatanya (RFC 8414) ada di alamat https://api.cenaly.com/.well-known/oauth-authorization-server/pbx-api (dan …/pbx-api/.well-known/openid-configuration).
  3. Registrasi dinamis klien (RFC 7591): POST /pbx-api/oauth/register. Alamat pengembalian — hanya localhost / 127.0.0.1 (port apa pun) atau alamat konektor yang dikenal (claude.ai, claude.com, chatgpt.com, chat.openai.com, vscode.dev, www.perplexity.ai, enterprise.perplexity.ai; untuk Cursor — juga tepat cursor://anysphere.cursor-mcp/oauth/callback). Metode masuk klien — none (klien publik), client_secret_post, atau client_secret_basic.
  4. Kode otorisasi dengan PKCE (hanya S256): GET /pbx-api/oauth/authorize → jendela masuk dan persetujuan pemilik → kembali ke alamat Anda dengan code, state, dan iss. Parameter resource — alamat server MCP.
  5. Token: POST /pbx-api/oauth/token. Kode bersifat sekali pakai dan berlaku 2 menit (code_verifier yang salah membatalkannya); token akses — 1 jam; token pembaruan — 90 hari, setiap pembaruan menerbitkan token baru, token lama berhenti berfungsi.
  6. Pencabutan: POST /pbx-api/oauth/revoke (RFC 7009) mematikan koneksi sepenuhnya — seperti "Cabut" di jendela "API dan MCP".

Token akses diterima di mana pun kunci diterima: baik di MCP maupun REST, dengan hak dan cabang yang diizinkan pemilik.

Batas dan kesalahan#

  • Per kunci atau koneksi: 120 permintaan per menit dan 20.000 per hari (REST dan MCP bersama).
  • Panggilan sekali klik — terpisah: 10 per menit dan 300 per hari.
  • Log — hingga 100 panggilan per permintaan; di log PBX cabang — 400 panggilan terakhir selama 90 hari.
Kode Kesalahan Yang harus dilakukan
401 api_key_missing, api_key_invalid kunci tidak ada, dicabut, atau kedaluwarsa; token OAuth kedaluwarsa — perbarui
403 scope_required kunci tidak memiliki hak — tambahkan di "Hak"
400 location_required kunci memiliki beberapa cabang — sertakan location
404 location_not_found cabang tidak ada atau kunci dibatasi ke cabang lain
429 rate_limited batas tercapai, coba lagi setelah Retry-After detik

Peristiwa Panggilan#

Secara real-time — webhook PBX: Telefoni → API dan MCP → Webhook atau POST /v1/webhooks dengan kunci berhak webhooks:write. Ke alamat https Anda dalam hitungan detik datang POST untuk setiap peristiwa: call.started (dimulai: arah, siapa, ke mana, saluran), call.ringing (pada siapa berdering — satu per setiap telepon), call.answered (siapa yang menjawab), call.transferred (siapa dan kepada siapa mengalihkan), call.ended (hasil, durasi, percakapan, siapa yang menjawab). Webhook dapat dibatasi pada cabang dan jenis peristiwa.

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

Tanda tangan — header X-Cenaly-Signature: t=<waktu unix>,v1=<HMAC-SHA256 dari "t.body" dengan secret webhook>. Hitung ulang, bandingkan dalam waktu konstan dan tolak t yang lebih tua dari 5 menit. Secret whsec_… ditampilkan sekali; "Secret baru" langsung mematikan yang sebelumnya.

Pengiriman — balas 2xx dalam 10 detik. Jika tidak, kami mengulang dengan jeda 10 dtk, 30 dtk, 2, 5, 10, 15 dan 15 menit (8 percobaan, sekitar satu jam); pengulangan membawa id yang sama — gunakan itu untuk membuang duplikat. Log pengiriman (kode respons, waktu, percobaan) — di jendela webhook dan GET /v1/webhooks/{id}/deliveries; "Periksa" mengirim webhook.ping layanan. Alamat 3 hari berturut-turut tidak menerima satu pun pengiriman — webhook mati sendiri: pemilik menerima email, di jendela "Webhook" — tanda "Dimatikan otomatis" dan tombol "Aktifkan" (atau PATCH /v1/webhooks/{id} dengan { "enabled": true }).

Tanpa server sendiri — feed yang sama lewat polling: GET /v1/events?since=<id peristiwa terakhir> atau alat MCP get_call_events (peristiwa cabang selama 7 hari terakhir, hingga 2000; per respons — hingga 500, more: true — lanjutkan dengan since yang sama).

Setelah pemrosesan rekaman — panggilan dengan transkripsi dan analisis datang lewat webhook sumber "Webhook" di bagian "Panggilan".

"Buka / tutup" — PUT /v1/open-closed dengan { "closed": true } menutup cabang hingga akhir hari (seperti *28 dari telepon: panggilan berjalan dengan aturan "di luar jam"), false — membuka; GET menunjukkan apakah tutup dan oleh siapa. Dengan "until" — tutup hingga saat itu (tidak lebih dari 30 hari), lalu terbuka sendiri: waktu tanpa offset (2026-10-05T09:00) dibaca dalam zona cabang; false juga menghapusnya. Perlu centang "Tutup dengan kode *28" yang aktif di perutean (jika tidak 409).

Keamanan#

  • Kunci ditampilkan sekali dan disimpan di kami hanya sebagai sidik jari; kunci yang bocor dicabut dengan satu tombol.
  • Koneksi OAuth hanya diizinkan oleh pemilik, dan terlihat ke alamat mana akses diberikan; koneksi yang diizinkan dapat dibatasi pada hak dan cabang serta dicabut kapan saja.
  • Nomor telepon — data pribadi klien Anda: berikan hak atas log dan rekaman hanya kepada integrasi yang benar-benar membutuhkannya.
  • Semua perubahan melalui kunci atau koneksi — di log tindakan PBX dengan nama kunci atau aplikasi.
Was this article helpful?