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: הוסיפו שרת MCP מרוחק (HTTP) עם הכתובת 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 תפרט אותם.
| Method | Path | הרשאה | מה עושה |
|---|---|---|---|
| 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 (מזהה אירוע או זמן), 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 — מתאים כל לקוח שתומך בו:
- בקשה ל-MCP ללא טוקן מקבלת 401 עם הכותרת
WWW-Authenticate: Bearer resource_metadata="https://api.cenaly.com/.well-known/oauth-protected-resource/pbx-api/mcp". - מטא-נתוני המשאב (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). - רישום דינמי של לקוח (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. - קוד הרשאה עם PKCE (רק
S256):GET /pbx-api/oauth/authorize→ חלון כניסה והסכמה של הבעלים → חזרה לכתובת שלכם עםcode,stateו-iss. הפרמטרresource— כתובת שרת ה-MCP. - טוקנים:
POST /pbx-api/oauth/token. הקוד חד-פעמי ותקף 2 דקות (code_verifierשגוי מבטל אותו); טוקן הגישה — שעה; טוקן הרענון — 90 ימים, בכל רענון מונפק חדש והקודם מפסיק לעבוד. - ביטול:
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 מאשר רק הבעלים, ונראה לאיזו כתובת עוברת הגישה; ניתן להגביל חיבור מאושר בהרשאות ובסניפים ולשלול אותו בכל רגע.
- מספרי טלפון הם נתונים אישיים של הלקוחות שלכם: תנו הרשאות ליומן ולהקלטות רק לאינטגרציות שבאמת זקוקות להן.
- כל השינויים לפי מפתח או חיבור — ביומן הפעולות של מרכזיית הטלפונים עם שם המפתח או האפליקציה.