ה-API פועל על אותם סוכנים, שיחות וקרדיטים (Credits) של לוח הבקרה באינטרנט. כל מה שאתם בונים בלוח הבקרה אפשר להפעיל מהמערכות שלכם, וגם להפך.
| מה | Endpoint |
|---|---|
| רשימת סוכנים | GET /api/v1/voice/agents |
| יצירת סוכן | POST /api/v1/voice/agents |
| שליפה / עדכון של סוכן | GET · PATCH /api/v1/voice/agents/{id} |
| ביצוע שיחה יוצאת | POST /api/v1/voice/calls |
| רשימת שיחות | GET /api/v1/voice/calls |
| שליפת שיחה (תמלול) | GET /api/v1/voice/calls/{id} |
| מחיקת שיחה | DELETE /api/v1/voice/calls/{id} |
| מחיקת השיחות של מתקשר | POST /api/v1/voice/calls/delete-by-caller |
| קמפיינים | GET · POST /api/v1/voice/campaigns |
| שליפת קמפיין | GET /api/v1/voice/campaigns/{id} |
| התחלה / השהיה / ביטול | POST /api/v1/voice/campaigns/{id}/{action} |
| קולות משובטים | GET · POST /api/v1/voice/voices |
| מחיקת קול משובט | DELETE /api/v1/voice/voices/{id} |
| רשימת "אל תתקשרו" | GET · POST /api/v1/voice/do-not-call |
| הסרה מהרשימה | DELETE /api/v1/voice/do-not-call/{phone} |
| שפות, קולות, תבניות | GET /api/v1/voice/catalog |
| הבדיקות של סוכן | GET · POST /api/v1/voice/agents/{id}/tests |
| הרצת בדיקות / קריאת הרצה | POST /api/v1/voice/agents/{id}/test-runs · GET /api/v1/voice/test-runs/{id} |
| ניתוב מספר לסוכן | PATCH /api/v1/voice/phone-numbers/{id} |
| רשימות מילים | GET · POST /api/v1/voice/vocabularies |
צרו מפתח בלוח הבקרה תחת אינטגרציות ← מפתחות API (או בלחיצה אחת בסקירה הכללית) ושלחו אותו כאסימון Bearer:
Authorization: Bearer sk-your-key
מפתח פועל במרחב העבודה שבו בעליו עובד, ועם התפקיד של אותו אדם: מפתח של חבר לקריאה בלבד יכול לקרוא אך לא לשנות דבר.
צרו סוכן מתבנית, ואם תרצו הגדירו את השדות שלו באותה בקשה. בלי template הוא מתחיל ריק; GET /api/v1/voice/catalog מציג את התבניות ואת השפות והקולות שסוכן מקבל. התבניות כתובות באנגלית ובסינית, ולכן לשפה אחרת שלחו system_prompt ו-first_message באותה שפה. או שכל הבקשה נשמרת או שלא נוצר סוכן בכלל, כך שאפשר לשלוח שוב בקשה שנדחתה אחרי שתוקנה. dashboard_url בתשובה הוא דף הסוכן בלוח הבקרה, שבו אפשר לדבר עם הטיוטה בדפדפן. כל סוכן פועל על EvaSay ASR, EvaSay LLM ו-EvaSay TTS, ש-EvaSay בוחרת לכל שיחה לפי השפה והעומס, והם כלולים במחיר השיחה; אין חשבונות של ספקים אחרים להגדיר.
curl https://evasay.com/api/v1/voice/agents \
-X POST \
-H "Authorization: Bearer sk-your-key" \
-H "Content-Type: application/json" \
-d '{
"name": "Front desk",
"language": "en",
"first_message": "Hi, thanks for calling Sunrise Salon. How can I help?",
"system_prompt": "You are the front desk of Sunrise Salon..."
}'
עדכנו כל אחד מהשדות האלה באמצעות PATCH /api/v1/voice/agents/{id}:
| שדה | הערות |
|---|---|
name, first_message, system_prompt | טקסט |
status | published מפרסם את הטיוטה כגרסה חדשה; draft מפסיק לקבל שיחות |
language | אחת מ-27 שפות, למשל en, zh, es, de, או multi כדי לעקוב אחר שפת המתקשר |
temperature | 0-100 |
max_duration_sec, silence_timeout_sec | מגבלות שיחה |
interruptible, end_call_enabled | ערכים בוליאניים |
confirm_details | בוליאני; חוזר בקול על מספרים ושמות ומבקש אישור |
ai_disclosure | בוליאני, ברירת מחדל true; לפני ההודעה הראשונה הסוכן אומר בשפת השיחה שהמתקשר מדבר עם בינה מלאכותית (מושמט כשההודעה הראשונה כבר אומרת זאת) |
voicemail_detection | בוליאני; שיחות יוצאות מאזינות תחילה ומסתיימות כשמגיעים לתא קולי |
voicemail_message | נשארת בתא קולי, יכולה להשתמש ב-{{variables}}; ללא הודעה — מנתקים |
transfer_number | מספר להעברה, בפורמט בין-לאומי |
transfer_destinations | עד 9 מספרים נוספים, [{name, number, when}]; הסוכן בוחר אחד לפי when |
transfer_briefing | בוליאני; מי שעונה ראשון שומע את סיכום השיחה של הסוכן |
pronunciations | עד 100 פריטים [{word, say, case_sensitive}]; הקול אומר say במקום word |
idle_messages | עד 3 תזכורות שנאמרות לפי התור למתקשר שותק לפני שהשיחה מסתיימת |
noise_reduction | בוליאני; רעש הרקע של המתקשר מסונן לפני שהוא נשמע |
recording_enabled | בוליאני; שיחות מוקלטות בשני ערוצים (המתקשר בשמאל, הסוכן בימין) |
recording_consent | announce, ask (נשמרת רק אם המתקשר מסכים) או none |
recording_notice | ההודעה או השאלה שנאמרות ראשונות; ריק לשימוש בטקסט המובנה בשפת השיחה |
handoffs | עד 5 פריטים [{agent_id, when}]: סוכנים אחרים שהסוכן הזה רשאי למסור להם שיחה |
knowledge_base_id | אחד ממאגרי הידע שלכם |
vocabulary_id | אחד מאוצרות המילים שלכם; המונחים בו מזוהים בצורה אמינה יותר כשהמתקשר אומר אותם |
voice_id | מזהה של קול מובנה של EvaSay, או אחד מהקולות המשובטים שלכם (clone:…) |
הקולות המובנים תלויים בשפה: לסינית יש ming-designed-female-clear ו-ming-designed-female-warm (נשיים), ming-designed-male-clear ו-ming-designed-male-friendly (גבריים), ולשאר השפות F1–F5 (נשיים) ו-M1–M5 (גבריים). קול מובנה שאינו מדבר את שפת הסוכן מוחלף בקול מאותו מין שמדבר אותה. שם השדה הישן tts_voice_id עדיין מתקבל. כל ערך אחר של voice_id, או קול משוכפל שעדיין לא מוכן, נדחה.
analysis_config קובע מה מופק מכל שיחה אחרי שהיא מסתיימת: summary (ברירת מחדל true), summaryLanguage, successCriteria (מה שיחה מוצלחת משיגה), fields (עד 20 {name, type, description} לחילוץ, כש-type הוא string, number או boolean) ו-scorecard (עד 10 {name, description, weight}, משקל 1–5). התוצאות נמצאות ב-analysis של השיחה וב-webhook call.analyzed.
שינוי שדות של סוכן משנה את הטיוטה שלו. שיחות ממשיכות להשתמש בגרסה המפורסמת עד שתפרסמו את הטיוטה באמצעות POST /api/v1/voice/agents/{id}/publish (אפשר עם note), או באמצעות status: "published" באותה בקשת PATCH. כל פרסום שומר גרסה ממוספרת; published_version בסוכן אומר באיזו גרסה משתמשות השיחות. שיחה נשארת בגרסה שהייתה חיה כשהתחילה, ולכן פרסום באמצע שיחה לא משנה אותה. שיחות ניסיון מלוח הבקרה משתמשות בטיוטה.
GET /agents/{id}/versions מציג את הגרסאות, ו-POST /agents/{id}/versions/{version}/restore משחזר: שיחות חדשות ישתמשו בגרסה הזו והטיוטה תהפוך להיות היא. שם הסוכן, הפריסה, מראה הווידג'ט וההתראות אינם מנוהלים בגרסאות ומשתנים מיד, וכך גם מסמכי מאגר הידע שלו.
בדיקה מריצה שיחה אחת בטקסט: מתקשר מדומה מגלם את scenario, הסוכן עונה מתוך הטיוטה שלו (הוראות, הודעה ראשונה וידע), ושופט בודק את השיחה מול success_criteria. כתבו בדיקות לשיחות החשובות, הריצו אותן אחרי כל שינוי, ופרסמו כשהן עוברות.
curl https://evasay.com/api/v1/voice/agents/AGENT_ID/tests \
-X POST \
-H "Authorization: Bearer sk-your-key" \
-H "Content-Type: application/json" \
-d '{
"name": "Move a booking",
"scenario": "A regular customer wants to move Friday 3 pm to Saturday morning.",
"success_criteria": "Offers Saturday times and confirms the new time and the customer'"'"'s name.",
"max_turns": 8
}'
POST /agents/{id}/test-runs מריץ את כל הבדיקות של הסוכן, או את אלה שב-test_ids, ומחזיר הרצה אחת לכל בדיקה (status: "running"). שאלו את GET /test-runs/{id} עד ש-status יהיה passed, failed או error; אז בהרצה יש transcript ואת reason של השופט (באנגלית, או בסינית עם reason_language: "zh"). כל הרצה עולה Credits, שמוצגים ליד הבדיקות בלוח הבקרה; ההרצות נעצרות בראשונה שהיתרה לא מכסה, ו-not_started מפרט את השאר. הרצה שלא הצליחה להתבצע מוחזרת. הבדיקות בודקות מה הסוכן אומר, לא את הקול או התזמון, והן לא קוראות לפונקציות שלו: בדקו אותן מראש עם POST /tools/{id}/test. לסוכן יש עד 30 בדיקות; PATCH ו-DELETE /agents/{id}/tests/{test_id} משנים או מסירים בדיקה.
מלבד שיחות שלמות (type: "simulation", ברירת המחדל), בדיקה יכולה לבדוק תשובה אחת. type: "next_reply" מקבל את chat_history, השיחה שלפניה שמסתיימת בדברי המתקשר ([{role, text}], כש-role הוא caller או agent), ואת success_criteria לתשובה הבאה של הסוכן. type: "tool_call" מקבל את chat_history ואת expected_tool {name, arguments, match}: הסוכן צריך לקרוא ל-name (אחת הפונקציות שלו, או end_call, transfer_call, handoff_to_agent) עם arguments, שמושווים במדויק (בלי רווחים בקצוות ובלי הבדל בין אותיות גדולות לקטנות) או, עם match: "judge", לפי המשמעות; ארגומנטים נוספים שהוא מעביר לא נבדקים. ה-transcript של הרצה מציג ב-tool_calls את הפונקציות שהסוכן קרא להן.
POST /agents/{id}/tests/generate מציע בדיקות מתוך הטיוטה של הסוכן: ההוראות, הידע והפונקציות שלו. הוא מקבל count (1–10, ברירת מחדל 5), types, focus (מה לכסות) ו-language (en או zh, לשמות ולקריטריונים), עולה Credits כמו הרצה אחת ומחזיר טיוטות לבדיקה ולשליחה אל POST /agents/{id}/tests; עם save: true הוא שומר אותן.
hooks עושה משהו ברגע מסוים בשיחה, עד 10 כללים: on: "silence" (המתקשר לא אמר דבר במשך seconds, 3–600, מאז שהסוכן סיים; פעם אחת עד שידבר שוב), on: "time_elapsed" (seconds מתחילת השיחה, 10–3600) או on: "call_ending". כל כלל מבצע (do) עד 3 מתוך {type: "say", text}, {type: "transfer", destination?}, {type: "end_call", text?} ו-{type: "tool", name, args?}; כלל לסיום השיחה מריץ פונקציות בלבד. שיחה שכלל סיים נושאת ended_reason בערך rule_ended.
בשיחות טלפון המקשים שהמתקשר לוחץ מגיעים לסוכן כתשובה שלו: קלט מסתיים ב-# או בהפסקה של שתי שניות. בשיחות יוצאות הסוכן יכול גם ללחוץ על מקשים כדי לעבור את תפריט הטלפון של חברה.
transfer_number הוא המספר הראשי של הסוכן להעברת מתקשר לאדם, והמספר שמחייגים אליו כשנגמרו הקרדיטים של מרחב העבודה. transfer_destinations מוסיף מספרים עם שמות, לכל אחד הערה מתי להשתמש בו ("חיוב: שאלות על חשבוניות והחזרים"), והסוכן בוחר. כש-transfer_briefing פעיל, הסוכן כותב סיכום קצר בזמן ההעברה; האדם שעונה שומע אותו, בקול של EvaSay ובשפת הסיכומים של הסוכן, לפני שהמתקשר מחובר. ended_reason של השיחה הוא אז transferred.
באמצעות handoffs סוכן יכול למסור שיחה לסוכן מפורסם אחר במרחב העבודה שלכם, למשל קבלה שמעבירה הזמנה לסוכן הזמנות. הסוכן בוחר לפי when. הסוכן השני מקבל את אותה שיחה עם כל מה שנאמר עד כה, ומדבר עם ההוראות, הקול, הידע, הכלים והמסירות שלו. השיחה נשארת רשומה, מנותחת ומחויבת תחת הסוכן הראשון; התמלול שלה מציין כל מסירה.
מספרים מחוברים בלוח הבקרה עם חשבון הספק שלכם. GET /api/v1/voice/phone-numbers מציג אותם, ו-PATCH /api/v1/voice/phone-numbers/{id} עם { "agent_id": "AGENT_ID" } מנתב את שיחות המספר לסוכן (לגרסה המפורסמת שלו), או עם "agent_id": null לאף סוכן; label משנה את שמו.
רשימת מילים מכילה שמות ומונחים שמתקשרים אומרים וזיהוי דיבור היה שומע לא נכון, כמו שמות מוצרים, תרופות או רחובות. POST /api/v1/voice/vocabularies עם { "name": "Products", "terms": ["Lumora", "Vantix Pro"] } (עד 1,000 מונחים של 50 תווים, או "preset": "medical" או "legal" כנקודת התחלה), ואז הגדירו את vocabulary_id של הסוכן. GET, PATCH (name, terms) ו-DELETE /vocabularies/{id}; אי אפשר למחוק רשימה שסוכן משתמש בה.
לכל מספר יש כללי שיחה בדף מספרי הטלפון, שחלים לפני שהסוכן עונה: מספרים חסומים או תחילות של מספרים (+1555), ומתקשרים שמסתירים את המספר שלהם, נדחים בלי מענה ולא עולים דבר; מתקשרים מרשימה אפשר להעביר ישר למספר אחר; וכשהסוכן אינו יכול לענות (לא מפורסם, אין worker, נגמרו הקרדיטים ואין מספר העברה) השיחה יכולה לצלצל במספר או להשמיע הודעה משלכם. גם חיפוש התחלה (run_at_start) יכול לדחות מתקשר בתשובה {"reject": true, "message": "..."}: הסוכן אומר את ההודעה, אם יש, ומנתק, וה-ended_reason הוא rejected.
בצעו שיחה אחת מאחד ממספרי הטלפון של מרחב העבודה שלכם. כל בקשה זקוקה ל-Idempotency-Key ייחודי; שליחת אותו מפתח שוב מחזירה את אותה שיחה במקום לחייג פעמיים.
curl https://evasay.com/api/v1/voice/calls \
-X POST \
-H "Authorization: Bearer sk-your-key" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{
"agent_id": "AGENT_ID",
"to": "+14155550100",
"variables": { "customer_name": "Alex", "order_id": "1234" }
}'
from נדרש כשיש במרחב העבודה יותר ממספר טלפון אחד. variables ממלאים מציני מקום בסגנון {{customer_name}} בהודעה הראשונה של הסוכן ובהנחיה שלו.
GET /api/v1/voice/calls/{id} מחזיר את מצב השיחה, משכה, הקרדיטים שחויבו, הסיכום, הניתוח והתמלול. רשימת שיחות מתקבלת עם GET /api/v1/voice/calls?agent_id=&status=&channel=&user_id=&page= (user_id: המזהה שלכם עצמכם לאדם, מאסימון שיחת אינטרנט). השדה turns הוא יומן ניפוי השגיאות של השיחה, תור אחר תור: לאן הלך הזמן מרגע שהמתקשר סיים לדבר ועד ששמע את התשובה, באלפיות שנייה — waitMs (סוף הדיבור), sttMs (זיהוי), llmMs (המילה הראשונה של המודל, ועוד אחת לכל סבב פונקציות), ttsMs (הצליל הראשון של הקול), firstAudioMs (התשובה נשמעה) — יחד עם הפונקציות שנקראו, ההפרעות והשגיאות. דף השיחה מציג אותו גם כן.
עם recording_enabled כל שיחה מוקלטת כקובץ WAV דו-ערוצי: המתקשר בשמאל, הסוכן בימין, בקצב הדגימה של השיחה. עם recording_consent: "announce" הסוכן אומר תחילה שהשיחה מוקלטת; עם "ask" הוא שואל, וההקלטה נשמרת רק אם המתקשר מסכים (היעדר תשובה נחשב לא); עם "none" לא נאמר דבר. בדקו מה החוק דורש במקום שבו אתם והמתקשרים שלכם נמצאים.
הקלטות נשמרות באחסון של EvaSay, או ב-bucket משלכם התואם S3 (AWS S3, Cloudflare R2, Google Cloud Storage, Supabase, MinIO) שמוגדר תחת אינטגרציות ← Webhooks והתראות ← אחסון הקלטות. ה-worker שמריץ את השיחה מעלה את הקובץ ישירות ל-bucket. GET /api/v1/voice/calls/{id} מחזיר recordingUrl שתקף לשעה לאחר שההקלטה נשמרה, ואת recording.status (recording, stored, declined או failed).
DELETE /api/v1/voice/calls/{id} מוחק שיחה שהסתיימה יחד עם התמלול, ההקלטה (באחסון של EvaSay או ב-bucket שלכם), הניתוח ורשומות ה-Webhook. ה-Credits שנוצלו נשארים בהיסטוריית הקרדיטים. שיחה שעדיין אי אפשר למחוק מחזירה 409 עם code call_not_deletable_yet: היא עדיין פעילה או הסתיימה זה עתה, עדיין בחיוב, ההקלטה אולי עדיין מועלית, או שיש בה חוב Credits שהיתרה לא כיסתה (הוסיפו Credits קודם).
כשמישהו מבקש למחוק את הנתונים שלו, POST /api/v1/voice/calls/delete-by-caller עם { "phone_number": "+14155550123" } מוחק את כל השיחות עם המספר הזה (מספר המתקשר בשיחות נכנסות, המספר שחויג בשיחות יוצאות), ועם { "user_id": "..." } את כל שיחות הרשת שבטוקן שלהן היה user_id הזה. התשובה היא { "deleted": 12, "kept_back": { "settling": 1 }, "more": false }: עד 200 שיחות בבקשה, לכן חזרו על הבקשה כל עוד more הוא true, ומאוחר יותר עבור השיחות ב-kept_back. אם המספר ברשימת "אל תתקשרו", הוא נשאר בה. בלוח הבקרה עושים אותו דבר ב-שיחות → מחיקת הנתונים של מתקשר.
שלחו POST /api/v1/voice/calls/{id}/control בזמן שהשיחה מתנהלת. ה-worker שמריץ את השיחה קולט את הפקודה תוך כשתי שניות; ה-API עונה 202. אם אין גישה ל-worker שמריץ את השיחה, ה-API עונה 503 (code call_unreachable) והפקודה לא מתבצעת.
type | מה קורה |
|---|---|
say | הסוכן אומר את text אחרי המשפט הנוכחי שלו, או מיד עם "interrupt": true |
note | הסוכן מקבל את text (לא נאמר בקול) ולוקח אותו בחשבון מהתשובה הבאה שלו; התמלול מציין זאת |
end | הסוכן אומר את text אם ניתן ואז מנתק; שיחת טלפון בלי text מנותקת מיד |
ended_reason של השיחה הוא אז api_ended. בדף השיחה בלוח הבקרה יש את אותן פקודות שליטה.
POST /api/v1/voice/calls/{id}/listen (אפשר עם { "channels": 2 }) מחזיר listen_url שאפשר לפתוח תוך שתי דקות. זהו WebSocket: תחילה הודעת JSON {"type":"start","sampleRate":8000,"channels":1,"encoding":"pcm_s16le"}, ואז מסגרות בינאריות של PCM ב-16 סיביות little-endian עם מה שהמתקשר שומע (שני הקולות מעורבבים; עם channels: 2 המתקשר בשמאל והסוכן בימין). הוא נסגר כשהשיחה מסתיימת. השמע מגיע ישירות מה-worker שמריץ את השיחה, לא דרך מישור הבקרה של EvaSay; כפתור ההאזנה בדף השיחה בלוח הבקרה משתמש באותה כתובת.
שלחו וקבלו את השמע של שיחה מהתוכנה שלכם, למשל מערכת הטלפוניה או האפליקציה שלכם. התחילו את השיחה:
curl https://evasay.com/api/v1/voice/calls/websocket \
-X POST \
-H "Authorization: Bearer sk-your-key" \
-H "Content-Type: application/json" \
-d '{ "agent_id": "AGENT_ID", "encoding": "pcm_s16le", "sample_rate": 16000 }'
ה-websocket_url בתשובה נושא אסימון חד-פעמי וניתן לפתוח אותו תוך 15 דקות. encoding הוא pcm_s16le (PCM ב-16 סיביות little-endian עם sample_rate של 8000, 16000 או 24000) או mulaw (μ-law ב-8 קילוהרץ). השמע עובר בשני הכיוונים כמסגרות בינאריות בפורמט הזה, רצוי של 20 מילישניות כל אחת. מסגרות טקסט הן JSON:
| כיוון | הודעות |
|---|---|
| אתם ← EvaSay | {"type":"dtmf","digits":"12#"} לחיצות מקשים; {"type":"end"} מנתק; {"type":"text","text":"…"} מילים שהמתקשר הקליד ("input":"button" לתשובה שנלחצה); {"type":"context","text":"…","key":"cart"} מה שהאפליקציה שלכם מדווחת (הסוכן לא עונה על כך); {"type":"tool_result","id":"…","result":{…}} (או "error") תשובה של פונקציית דף |
| EvaSay ← אתם | start (עם callId); clear (המתקשר קטע: השליכו שמע של הסוכן שעדיין לא הושמע); transcript (role, text, final, ו-input למילים מוקלדות); user_started_speaking, user_stopped_speaking, agent_started_speaking, agent_stopped_speaking; cards (cards, quick_replies); tool (id, name, arguments: הריצו אחת מפונקציות הדף שלכם); notice (code: too_fast או limit למילים מוקלדות); ended (עם reason, ואז השקע נסגר) |
הסוכן מברך ברגע שאתם מתחברים. אפשר להוסיף לבקשה user_id ו-page_tools (פונקציות הדף שהאפליקציה שלכם עונה עליהן, ראו להלן). שיחות מחויבות לפי דקה כמו כל שיחה אחרת, עם אותן רשומות שיחה, ניתוח ו-Webhooks.
בשיחת אינטרנט (הווידג'ט, הדף המאוחסן, האפליקציה שלכם) המתקשר רואה צ'אט לצד הקול, ולכן הסוכן יכול לעשות יותר מלדבר. מתקשרים בטלפון אינם מקבלים דבר מזה.
הפעילו סוכן ← כלים ← שליחה למתקשר (send_to_caller ב-API של הסוכן) והסוכן יוכל להציג עד חמישה כרטיסים בו-זמנית על מסך המתקשר: כותרת, שורה מתחתיה, תיאור, תמונה, קישור ועד שני כפתורי תשובה בכל אחד; הוא יכול גם להציע עד שלוש תשובות מהירות מתחת לשאלה. קישורים אינם מוקראים לעולם.
הסוכן רשאי לשלוח רק קישורים ותמונות שניתנו לו באותה שיחה: ההוראות והברכה שלו, מאגר הידע (מסמך שנקרא מדף אינטרנט נושא את כתובתו), תשובות הפונקציות שלכם והכרטיסים המוכנים. קישור חייב גם להיות באחד מ-allowed_hosts (האתר של כרטיס מוכן תמיד מותר). קישורים שהסוכן ממציא, או שהמתקשר מקריא, לא נשלחים. קישורים לאתרים האלה בדברי הסוכן ניתנים ללחיצה בצ'אט.
"send_to_caller": {
"enabled": true,
"allowed_hosts": ["shop.example.com", "*.cdn.example.com"],
"presets": [
{ "name": "hours", "when": "asked when we open", "title": "Opening hours",
"description": "Mon–Sat 9:00–18:00", "url": "https://shop.example.com/stores", "image_url": "" }
]
}
כל שליחה נשלחת אליכם כ-Webhook בשם call.message_sent (channel, items עם title ו-url, quickReplies, blocked). שיחה שולחת לכל היותר 10 פעמים.
במהלך השיחה המתקשר יכול גם להקליד (כתובת דוא"ל, מספר הזמנה) או להקיש על כפתור תשובה; הסוכן עונה על כך כמו על דיבור, ועוצר קודם אם דיבר. עד 500 תווים להודעה, אחת בשנייה, 100 לשיחה. ברשומת השיחה התורות האלה מסומנים כמוקלדים או כמוקשים.
הווידג'ט נותן לדף שלכם אובייקט evasay. הכול אופציונלי, ומסגרת השיחה מאזינה לדף שלכם רק אם הוא אחד מהאתרים המותרים של הווידג'ט (סוכן ← פריסה):
<script src="https://evasay.com/voice-widget.js" data-agent="AGENT_SLUG" async></script>
<script>
window.evasay = window.evasay || [];
evasay.push(function (agent) {
agent.setVariables({ plan: 'pro', page: location.pathname }); // for the next call
agent.update('Cart: 2 items, $120', { key: 'cart' }); // during it
agent.registerTool('add_to_cart', async function (args) {
// your code, in the visitor's browser
return { ok: true, checkout: 'https://shop.example.com/checkout' };
});
agent.on('cards', function (cards) {}); // also 'live', 'ended'
});
</script>
setVariables ממלאים את {{name}} בהוראות ובברכה. הם מגיעים מהדפדפן של המבקר, ולכן הסוכן מקבל הודעה שאינם מאומתים, והם אף פעם לא מגיעים לפונקציות שלכם או לחיפוש ההתחלה.update מספר לסוכן מה קורה בדף בלי לגרום לו לענות; עדכון חדש יותר עם אותו key מחליף את הישן."kind": "page", ללא url) ורשמו בדף שלכם פונקציה באותו שם. הסוכן רשאי לקרוא לה רק בשיחות מדף שרשם אותה; הוא ממתין לתשובה עד timeout_sec (1–10, ברירת מחדל 5) אלא אם wait_for_result הוא false. היא רצה בחיבור של המבקר, כמו לחיצה שלו: בקשו אישור בדף שלכם לפני כל דבר שעולה כסף או שאי אפשר לבטל. קישורים בתשובתה יכולים להישלח ככרטיסים.הגדירו את מי יכול להתחיל שיחה ל-רק עם אסימון, והשרת שלכם ישיג אסימון חד-פעמי עבור המשתמש המחובר:
curl https://evasay.com/api/v1/voice/web-calls \
-X POST \
-H "Authorization: Bearer sk-your-key" \
-H "Content-Type: application/json" \
-d '{ "agent_id": "AGENT_ID", "user_id": "u_42", "variables": { "name": "Ann" }, "expires_in": 600 }'
התשובה כוללת token (שיחה אחת, תוך expires_in שניות, 30–3600, ברירת מחדל 600), agent (ה-slug) ו-web_call_url. העבירו את האסימון לדף עם data-token-url="/your/endpoint" על הסקריפט של הווידג'ט (הוא שולח לשם POST עם העוגיות של המבקר וקורא { "token": "…" }) או עם agent.setToken(async () => token). ה-variables של האסימון מאומתים: ההוראות, חיפוש ההתחלה ותבניות הפונקציות שלכם רשאים להשתמש בהם, וכך גם ב-user_id ששיחה שומרת (userId בשיחה, user_id לסינון שיחות). שמרו את מפתח ה-API שלכם בשרת שלכם.
באפליקציה שלכם שלחו POST עם { "token": "…", "pageTools": ["add_to_cart"] } אל https://evasay.com + web_call_url. התשובה היא חיבור השיחה (כתובת הצעה של WebRTC, או כתובת WebSocket, עם אסימון השיחה שלה), עבור לקוח RTVI כמו ערכות ה-SDK ללקוח של Pipecat לווב, iOS, Android ו-React Native. כרטיסים, פונקציות דף והודעות מגיעים כהודעות RTVI מסוג server-message (evasay.cards, evasay.tool, evasay.notice); שלחו מילים מוקלדות עם send-text ודיווחים ותשובות של הדף כהודעות client-message בשמות evasay.context ו-evasay.tool_result. או העבירו את השמע בעצמכם באמצעות שמע דרך WebSocket, עם user_id ו-page_tools.
תחת מספרי טלפון ← SIP המרכזייה שלכם, טלפוני SIP או קו SIP trunk שלכם יכולים להתקשר ישירות לסוכנים שלכם; ספק ה-SIP שלכם מחייב על השיחות:
sip:ev…@<EvaSay's SIP domain>, שיחות נכנסות בלבד, למרכזיות (3CX, FreePBX, Asterisk…) ולטלפוני SIP.from); העברות לאדם נמסרות לקו באמצעות REFER. כשהקו מבקש פרטי גישה, EvaSay עונה עם שם המשתמש והסיסמה של הקו שהזנתם.שיחות נכנסות מתחברות בשיטת digest עם שם המשתמש והסיסמה ש-EvaSay נותנת לכם (ה-realm הוא דומיין ה-SIP); אפשר גם להגביל את כתובות ה-IP של המקור, או לקבל לפי IP בלבד כשהספק שלכם אינו יכול להתחבר (כתובות ה-IP הן אז חובה). לכל כתובת SIP או קו יש מגבלה של שיחות בו-זמניות; מעבר לה שיחות מקבלות 486. סיסמאות מוצגות פעם אחת, בעת היצירה או האיפוס. UDP ו-G.711 (PCMU, PCMA) בלבד; מקשים באמצעות RFC 4733 או SIP INFO; כבו את הרישום (REGISTER) בקו של המרכזייה שלכם.
קמפיין מתקשר לרשימת אנשי קשר עם סוכן אחד, בתוך שעות חיוג ומגבלת מקביליות (max_concurrency, עד 100 שיחות בו-זמנית, ולעולם לא יותר ממגבלת השיחות הבו-זמניות של מרחב העבודה שלכם), וחוזר לנסות עם מי שלא הצליח להשיג.
curl https://evasay.com/api/v1/voice/campaigns \
-X POST \
-H "Authorization: Bearer sk-your-key" \
-H "Content-Type: application/json" \
-d '{
"name": "Appointment reminders",
"agent_id": "AGENT_ID",
"phone_number_id": "PHONE_NUMBER_ID",
"timezone": "America/New_York",
"window_start": "09:00",
"window_end": "18:00",
"max_concurrency": 2,
"max_attempts": 2,
"retry_delay_min": 60,
"consent_confirmed": true,
"contacts": [
{ "phone": "+14155550100", "name": "Alex", "appointment": "Tuesday 3 pm" }
]
}'
אנשי הקשר יכולים להיות גם טקסט CSV עם מספר הטלפון בעמודה הראשונה. consent_confirmed: true הוא חובה: בו אתם מאשרים שכל מי שברשימה הסכים שיתקשרו אליו, גם באמצעות קול של בינה מלאכותית, ו-EvaSay שומרת את האישור הזה עם הקמפיין (consent_confirmed_at). הקמפיין נוצר כטיוטה; התחילו אותו עם POST /api/v1/voice/campaigns/{id}/start, והשתמשו ב-pause או cancel באותו אופן. הסוכן חייב להיות מפורסם לפני שקמפיין מתחיל.
כש-voicemail_detection פעיל (ברירת המחדל) שיחה יוצאת ממתינה שהצד השני ידבר לפני שהסוכן מברך; אם הם שותקים, הסוכן מברך אחרי שתי שניות או שלוש. כשהסוכן שומע תא קולי או הקלטה של חברת טלפוניה, הוא ממתין עד שהברכה והצפצוף נגמרים, משאיר את voicemail_message, או מנתק כשאין הודעה. שיחות כאלה מסתיימות עם ended_reason בערך voicemail, מחויבות על הזמן שנמשכו, ואינן מנותחות או מדווחות.
בקמפיין, מספר שהגיע לתא קולי מחויג שוב כמו מספר שלא ענה, וההודעה נשארת רק בניסיון האחרון, כך שאיש אינו מקבל אותה הודעה פעמיים.
כל שיחה יוצאת, מקמפיין או מ-POST /api/v1/voice/calls, בודקת תחילה את רשימת "אל תתקשרו" של מרחב העבודה. מספר שברשימה לא מחויג לעולם: ה-API עונה 409 עם code בערך do_not_call, וקמפיין מסמן את איש הקשר כ-canceled עם outcome בערך do_not_call וממשיך לבא.
כשהאדם בשיחה שהסוכן ביצע מבקש שלא יתקשרו אליו שוב, הסוכן מוסיף את המספר שלו לרשימה בעצמו, אומר לו זאת, וה-Webhook בשם call.do_not_call נשלח. אפשר גם להוסיף ולהסיר מספרים תחת קמפיינים ← רשימת "אל תתקשרו" או עם ה-API:
curl https://evasay.com/api/v1/voice/do-not-call \
-X POST \
-H "Authorization: Bearer sk-your-key" \
-H "Content-Type: application/json" \
-d '{ "phones": ["+14155550100"], "note": "Asked by email" }'
המספרים בפורמט בין-לאומי; עד 1,000 בכל פעם. GET /api/v1/voice/do-not-call מציג אותם, החדשים ראשונים (search, limit, page), כל אחד עם source שלו (call, dashboard או api). DELETE /api/v1/voice/do-not-call/%2B14155550100 מסיר אחד מהרשימה; עשו זאת רק כשהאדם הסכים שיתקשרו אליו.
POST /api/v1/voice/voices יוצר קול מהקלטת WAV של דובר אחד (multipart עם audio, name, language, consent=true). הוא עונה 202 עם המצב running; שאלו את GET /api/v1/voice/voices עד שהמצב הוא ready, ואז הגדירו את voice_id של סוכן ל-voice_id של הקול. language היא השפה שמדוברת בהקלטה, כל אחת משפות הסוכנים שלעיל; הקול מדבר את כולן חוץ מסינית, שבה עונה קול מובנה מאותו מין, והוא דומה ביותר לדובר בהקלטה בשפת ההקלטה. כל קול משובט עולה קרדיטים, שלוח הבקרה מציג לפני שאתם יוצרים אחד.
הוסיפו כתובת https תחת אינטגרציות ← Webhooks והתראות כדי לקבל אירועי שיחה:
| אירוע | מתי |
|---|---|
call.started | הסוכן ענה |
call.ended | השיחה הסתיימה, עם משכה והקרדיטים |
call.analyzed | הסיכום, התוצאה, השדות שחולצו והתמלול מוכנים |
call.transcript | במהלך השיחה, השורות החדשות של התמלול כל כמה שניות |
call.tool_called | הסוכן קרא לאחת הפונקציות שלכם: name, arguments, status, durationMs |
call.handed_off | השיחה נמסרה לסוכן אחר: fromAgentId, toAgentId |
call.transferred | השיחה הועברה לאדם: destination |
call.voicemail | שיחה יוצאת הגיעה לתא קולי |
call.do_not_call | האדם בשיחה יוצאת ביקש שלא יתקשרו אליו שוב: phone |
call.recording_ready | ההקלטה הדו-ערוצית נשמרה: recordingUrl (תקף ל-24 שעות), durationMs |
call.message_sent | הסוכן הציג כרטיסים על מסך מתקשר מהאינטרנט או מהאפליקציה: items, quickReplies |
alert.triggered | אחת ההתראות שלכם (Webhooks והתראות ← התרעות) חצתה את הסף שלה |
alert.resolved | אותה התראה חזרה למצב תקין |
אירועים שנשלחים במהלך שיחה נושאים data.call (id, agentId, channel, direction, מספרים). כל בקשה חתומה:
EvaSay-Signature: t=<unix seconds>,v1=<hex HMAC-SHA256 of "<t>.<raw body>">
EvaSay-Delivery: <delivery id>
אמתו את החתימה עם סוד ה-Webhook שהוצג כשיצרתם אותו, וענו בסטטוס 2xx. מסירות שנכשלו מנוסות שוב אחרי דקה, 5 דקות, 30 דקות, שעתיים ו-12 שעות עם אותו גוף ואותו מזהה EvaSay-Delivery, כך שאפשר להתעלם מחזרות. המסירות האחרונות של Webhook, עם הגוף המדויק שנשלח והסטטוס שנקודת הקצה שלכם החזירה, מוצגות על ידי GET /webhooks/{id}/deliveries ובלוח הבקרה; POST /webhooks/{id}/deliveries/{delivery_id} שולח אחת מחדש.
מלבד דוא"ל והווב-הוקים alert.triggered / alert.resolved, התראות יכולות ללכת לערוץ Slack (incoming webhook), לרובוט קבוצה של WeCom או ל-Telegram תחת Webhooks והתראות ← התרעות ← לשלוח גם אל.
לשגיאות צורה אחת:
{
"error": {
"type": "invalid_request_error",
"code": "invalid_agent_field",
"message": "status must be draft or published",
"param": "status"
}
}
| סטטוס | משמעות |
|---|---|
| 400 | קלט לא תקין (code ו-param אומרים איזה) |
| 401 | מפתח API חסר או לא תקין |
| 402 | אין מספיק קרדיטים להתחלת השיחה |
| 403 | המפתח לקריאה בלבד, או שהסוכן אינו זמין |
| 404 | אין סוכן, שיחה או קמפיין כאלה במרחב העבודה הזה |
| 409 | מצב שגוי (למשל התחלת קמפיין שכבר רץ), חשבון ספק אינו מחובר, או שהמספר ברשימת "אל תתקשרו" (do_not_call) |
| 429 | יותר מדי בקשות; האטו ונסו שוב |
בקשות ה-API הקולי של מרחב העבודה ב-30 הימים האחרונים (זמן, endpoint, סטטוס, משך, מפתח וקוד שגיאה; ללא גופים) מופיעות תחת מפתחות API ← יומן בקשות API.
קריאות מוגבלות ל-120 בקשות בדקה לכל מפתח, וכתיבות ושיחות ל-30.
שיחות מחויבות לפי דקה מהקרדיטים של מרחב העבודה, אותה יתרה שלוח הבקרה משתמש בה. התעריפים הנוכחיים נמצאים בדף התמחור.
השתמשו בחוזה ה-OpenAPI כדי ליצור לקוח אינטגרציה. ה-API הציבורי, לוח הבקרה ונקודת הקצה לניהול MCP פועלים על אותם משאבים והרשאות של מרחב העבודה.
| יכולת | Endpoint |
|---|---|
| כלים לשימוש חוזר | GET / POST /api/v1/voice/tools |
| קריאה / עדכון / מחיקה של כלי | GET / PATCH / DELETE /api/v1/voice/tools/{id} |
| תצוגה מקדימה או בדיקה של כלי | POST /api/v1/voice/tools/{id}/test |
| קישור כלים לסוכן | PUT /api/v1/voice/agents/{id}/tools |
| מאגרי ידע | GET / POST /api/v1/voice/knowledge-bases |
| קריאה / עדכון / מחיקה של מאגר ידע | GET / PATCH / DELETE /api/v1/voice/knowledge-bases/{id} |
| הוספה / רשימה של מסמכים | POST / GET /api/v1/voice/knowledge-bases/{id}/documents |
| קריאה / מחיקה של מסמך | GET / DELETE /api/v1/voice/knowledge-bases/{id}/documents/{doc_id} |
| מנויים לאירועי שיחה | GET / POST /api/v1/voice/webhooks |
| קריאה / עדכון / מחיקה של מנוי | GET / PATCH / DELETE /api/v1/voice/webhooks/{id} |
| שליחת אירוע בדיקה חתום | POST /api/v1/voice/webhooks/{id}/test |
| גילוי כלי MCP מרוחקים | POST /api/v1/voice/mcp/discover |
| נקודת הקצה לניהול MCP | /api/v1/voice/mcp |
רשמו כלי HTTP ששואל את מתאם ה-CRM שלכם:
{
"name": "lookup_customer",
"description": "Find a customer after confirming their customer ID.",
"kind": "http",
"url": "https://crm.example.com/customers/{{customer_id}}",
"method": "GET",
"read_only": true,
"credential_ref": "crm",
"input_schema": {
"type": "object",
"properties": { "customer_id": { "type": "string" } },
"required": ["customer_id"],
"additionalProperties": false
},
"response_path": "data"
}
POST /tools מחזיר { "data": { "id": "TOOL_ID", ... } }. קשרו את ההגדרה שלו לסוכן עם PUT /agents/AGENT_ID/tools ו-{ "tool_ids": ["TOOL_ID"] }. פעולה זו מחליפה את כל רשימת הכלים בתצלומי מצב; קשרו מחדש כשכלי בספרייה משתנה. מחיקת הגדרה מהספרייה משאירה את התצלומים הקיימים. אפשר גם לקרוא ולהחליף הגדרות מוטמעות עם השדה tools של ה-API של הסוכן. השתמשו ב-analysis_config וב-widget_config כדי להגדיר את הניתוח והווידג'ט דרך ה-API של הסוכן.
כלי יכול להשתמש ב-GET, POST, PUT, PATCH או DELETE. query ו-request_body מקבלים תבניות JSON מקוננות כמו { "customer": { "id": "{{customer_id}}" } }. מציין מקום שלם שומר על סוג ה-JSON המקורי. מציייני מקום ב-URL מקודדים ויכולים להופיע רק אחרי מארח HTTPS ציבורי קבוע. ללא request_body, כלים שאינם GET מקבלים { "arguments": {...}, "call": { "callId": "...", "agentId": "...", "toolCallId": "...", "idempotencyKey": "..." } }. response_path בוחר שדה בסימון נקודות. parameters פשוטים עדיין מתקבלים; input_schema תומך בנוסף באובייקטים מקוננים, מערכים, רשימות ערכים וגבולות מספריים. הפניות לסכמות חיצוניות וביטויים רגולריים אינם מתקבלים.
static_args: ערכים שנשלחים בכל קריאה בלי קשר למה שהמודל כותב, כמו מזהה חנות; הם ממלאים גם את {{name}} בכתובת ובגוף.extract: [{name, path}] שומר שדות מתשובת פונקציה (data.id) עבור {{name}} של פונקציות מאוחרות יותר, כך ש-customer_id מחיפוש יכול להיכנס להזמנה שבאה אחריו בלי שהמודל יחזור עליו. שדות של חיפוש התחלה נשמרים באותו אופן.reject_when: עד 5 כללים {on: caller|agent, pattern, negate}; כל עוד כולם מתקיימים על המילים האחרונות, הפונקציה אינה רצה והסוכן מקבל את reject_message.model_says: בכל קריאה המודל כותב משפט אחד שנאמר בזמן שהפונקציה רצה, במקום speak_before הקבוע.חברו אפליקציה תחת אינטגרציות ← Webhooks והתראות ← אפליקציות מחוברות, ואז השתמשו ב"הוספת פונקציה מוכנה" בלשונית ידע וכלים של הסוכן; אין צורך ב-endpoint משלכם:
check_availability (שעות פנויות בתאריך) ו-book_appointment (קובע את השעה שהמתקשר בחר). השעות ב-Google Calendar עוקבות אחר אזור הזמן, ימי הפעילות, השעות ומשך הפגישה שהגדרתם; Cal.com משתמש בזמינות של סוג האירוע עצמו, ובדוא"ל גיבוי שתגדירו למקרה שהמתקשר לא נותן כתובת.save_to_sheet, שמוסיפה שורה עם העמודות שתציינו, יחד עם מזהה השיחה והשעה שלה.notify_team, שמפרסמת בערוץ Slack (incoming webhook) הודעה שהסוכן כותב.מישור הבקרה של EvaSay מריץ את הפונקציות האלה עם החשבון שחיברתם; לא ה-worker ולא הגדרת הסוכן מחזיקים את פרטי הגישה של האפליקציה. קריאת סוכן דרך ה-API מציגה אותן כ-kind: "app" (עם app, action, connection_id, app_config); שלחו אותן בחזרה ללא שינוי בעת החלפת tools כדי לשמור אותן. אפליקציות מחוברות בלוח הבקרה בלבד.
הגדירו run_at_start: true על אחד מכלי הסוכן והוא ייקרא בתחילת כל שיחה, לפני שהסוכן מברך או עונה. פרמטרים בשמות caller_number, called_number, direction, channel או call_id ממולאים עבורו. השדות שהוא מחזיר ממלאים {{variables}} ב-first_message, ב-system_prompt וב-idle_messages (שדות ברמה אחת מתחת כמו {{customer.name}}), והתשובה כולה ניתנת לסוכן כרקע. ברכה עם משתנים ממתינה לתשובה עד 3 שניות; מה שלא נמצא נשאר ריק. כלי אחד לכל סוכן יכול לרוץ בתחילה.
פרטי גישה מוגדרים בסביבת השרת עבור מרחב העבודה והיעד שלכם; בקשו מ-support@evasay.com להקצות credential_ref. אל תשימו מפתחות API בהגדרות סוכן, בכותרות, בהנחיות או בפרמטרים של כלים. המתאם שלכם יכול להחזיק את פרטי הגישה ל-CRM בסביבה שלו.
הציגו תצוגה מקדימה של כלי לפני ששולחים בקשות למערכת העסקית:
{
"arguments": { "customer_id": "customer-123" },
"dry_run": true,
"mock_result": { "name": "Alex", "order_status": "shipped" }
}
תצוגה מקדימה מאמתת את הפרמטרים ומציגה את הבקשה שמופתה; היא אינה מנהלת שיחה ואינה יוצרת קשר עם המערכת העסקית. הגדירו dry_run=false להרצה אמיתית. בדיקת כתיבה חיה דורשת גם confirmed=true ו-idempotency_key (8–128 אותיות, ספרות, נקודות, קווים תחתונים, נקודתיים או מקפים). תשובות בדיקה כוללות ok, status, duration_ms ותוצאה מוגבלת. הן אינן מחזירות פרטי גישה. בדיקות קריאה וכתיבה דורשות הרשאת כתיבה במרחב העבודה.
במהלך שיחה בקשות עסקיות נושאות Idempotency-Key יציב. ה-endpoint העסקי שלכם חייב לכבד אותו. כתיבות זהות בתוך שיחה עוברות הסרת כפילויות, כולל פעולות שתוצאתן לא ידועה אחרי פסק זמן. פעולה אחרת שנעשית בכוונה זקוקה לארגומנט עסקי נפרד, כמו operation_id. EvaSay אינה משחזרת כתיבות באופן אוטומטי. אירועי הרצת כלים כוללים סטטוס ומשך; תכונת בדיקת השיחה נשארת הדמיית טקסט, לא בדיקה של הרצת כלים.
הגדירו חיבור MCP מסוג Streamable HTTP עם:
URL: https://evasay.com/api/v1/voice/mcp
Authorization: Bearer <your EvaSay API key>
למשל ב-Claude Code:
claude mcp add --transport http evasay https://evasay.com/api/v1/voice/mcp --header "Authorization: Bearer $EVASAY_API_KEY"
החיבור מסביר לכלי איך לבנות סוכן: לקרוא את הקטלוג, ליצור טיוטה, להוסיף ידע, פונקציות ורשימות מילים, לכתוב בדיקות ולהריץ אותן, לתקן את הטיוטה עד שהן עוברות, לתת לכם את dashboard_url של הסוכן כדי לנסות אותו, ולפרסם ולנתב מספר רק אחרי שאישרתם. כלים שקוראים תיעוד יכולים להתחיל מ-https://evasay.com/llms.txt, שמקשר לדף הזה, לחוזה OpenAPI ולכתובת ה-MCP.
השתמשו בהגדרת האסימון או משתנה הסביבה המאובטחת של הלקוח. נקודת הקצה משתמשת באימות מפתח API, לא בתהליך התחברות OAuth. היא חושפת יצירה והגדרה של סוכנים, כלי ספרייה, ידע, Webhooks ורשומות שיחה. פרסום וביצוע שיחות אמיתיות הן פעולות כתיבה; שיחות יוצאות צורכות קרדיטים ועמלות ספק. כל קריאה לכלי בודקת שוב את הרשאות מרחב העבודה. הפעילו את בקרות האישור של הלקוח שלכם לפעולות כתיבה. נקודת הקצה משתמשת בתשובות JSON חסרות מצב; היא אינה מציעה זרם התראות ברקע.
דוגמה להוראה לכלי התכנות: "צור סוכן EvaSay כטיוטה, רשום את נקודת הקצה לחיפוש ב-CRM שלי, הצג לה תצוגה מקדימה עם ארגומנטי בדיקה, קשור אותה לסוכן והגדר Webhook בשם call.analyzed". עיינו ואשרו במפורש פרסום ושיחות אמיתיות.
POST /mcp/discover מקבל { "url": "https://crm.example.com/mcp", "credential_ref": "crm" } ומחזיר את הכלים והסכמות של השרת. רשמו רק את הכלי שנבחר:
{
"name": "lookup_customer",
"description": "Find a CRM customer by confirmed ID.",
"kind": "mcp",
"url": "https://crm.example.com/mcp",
"mcp_tool": "get_customer",
"credential_ref": "crm",
"read_only": true,
"input_schema": {
"type": "object",
"properties": { "customer_id": { "type": "string" } },
"required": ["customer_id"]
}
}
רק כלים רשומים זמינים לסוכן. חיבורים מרוחקים תומכים ב-Streamable HTTP עם תשובות JSON או SSE לבקשות, יעדי HTTPS ציבוריים ופרטי גישה שהוגדרו מראש. נקודות קצה ישנות של SSE, משא ומתן OAuth, sampling/elicitation שיוזם השרת וקבצים מצורפים בינאריים אינם נתמכים. הגילוי אינו מעניק אוטומטית גישה לכל כלי השרת. סכמת הכלי המרוחק חייבת להיות מוטמעת ולהשתמש בתת-הקבוצה הנתמכת של JSON Schema.
צרו Webhook באמצעות POST /webhooks עם { "url": "https://crm.example.com/evasay-events", "events": ["call.analyzed"] }. התשובה מכילה את המנוי וסוד חתימה שנוצר, שמוחזר רק ביצירה. אמתו את EvaSay-Signature, הסירו כפילויות של EvaSay-Delivery ועדכנו את ה-CRM שלכם. Webhooks של אירועים הם התראות אסינכרוניות; כלים במהלך שיחה מחזירים תוצאות ישירות לסוכן.