Το 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 |
| Δοκιμές ενός agent | GET · POST /api/v1/voice/agents/{id}/tests |
| Εκτέλεση δοκιμών / ανάγνωση εκτέλεσης | POST /api/v1/voice/agents/{id}/test-runs · GET /api/v1/voice/test-runs/{id} |
| Ανάθεση αριθμού σε agent | PATCH /api/v1/voice/phone-numbers/{id} |
| Λίστες λέξεων | GET · POST /api/v1/voice/vocabularies |
Δημιουργήστε ένα κλειδί στον πίνακα ελέγχου, στο Ενσωματώσεις → Κλειδιά API (ή με ένα κλικ στην επισκόπηση), και στείλτε το ως Bearer token:
Authorization: Bearer sk-your-key
Ένα κλειδί ενεργεί στον χώρο εργασίας όπου εργάζεται ο κάτοχός του, με τον ρόλο εκείνου του ατόμου: το κλειδί ενός μέλους μόνο ανάγνωσης μπορεί να διαβάζει αλλά όχι να αλλάζει τίποτα.
Δημιουργήστε έναν πράκτορα από ένα πρότυπο, ορίζοντας προαιρετικά τα πεδία του στο ίδιο αίτημα. Χωρίς template ξεκινά κενός· το GET /api/v1/voice/catalog παραθέτει τα πρότυπα μαζί με τις γλώσσες και τις φωνές που δέχεται ένας agent. Τα πρότυπα είναι γραμμένα στα αγγλικά και στα κινεζικά, οπότε για άλλη γλώσσα στείλτε system_prompt και first_message σε αυτήν. Είτε αποθηκεύεται ολόκληρο το αίτημα είτε δεν δημιουργείται agent, οπότε ένα αίτημα που απορρίφθηκε μπορεί να σταλεί ξανά αφού διορθωθεί. Το dashboard_url της απάντησης είναι η σελίδα του agent στον πίνακα ελέγχου, όπου μιλάτε με το πρόχειρο από τον browser. Κάθε πράκτορας λειτουργεί με 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 επαναφέρει: οι νέες κλήσεις χρησιμοποιούν εκείνη την έκδοση και το προσχέδιο γίνεται αυτή. Το όνομα του πράκτορα, η ανάπτυξη, η εμφάνιση του widget και οι ειδοποιήσεις δεν έχουν εκδόσεις και αλλάζουν αμέσως, όπως και τα έγγραφα της βάσης γνώσης του.
Μια δοκιμή παίζει μία κλήση σε κείμενο: ένας προσομοιωμένος καλών υποδύεται το scenario, ο agent απαντά από το πρόχειρό του (οδηγίες, πρώτο μήνυμα και γνώση) και ένας κριτής ελέγχει τη συνομιλία με βάση το 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 εκτελεί όλες τις δοκιμές του agent, ή όσες είναι στο test_ids, και απαντά με μία εκτέλεση ανά δοκιμή (status: "running"). Ρωτάτε το GET /test-runs/{id} μέχρι το status να γίνει passed, failed ή error· τότε η εκτέλεση έχει το transcript και το reason του κριτή (στα αγγλικά, ή στα κινεζικά με reason_language: "zh"). Κάθε εκτέλεση κοστίζει Credits, που εμφανίζονται μαζί με τις δοκιμές στον πίνακα ελέγχου· οι εκτελέσεις σταματούν στην πρώτη που δεν καλύπτει το υπόλοιπο, και το not_started παραθέτει τις υπόλοιπες. Μια εκτέλεση που δεν ολοκληρώνεται επιστρέφεται. Οι δοκιμές ελέγχουν τι λέει ο agent, όχι τη φωνή ή τον χρονισμό του, και δεν καλούν τις συναρτήσεις του: δοκιμάστε τις πρώτα με POST /tools/{id}/test. Ένας agent έχει έως 30 δοκιμές· τα PATCH και DELETE /agents/{id}/tests/{test_id} αλλάζουν ή αφαιρούν μία.
Εκτός από ολόκληρες κλήσεις (type: "simulation", προεπιλογή), μια δοκιμή μπορεί να ελέγξει μία μόνο απάντηση. Το type: "next_reply" παίρνει chat_history, τη συνομιλία πριν από αυτήν που τελειώνει με τον καλούντα ([{role, text}], με role ίσο με caller ή agent), και success_criteria για την επόμενη απάντηση του agent. Το type: "tool_call" παίρνει chat_history και expected_tool {name, arguments, match}: ο agent πρέπει να καλέσει το name (μία από τις συναρτήσεις του ή end_call, transfer_call, handoff_to_agent) με arguments, που συγκρίνονται ακριβώς (κείμενο χωρίς κενά στα άκρα, χωρίς διάκριση πεζών-κεφαλαίων) ή, με match: "judge", κατά νόημα· τα υπόλοιπα ορίσματα αγνοούνται. Το transcript μιας εκτέλεσης δείχνει στο tool_calls τις συναρτήσεις που κάλεσε ο agent.
Το POST /agents/{id}/tests/generate προτείνει δοκιμές από το πρόχειρο του agent: οδηγίες, γνώση και συναρτήσεις. Παίρνει 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 είναι ο κύριος αριθμός του πράκτορα για να περάσει έναν καλούντα σε άνθρωπο και ο αριθμός που καλείται όταν ο χώρος εργασίας έχει εξαντλήσει τα credits. Το 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 (στη δημοσιευμένη έκδοσή του), ή με "agent_id": null σε κανέναν· το label τον μετονομάζει.
Μια λίστα λέξεων περιέχει ονόματα και όρους που λένε οι καλούντες και που η αναγνώριση ομιλίας θα άκουγε λάθος, όπως ονόματα προϊόντων, φαρμάκων ή οδών. POST /api/v1/voice/vocabularies με { "name": "Products", "terms": ["Lumora", "Vantix Pro"] } (έως 1.000 όροι των 50 χαρακτήρων, ή "preset": "medical" ή "legal" ως αφετηρία) και μετά ορίστε το vocabulary_id του agent. GET, PATCH (name, terms) και DELETE /vocabularies/{id}· λίστα που χρησιμοποιεί κάποιος agent δεν διαγράφεται.
Κάθε αριθμός έχει κανόνες κλήσης στη σελίδα Αριθμοί τηλεφώνου, που εφαρμόζονται πριν απαντήσει ο πράκτορας: αποκλεισμένοι αριθμοί ή αρχές αριθμών (+1555) και καλούντες που κρύβουν τον αριθμό τους απορρίπτονται χωρίς απάντηση και δεν κοστίζουν τίποτα· οι καλούντες μιας λίστας μπορούν να περάσουν κατευθείαν σε άλλον αριθμό· και όταν ο πράκτορας δεν μπορεί να απαντήσει (μη δημοσιευμένος, χωρίς worker, εξαντλημένα credits χωρίς αριθμό μεταφοράς) η κλήση μπορεί να χτυπήσει σε έναν αριθμό ή να παίξει το δικό σας μήνυμα. Μια αναζήτηση έναρξης (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}} στο πρώτο μήνυμα και στο prompt του πράκτορα.
Το GET /api/v1/voice/calls/{id} επιστρέφει την κατάσταση της κλήσης, τη διάρκεια, τα credits που χρεώθηκαν, τη σύνοψη, την ανάλυση και την απομαγνητοφώνηση. Παραθέστε κλήσεις με GET /api/v1/voice/calls?agent_id=&status=&channel=&user_id=&page= (user_id: το δικό σας αναγνωριστικό για το άτομο, από ένα token web κλήσης). Τα 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": "..." } όλες τις κλήσεις web με αυτό το user_id στο token τους. Απαντά { "deleted": 12, "kept_back": { "settling": 1 }, "more": false }: έως 200 κλήσεις ανά αίτημα, οπότε ζητήστε ξανά όσο το more είναι true, και αργότερα για τις κλήσεις στο kept_back. Αν ο αριθμός είναι στη λίστα «Μην καλείτε», παραμένει εκεί. Στον πίνακα ελέγχου το ίδιο γίνεται από Κλήσεις → Διαγραφή δεδομένων καλούντος.
Στείλτε POST /api/v1/voice/calls/{id}/control ενώ μια κλήση βρίσκεται σε εξέλιξη. Ο worker που εκτελεί την κλήση παίρνει την εντολή μέσα σε περίπου 2 δευτερόλεπτα· το 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 bit 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 στην απάντηση φέρει ένα token μίας χρήσης και μπορεί να ανοιχτεί μέσα σε 15 λεπτά. Το encoding είναι pcm_s16le (PCM 16 bit little-endian με sample_rate 8000, 16000 ή 24000) ή mulaw (μ-law 8 kHz). Ο ήχος κινείται προς τις δύο κατευθύνσεις ως δυαδικά πλαίσια σε αυτή τη μορφή, ιδανικά των 20 ms το καθένα. Τα πλαίσια κειμένου είναι 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, και μετά το socket κλείνει) |
Ο πράκτορας χαιρετά μόλις συνδεθείτε. Στο αίτημα μπορούν να προστεθούν user_id και page_tools (οι συναρτήσεις σελίδας στις οποίες απαντά η εφαρμογή σας, βλ. παρακάτω). Οι κλήσεις χρεώνονται ανά λεπτό όπως όλες οι άλλες, με τα ίδια αρχεία κλήσεων, την ίδια ανάλυση και τα ίδια webhooks.
Σε μια web κλήση (το widget, η φιλοξενούμενη σελίδα, η εφαρμογή σας) ο καλών βλέπει ένα chat δίπλα στη φωνή, ώστε ο πράκτορας να μπορεί να κάνει περισσότερα από το να μιλά. Οι καλούντες από τηλέφωνο δεν έχουν τίποτα από αυτά.
Ενεργοποιήστε το Πράκτορας → Εργαλεία → Αποστολή στον καλούντα (send_to_caller στο API πρακτόρων) και ο πράκτορας μπορεί να τοποθετεί έως πέντε κάρτες τη φορά στην οθόνη του καλούντος: έναν τίτλο, μια γραμμή από κάτω, μια περιγραφή, μια εικόνα, έναν σύνδεσμο και έως δύο κουμπιά απάντησης η καθεμία· μπορεί επίσης να προσφέρει έως τρεις γρήγορες απαντήσεις κάτω από μια ερώτηση. Οι σύνδεσμοι δεν διαβάζονται ποτέ φωναχτά.
Ο πράκτορας μπορεί να στέλνει μόνο συνδέσμους και εικόνες που του δόθηκαν σε εκείνη την κλήση: τις οδηγίες και τον χαιρετισμό του, τη βάση γνώσης (ένα έγγραφο που διαβάστηκε από μια ιστοσελίδα φέρει τη διεύθυνσή της), τις απαντήσεις των συναρτήσεών σας και τις έτοιμες κάρτες. Ένας σύνδεσμος πρέπει επίσης να βρίσκεται σε έναν από τους allowed_hosts (ο ίδιος ο ιστότοπος μιας έτοιμης κάρτας είναι πάντα). Σύνδεσμοι που επινοεί ο πράκτορας ή που υπαγορεύει φωναχτά ο καλών δεν στέλνονται. Οι σύνδεσμοι προς αυτούς τους ιστότοπους μέσα στα λόγια του πράκτορα είναι κλικαριστοί στο chat.
"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 φορές.
Κατά τη διάρκεια της κλήσης ο καλών μπορεί επίσης να πληκτρολογήσει (μια διεύθυνση email, έναν αριθμό παραγγελίας) ή να αγγίξει ένα κουμπί απάντησης· ο πράκτορας απαντά όπως σε ομιλία, σταματώντας πρώτα αν μιλούσε. Έως 500 χαρακτήρες ανά μήνυμα, ένα το δευτερόλεπτο, 100 ανά κλήση. Στο αρχείο της κλήσης αυτοί οι γύροι σημειώνονται ως πληκτρολογημένοι ή αγγιγμένοι.
Το widget δίνει στη σελίδα σας ένα αντικείμενο evasay. Όλα είναι προαιρετικά, και το πλαίσιο της κλήσης ακούει τη σελίδα σας μόνο αν είναι ένας από τους επιτρεπόμενους ιστότοπους του widget (Πράκτορας → Ανάπτυξη):
<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. Εκτελείται με τη σύνδεση του επισκέπτη, σαν δικό του κλικ: ζητήστε επιβεβαίωση στη δική σας σελίδα πριν από οτιδήποτε κοστίζει χρήματα ή δεν αναιρείται. Σύνδεσμοι στην απάντησή της μπορούν να σταλούν ως κάρτες.Ορίστε το Ποιος μπορεί να ξεκινήσει κλήση σε Μόνο με token και ζητήστε από τον διακομιστή σας ένα token μίας χρήσης για τον συνδεδεμένο χρήστη:
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. Δώστε το token στη σελίδα με data-token-url="/your/endpoint" στο script του widget (κάνει εκεί POST με τα cookies του επισκέπτη και διαβάζει { "token": "…" }) ή με agent.setToken(async () => token). Τα variables του token είναι επαληθευμένα: οι οδηγίες, η αναζήτηση έναρξης και τα πρότυπα των συναρτήσεών σας μπορούν να τα χρησιμοποιούν, όπως και το user_id, που η κλήση διατηρεί (userId στην κλήση, user_id για φιλτράρισμα κλήσεων). Κρατήστε το κλειδί API σας στον διακομιστή σας.
Στη δική σας εφαρμογή, κάντε POST { "token": "…", "pageTools": ["add_to_cart"] } στο https://evasay.com + web_call_url. Η απάντηση είναι η σύνδεση της κλήσης (μια διεύθυνση προσφοράς WebRTC ή μια διεύθυνση WebSocket, με το token κλήσης της), για έναν πελάτη RTVI όπως τα client SDK του Pipecat για web, 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 το δικό σας PBX, τα SIP τηλέφωνα ή το SIP trunk σας μπορούν να καλούν απευθείας τους πράκτορές σας· τις κλήσεις χρεώνει ο πάροχος SIP σας:
sip:ev…@<EvaSay's SIP domain>, μόνο εισερχόμενες κλήσεις, για PBX (3CX, FreePBX, Asterisk…) και SIP τηλέφωνα.from)· οι μεταφορές σε άνθρωπο παραδίδονται στο trunk με REFER. Όταν το trunk ζητά διαπιστευτήρια, η EvaSay απαντά με το όνομα χρήστη και τον κωδικό του trunk που εισαγάγατε.Οι εισερχόμενες κλήσεις συνδέονται με digest με το όνομα χρήστη και τον κωδικό που σας δίνει η EvaSay (το realm είναι το SIP domain)· μπορείτε επίσης να περιορίσετε τις IP προέλευσης, ή να δέχεστε μόνο με IP όταν ο πάροχός σας δεν μπορεί να συνδεθεί (οι IP είναι τότε υποχρεωτικές). Κάθε διεύθυνση SIP ή trunk έχει όριο ταυτόχρονων κλήσεων· πέρα από αυτό οι κλήσεις παίρνουν 486. Οι κωδικοί εμφανίζονται μία φορά, κατά τη δημιουργία ή την επαναφορά. Μόνο UDP και G.711 (PCMU, PCMA)· πλήκτρα μέσω RFC 4733 ή SIP INFO· απενεργοποιήστε την εγγραφή (REGISTER) στο trunk του PBX σας.
Μια καμπάνια καλεί μια λίστα επαφών με έναν πράκτορα, εντός ωρών κλήσης και ορίου ταυτοχρονισμού (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 είναι η γλώσσα που μιλιέται στην ηχογράφηση, οποιαδήποτε από τις γλώσσες πρακτόρων παραπάνω· η φωνή τις μιλά όλες εκτός από τα κινεζικά, όπου απαντά μια ενσωματωμένη φωνή του ίδιου φύλου, και μοιάζει περισσότερο με τον ομιλητή της ηχογράφησης στη γλώσσα της ηχογράφησης. Κάθε κλωνοποιημένη φωνή κοστίζει credits, που εμφανίζονται στον πίνακα ελέγχου πριν δημιουργήσετε μία.
Προσθέστε μια διεύθυνση https στο Ενσωματώσεις → Webhooks και ειδοποιήσεις για να λαμβάνετε συμβάντα κλήσεων:
| Συμβάν | Πότε |
|---|---|
call.started | Ο πράκτορας απάντησε |
call.ended | Η κλήση τελείωσε, με τη διάρκεια και τα credits |
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 | Ο πράκτορας έδειξε κάρτες στην οθόνη ενός καλούντος από web ή εφαρμογή: 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. Οι αποτυχημένες παραδόσεις επαναλαμβάνονται μετά από 1 λεπτό, 5 λεπτά, 30 λεπτά, 2 ώρες και 12 ώρες με το ίδιο σώμα και το ίδιο αναγνωριστικό EvaSay-Delivery, ώστε να μπορείτε να αγνοείτε τις επαναλήψεις. Οι τελευταίες παραδόσεις ενός webhook, με το ακριβές σώμα που στάλθηκε και την κατάσταση που απάντησε το endpoint σας, παρατίθενται από το GET /webhooks/{id}/deliveries και στον πίνακα ελέγχου· το POST /webhooks/{id}/deliveries/{delivery_id} στέλνει ξανά μία.
Εκτός από το email και τα webhooks 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 | Δεν υπάρχουν αρκετά credits για την έναρξη της κλήσης |
| 403 | Το κλειδί είναι μόνο ανάγνωσης ή ο πράκτορας δεν είναι διαθέσιμος |
| 404 | Δεν υπάρχει τέτοιος πράκτορας, κλήση ή καμπάνια σε αυτόν τον χώρο εργασίας |
| 409 | Λάθος κατάσταση (π.χ. έναρξη καμπάνιας που τρέχει), ένας λογαριασμός παρόχου δεν είναι συνδεδεμένος, ή ο αριθμός βρίσκεται στη λίστα «Μην καλείτε» (do_not_call) |
| 429 | Πάρα πολλά αιτήματα· επιβραδύνετε και ξαναδοκιμάστε |
Τα αιτήματα Voice API του χώρου εργασίας των τελευταίων 30 ημερών (ώρα, endpoint, κατάσταση, διάρκεια, κλειδί και κωδικός σφάλματος· χωρίς σώματα) παρατίθενται στο Κλειδιά API → Αρχείο αιτημάτων API.
Οι αναγνώσεις περιορίζονται σε 120 αιτήματα το λεπτό ανά κλειδί, οι εγγραφές και οι κλήσεις σε 30.
Οι κλήσεις χρεώνονται ανά λεπτό από τα credits του χώρου εργασίας, το ίδιο υπόλοιπο που χρησιμοποιεί ο πίνακας ελέγχου. Οι τρέχουσες τιμές βρίσκονται στη σελίδα τιμών.
Χρησιμοποιήστε το συμβόλαιο OpenAPI για να δημιουργήσετε έναν client ενσωμάτωσης. Το δημόσιο API, ο πίνακας ελέγχου και το endpoint διαχείρισης 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 |
| Endpoint διαχείρισης 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 για να ρυθμίσετε την ανάλυση και το widget μέσω του 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 χρησιμοποιεί τη δική του διαθεσιμότητα του τύπου συμβάντος και ένα εναλλακτικό email που ορίζετε για όταν ο καλών δεν δίνει κανένα.save_to_sheet, που προσθέτει μια γραμμή με τις στήλες που αναφέρετε, συν το ID και την ώρα της κλήσης.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 σε ορισμούς πρακτόρων, κεφαλίδες, prompts ή παραμέτρους εργαλείων. Ο προσαρμογέας σας μπορεί να κρατά τα διαπιστευτήρια του 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 πρέπει να το τηρεί. Πανομοιότυπες εγγραφές μέσα σε μια κλήση αποδιπλασιάζονται, συμπεριλαμβανομένων λειτουργιών με άγνωστο αποτέλεσμα μετά από timeout. Μια διαφορετική σκόπιμη λειτουργία χρειάζεται ξεχωριστό επιχειρηματικό όρισμα, όπως 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"
Η σύνδεση λέει στο εργαλείο πώς να φτιάξει έναν agent: να διαβάσει τον κατάλογο, να δημιουργήσει πρόχειρο, να προσθέσει γνώση, συναρτήσεις και λίστες λέξεων, να γράψει και να εκτελέσει δοκιμές, να διορθώνει το πρόχειρο μέχρι να περάσουν, να σας δώσει το dashboard_url του agent για να τον δοκιμάσετε, και να δημοσιεύσει και να αναθέσει αριθμό μόνο αφού εγκρίνετε. Τα εργαλεία που διαβάζουν τεκμηρίωση μπορούν να ξεκινήσουν από το https://evasay.com/llms.txt, που παραπέμπει σε αυτή τη σελίδα, στο συμβόλαιο OpenAPI και στη διεύθυνση MCP.
Χρησιμοποιήστε την ασφαλή ρύθμιση token ή μεταβλητής περιβάλλοντος του client. Το endpoint χρησιμοποιεί έλεγχο ταυτότητας με κλειδί API, όχι ροή σύνδεσης OAuth. Εκθέτει τη δημιουργία και ρύθμιση πρακτόρων, τα εργαλεία της βιβλιοθήκης, τη γνώση, τα webhooks και τα αρχεία κλήσεων. Η δημοσίευση και οι πραγματικές κλήσεις είναι ενέργειες εγγραφής· οι εξερχόμενες κλήσεις καταναλώνουν credits και χρεώσεις παρόχου. Κάθε κλήση εργαλείου ελέγχει ξανά τα δικαιώματα του χώρου εργασίας. Ενεργοποιήστε τους ελέγχους επιβεβαίωσης του client σας για τις ενέργειες εγγραφής. Το endpoint χρησιμοποιεί απαντήσεις JSON χωρίς κατάσταση· δεν προσφέρει ροή ειδοποιήσεων στο παρασκήνιο.
Ένα παράδειγμα οδηγίας για το εργαλείο προγραμματισμού είναι: «Δημιούργησε έναν πράκτορα EvaSay ως προσχέδιο, καταχώρισε το endpoint αναζήτησης του 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 και προρυθμισμένα διαπιστευτήρια. Τα παλαιά endpoints 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 συμβάντων είναι ασύγχρονες ειδοποιήσεις· τα εργαλεία κατά τη διάρκεια της κλήσης επιστρέφουν τα αποτελέσματα απευθείας στον πράκτορα.