API זה מתמלל קובצי שמע שהושלמו כמשימות בתור. שלחו קובץ, שמרו את מזהה המשימה שהוחזר ואחזרו את המשימה עד לסיום העיבוד. שלחו כל בקשה ב-HTTPS עם פרטי האימות של חשבונכם, באמצעות פרטי HTTP Basic כפי שמוצג בדוגמאות או אסימון API, כמתואר בסעיף אימות. שמרו את פרטי האימות בשרת שלכם.
נקודות קצה
שני שרתי API, https://api.multi.tel ושרת התאימות https://api.multitel.net, חולקים אותן משימות ברמת החשבון, מפתחות אידמפוטנטיות, מגבלות וחיוב. הם נבדלים בקידוד ההעלאה ובמבנה מעטפת התגובה, לכן השתמשו בעקביות בשרת אחד עם מנתח תגובות תואם.
| פעולה | שיטה ונתיב |
|---|---|
| מידע על השירות | GET /v3/speech_to_text |
| שליחת משימה | POST /v3/speech_to_text |
| הערכה ללא יצירת משימה | POST /v3/speech_to_text/estimate |
| קריאת משימה | GET /v3/speech_to_text/JOB_ID |
| הסדרת תשלום למשימה הממתינה לתשלום | POST /v3/speech_to_text/JOB_ID/settle |
| שימוש | GET /v3/speech_to_text/usage |
בשרת api.multi.tel, כל נתיב זמין גם עם הקידומת /v1/speech-to-text במקום /v3/speech_to_text, לדוגמה POST /v1/speech-to-text/estimate. בשרת api.multitel.net, השתמשו בנתיבי /v3/speech_to_text.
תגובת המידע על השירות מדווחת על mode (batch), realtime (false), paidEnabled (האם מתקבלות כעת משימות חדשות בתשלום), pricePerMinuteUsd (0.005), billingUnit (audio_second), maxAudioSeconds (7200) וכן maxUploadBytes (26214400), יחד עם תיאור קצר בשדה description. קריאת המידע היא ללא עלות ופועלת גם כשהגשת משימות בתשלום מושבתת; היא מחזירה 503 transcription_unavailable רק כשהשירות כולו אינו זמין.
הכנת קובץ שמע
השתמשו בקובץ שמע שהושלם, בגודל של עד 25 MiB (26,214,400 בתים) ובאורך של עד 2 שעות (7,200 שניות). בעת השליחה, הקובץ חייב להיות מזוהה כמדיה בפורמט MP3, WAV, Ogg, FLAC, MOV או Matroska המכילה זרם שמע, עם משך במטא-נתונים הגדול מאפס ואינו עולה על 7,200 שניות. קובץ מזוהה שאינו עומד בבדיקות אלה נדחה עם 422 unsupported_audio. קובץ שלא ניתן לקרוא באף אחד מהפורמטים האלה עשוי כרגע להידחות במקום זאת עם שגיאת שרת (500); אל תשלחו שוב קובץ כזה ללא שינוי. סיומת קובץ לבדה אינה מעידה על תאימות.
מעבר הבדיקות אינו מבטיח שניתן לפענח את השמע. השמע מעובד כערוץ אחד או שניים. קובץ עם יותר משני ערוצי שמע, קובץ שהשמע המפוענח שלו ארוך מ-2 שעות, או כל קובץ אחר שפענוחו נכשל במהלך העיבוד, מסתיים כמשימה במצב failed, בדרך כלל עם decode_failed, ואינו מחויב. המירו שמע מרובה ערוצים למונו או לסטריאו לפני השליחה.
רמז השפה האופציונלי הוא קוד בן שתיים או שלוש אותיות קטנות המציין את השפה המדוברת, כגון en. כדי לא לספק רמז, השמיטו את השדה; api.multi.tel דוחה מחרוזת ריקה. הרמז מנחה את העיבוד אך אינו נבדק מול רשימת שפות נתמכות, לכן השתמשו בקוד תקין של השפה המדוברת.
שליחת משימת תמלול
שלחו JSON עם Content-Type: application/json אל POST https://api.multi.tel/v3/speech_to_text. גוף הבקשה יכול להיות בגודל של עד 35 MiB, כדי להכיל קובץ בגודל המרבי לאחר קידוד base64; גוף גדול יותר נדחה עם 413.
| שדה | משמעות |
|---|---|
audioBase64 | נדרש. הקובץ המלא ב-base64 תקני (A–Z, a–z, 0–9, +, /) עם תווי מילוי = לפי הצורך. אל תוסיפו קידומת data-URL, מעברי שורה או רווחים, ואל תשתמשו באלפבית המותאם לכתובות URL. הערך חייב להתפענח לקובץ בגודל שבין 1 בית ל-25 MiB ולהתקודד מחדש לאותו טקסט בדיוק. |
language | רמז שפה אופציונלי, כמתואר לעיל. |
כל מאפיין JSON אחר, כולל idempotency_key, נדחה עם 400 invalid_transcription_request. שלחו את המפתח ככותרת.
מפתח אידמפוטנטיות
כל שליחה דורשת כותרת Idempotency-Key באורך של 1 עד 190 תווים. השתמשו באותיות ASCII, בספרות, ב--, _, . וב-:, ללא רווחים בתחילת הערך או בסופו: שרת התאימות מסיר רווחים מסביב ומודד את המפתח בבתים, לכן תווים אחרים עשויים להיספר אחרת בכל שרת. מפתח חסר, או מפתח באורך 191 תווים ומעלה, נדחה עם 400.
המפתחות משויכים לחשבונכם ולשירות המרת דיבור לטקסט, בשני השרתים ובכל פרטי האימות של החשבון. שליחה חוזרת של אותו מפתח עם אותו קובץ ושפה מחזירה את המשימה הקיימת עם HTTP 200 ו-duplicate: true, ללא קשר למצבה וגם אם העיבוד עודכן מאז יצירתה, ללא חיוב נוסף. שימוש חוזר במפתח עם קובץ או שפה שונים מחזיר 409 idempotency_conflict. מפתח חדש יוצר משימה חדשה גם עבור קובץ זהה, עם חיוב נפרד אם העיבוד מסתיים בהצלחה.
API_USER="your-api-username"
API_PASSWORD="your-api-password"
node -e 'process.stdout.write(JSON.stringify({audioBase64:require("node:fs").readFileSync("completed-call.mp3").toString("base64"),language:"en"}))' > completed-call.json
curl --fail-with-body --silent --show-error --user "$API_USER:$API_PASSWORD" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: speech-call-001" \
--data-binary @completed-call.json \
-o speech-job.json \
https://api.multi.tel/v3/speech_to_text
node -p 'JSON.parse(require("node:fs").readFileSync("speech-job.json","utf8")).data.id'משימה חדשה מחזירה HTTP 202 עם השדות המוצגים להלן, ושליחה חוזרת מחזירה HTTP 200 עם אובייקט המשימה המלא המתואר בסעיף קריאת התמלול. קראו את מזהה המשימה, שהוא UUID, מתוך data.id. תגובה למשימה חדשה נראית כך (המזהה והערכים הם דוגמאות):
{
"status": "success",
"data": {
"id": "3f6c1b2e-8a4d-4e7f-9c21-5b0d7e4a9f13",
"status": "queued",
"mode": "batch",
"realtime": false,
"source": "api",
"durationSeconds": 90.5,
"billedSeconds": 91,
"costUsd": "0.007583334",
"pricePerMinuteUsd": "0.005"
}
}כל עוד משימה נמצאת בתור או פועלת, durationSeconds, billedSeconds ו-costUsd הם אומדנים מהמטא-נתונים של הקובץ. החיוב הסופי מבוסס על משך השמע המפוענח.
שליחה יכולה גם להחזיר 402 insufficient_balance כאשר יתרה ששולמה מראש אינה מספיקה לכיסוי המשימה יחד עם המשימות האחרות שלכם שטרם הסתיימו, 429 transcription_queue_full כאשר לחשבונכם או לשירות יש יותר מדי משימות שטרם הסתיימו, 429 audio_validation_busy כאשר אין קיבולת פנויה לאימות קבצים, וכן 503 paid_transcription_not_enabled כאשר תמלול בתשלום מושבת. נסו שוב מאוחר יותר לאחר תגובות 429 ו-503, עם אותו מפתח.
הערכה ללא יצירת משימה
שלחו את אותו גוף JSON אל POST https://api.multi.tel/v3/speech_to_text/estimate. אין צורך במפתח אידמפוטנטיות. הערכה מאמתת ומודדת את הקובץ, אך אינה מתמללת אותו, יוצרת משימה, משריינת כספים, בודקת את יתרתכם או מחייבת את חשבונכם. רמז language מתקבל אך אינו משפיע על ההערכה.
הערכה מוצלחת מחזירה HTTP 200 עם estimate: true, charged: false, mode, realtime, durationSeconds, billedSeconds, pricePerMinuteUsd ו-costUsd תחת data. היא משתמשת במשך שבמטא-נתונים של הקובץ, בעוד שמשימה שהושלמה מחויבת לפי משך השמע המפוענח, שעשוי להיות שונה. הערכות מחילות את אותן בדיקות קובץ כמו שליחות. הן זמינות רק כאשר תמלול בתשלום מופעל (אחרת מתקבל 503 paid_transcription_not_enabled). הן עשויות להחזיר 429 audio_validation_busy כאשר אין קיבולת פנויה לאימות קבצים; נסו שוב לאחר המתנה קצרה.
קריאת התמלול
בצעו תשאול מחזורי של GET /v3/speech_to_text/JOB_ID כמתואר במדריך זרימת העבודה של משימות. אובייקט המשימה מכיל את השדות הבאים:
| שדה | משמעות |
|---|---|
id | ה-UUID של המשימה. |
status | queued, running, completed, failed או awaiting_payment. |
progress | אחוז בין 0 ל-99 בזמן הפעולה, אם זמין; 100 לאחר השלמה; אחרת null. |
durationSeconds, billedSeconds | משך השמע והשניות השלמות לחיוב. אלה אומדנים מהמטא-נתונים כשהמשימה בתור או פועלת, והם מבוססים על משך השמע המפוענח לאחר השלמתה או כשהיא ממתינה לתשלום. |
costUsd, costIsEstimate | העלות בדולרים אמריקאיים כמחרוזת עשרונית עם תשע ספרות אחרי הנקודה. costIsEstimate הוא true כל עוד המשימה בתור או פועלת. משימה שנכשלה אינה מחויבת, אף שהשדה costUsd שלה עדיין מציג את האומדן. |
pricePerMinuteUsd | 0.005 עבור משימות API, ו-0.000 עבור משימות חינמיות של הקלטות Hosted PBX. |
failureCode | למשימה שנכשלה: decode_failed (לא ניתן היה לפענח את השמע, למשל משום שיש בו יותר משני ערוצים או שאורכו לאחר הפענוח עולה על 2 שעות), inference_timeout (העיבוד ארך זמן רב מדי), service_error, או worker_lease_lost (העיבוד הופסק). גם הקודים unsupported_audio ו-quality_check_failed מוגדרים. משימה הממתינה לתשלום מציגה insufficient_balance, שעשוי להישאר גם לאחר הסדרת התשלום למשימה. |
source, modelVersion, createdAt | source הוא api עבור שליחות API, או hpbx עבור משימת הקלטה של Hosted PBX בחשבונכם. modelVersion הוא מחרוזת אטומה של גרסת העיבוד. createdAt הוא זמן השליחה. |
duplicate | true בתגובות המחזירות משימה קיימת. |
result | מופיע רק כאשר status הוא completed. |
| שדה בתוצאה | משמעות |
|---|---|
text | התמלול המלא: הטקסטים של כל המקטעים מחוברים במעברי שורה, לפי סדר המקטעים. |
segments | מערך מקטעים המסודרים לפי זמן ההתחלה. כל מקטע מכסה חלק מהשמע באורך של עד כ-29 שניות. השדות start ו-end (בשניות מתחילת השמע) מסמנים את החלק הזה, ולא מילים או משפטים בודדים, וחלקים עוקבים יכולים לחפוף עד 1 שנייה. לכל מקטע יש גם text ו-language (קוד שפה, שיכול להיות ריק), וכן channel עבור תוצאות עם שני ערוצים. |
channelCount | 1 או 2. מופיע בתוצאות הנוכחיות; תוצאות ישנות עשויות לא לכלול אותו. |
audioDurationMs | משך השמע המפוענח במילישניות. החיוב מעגל אותו כלפי מעלה לשניות שלמות. |
qualityFlags | ריק, או review_recommended יחד עם repetition_detected (ביטוי חוזר בתדירות חריגה בתוך חלק מהשמע), no_speech (לא תומלל דיבור), או שניהם. |
pipelineVersion | עשוי להופיע. מזהה עיבוד אטום. |
התמלולים וחותמות הזמן, תוויות השפה ותוויות הערוצים שלהם נוצרים אוטומטית, ודיוקם אינו מובטח. התייחסו לכל דגל איכות כסיבה לבדוק את התוצאה, והשוו שמות, מספרים והתחייבויות חשובים לשמע המקורי. דילוג מתבצע על שתיקות ארוכות ועל קטעים חלשים מאוד, ולכן לא נוצרים עבורם מקטעים. התוצאות אינן מזהות דוברים בודדים. כאשר תוצאה מדווחת על channelCount בערך 2, לכל מקטע יש channel בערך A (הערוץ הראשון, או השמאלי) או B (הערוץ השני, או הימני). הדבר מפריד בין דוברים רק אם כל דובר הוקלט בערוץ נפרד. שמע בשני ערוצים מחויב פעם אחת לפי משכו, ולא לכל ערוץ. בתוצאות מונו אין תוויות ערוצים.
שימוש ב-api.multitel.net
נקודת הקצה לתאימות POST https://api.multitel.net/v3/speech_to_text מקבלת multipart/form-data עם חלק קובץ בשם audio ושדה אופציונלי בשם language, במקום JSON עם audioBase64. ערך ריק של language נחשב כהיעדר רמז. שלחו את אותה כותרת Idempotency-Key. אם הכותרת חסרה, שרת זה מקבל גם שדה טופס בשם idempotency_key. שדות בשם source, free, billing_source, realtime או stream נדחים עם 400 unsupported_transcription_option; שדות טופס אחרים אינם נלקחים בחשבון. שרת זה מחזיר גם את השגיאות הבאות:
- 400
idempotency_key_requiredעבור מפתח חסר או ארוך מדי. - 400
audio_upload_requiredעבור העלאה חסרה או העלאה שלא התקבלה במלואה. - 400
invalid_languageעבור שפה לא תקינה. - 413
invalid_audio_sizeעבור קובץ ריק או גדול מדי. - 400
invalid_jobעבור מזהה משימה במבנה לא תקין.
תגובות משירות המרת הדיבור לטקסט של שרת זה משתמשות במעטפת {"status":{"code":HTTP_STATUS},"response":{...}}. שימו לב כי status הוא אובייקט, לא מחרוזת. במקרה הצלחה, response מכיל את אותו אובייקט כמו data בשרת הראשי, כך שמזהה המשימה הוא response.id. במקרה שגיאה, response.code מכיל את קוד השגיאה; לא נכללת הודעה או מזהה בקשה. כשלי אימות (401) מוחזרים מבדיקת ההתחברות הכללית של השרת ועשוי להיות להם גוף שונה, לכן בדקו את קוד מצב ה-HTTP לפני הניתוח. אל תחליפו את קידוד ההעלאה או את מנתח התגובות בין השרתים.
לקבלת הערכה בשרת זה, שלחו ב-POST את אותם שדות multipart אל /v3/speech_to_text/estimate. אין צורך במפתח אידמפוטנטיות, וההערכה נמצאת תחת response.
API_USER="your-api-username"
API_PASSWORD="your-api-password"
curl --fail-with-body --silent --show-error --user "$API_USER:$API_PASSWORD" \
-H "Idempotency-Key: speech-call-001" \
-F "audio=@completed-call.mp3" -F "language=en" \
-o speech-job.json \
https://api.multitel.net/v3/speech_to_text
node -p 'JSON.parse(require("node:fs").readFileSync("speech-job.json","utf8")).response.id'