API này chép lời các tệp âm thanh hoàn chỉnh bằng tác vụ trong hàng đợi. Gửi tệp, lưu ID tác vụ được trả về và truy vấn tác vụ cho đến khi xử lý xong. Gửi mọi yêu cầu qua HTTPS bằng thông tin xác thực của tài khoản: thông tin HTTP Basic như trong ví dụ hoặc mã thông báo API, theo hướng dẫn tại Xác thực. Giữ thông tin xác thực trên máy chủ của bạn.
Điểm cuối
Hai máy chủ API, https://api.multi.tel và máy chủ tương thích https://api.multitel.net, dùng chung tác vụ, khóa lũy đẳng, giới hạn và tính phí trong phạm vi tài khoản. Chúng khác nhau về mã hóa tải lên và cấu trúc bao ngoài của phản hồi, vì vậy hãy dùng nhất quán một máy chủ với bộ phân tích phù hợp.
| Thao tác | Phương thức và đường dẫn |
|---|---|
| Thông tin dịch vụ | GET /v3/speech_to_text |
| Gửi tác vụ | POST /v3/speech_to_text |
| Ước tính mà không tạo tác vụ | POST /v3/speech_to_text/estimate |
| Đọc tác vụ | GET /v3/speech_to_text/JOB_ID |
| Thanh toán tác vụ đang chờ trả phí | POST /v3/speech_to_text/JOB_ID/settle |
| Mức sử dụng | GET /v3/speech_to_text/usage |
Trên api.multi.tel, mọi đường dẫn cũng có thể dùng tiền tố /v1/speech-to-text thay cho /v3/speech_to_text, ví dụ POST /v1/speech-to-text/estimate. Trên api.multitel.net, hãy dùng các đường dẫn /v3/speech_to_text.
Phản hồi thông tin dịch vụ cung cấp mode (batch), realtime (false), paidEnabled (hiện có chấp nhận lượt gửi trả phí mới hay không), pricePerMinuteUsd (0.005), billingUnit (audio_second), maxAudioSeconds (7200) và maxUploadBytes (26214400), cùng với một description ngắn. Việc đọc là miễn phí và vẫn hoạt động khi lượt gửi trả phí bị tắt; chỉ trả về 503 transcription_unavailable khi toàn bộ dịch vụ không khả dụng.
Chuẩn bị tệp âm thanh
Dùng tệp âm thanh hoàn chỉnh có kích thước tối đa 25 MiB (26,214,400 byte) và thời lượng tối đa 2 giờ (7,200 giây). Khi gửi, tệp phải được nhận diện là nội dung MP3, WAV, Ogg, FLAC, MOV hoặc Matroska chứa luồng âm thanh, với thời lượng trong siêu dữ liệu lớn hơn không và không quá 7,200 giây. Tệp được nhận diện nhưng không đạt các bước kiểm tra này bị từ chối với 422 unsupported_audio. Hiện tại, tệp không đọc được theo bất kỳ định dạng nào kể trên có thể bị từ chối bằng lỗi máy chủ (500); đừng gửi lại tệp đó khi chưa thay đổi. Chỉ phần mở rộng của tệp không đủ để xác định tính tương thích.
Vượt qua các bước kiểm tra không bảo đảm âm thanh có thể được giải mã. Âm thanh được xử lý ở dạng một hoặc hai kênh. Tệp có hơn hai kênh âm thanh, tệp có thời lượng sau giải mã dài hơn 2 giờ hoặc tệp khác không giải mã được trong quá trình xử lý sẽ kết thúc dưới dạng tác vụ failed, thường có mã decode_failed, và không bị tính phí. Chuyển âm thanh đa kênh thành mono hoặc stereo trước khi gửi.
Gợi ý ngôn ngữ không bắt buộc là mã gồm hai hoặc ba chữ cái viết thường của ngôn ngữ được nói, chẳng hạn en. Để không đưa ra gợi ý, hãy bỏ trường này; api.multi.tel từ chối chuỗi rỗng. Gợi ý định hướng xử lý nhưng không được đối chiếu với danh sách ngôn ngữ hỗ trợ, vì vậy hãy dùng mã hợp lệ cho ngôn ngữ được nói.
Gửi tác vụ chép lời
Gửi JSON với Content-Type: application/json đến POST https://api.multi.tel/v3/speech_to_text. Nội dung yêu cầu có thể tối đa 35 MiB, đủ chứa tệp kích thước tối đa sau mã hóa base64; nội dung lớn hơn bị từ chối với 413.
| Trường | Ý nghĩa |
|---|---|
audioBase64 | Bắt buộc. Toàn bộ tệp ở dạng base64 chuẩn (A–Z, a–z, 0–9, +, /), dùng ký tự đệm = khi cần. Không thêm tiền tố data-URL, dấu xuống dòng hoặc khoảng trắng, và không dùng bảng ký tự an toàn cho URL. Giá trị sau giải mã phải từ 1 byte đến 25 MiB và khi mã hóa lại phải cho ra đúng văn bản ban đầu. |
language | Gợi ý ngôn ngữ không bắt buộc, như mô tả ở trên. |
Mọi thuộc tính JSON khác, kể cả idempotency_key, đều bị từ chối với 400 invalid_transcription_request. Gửi khóa dưới dạng tiêu đề HTTP.
Khóa lũy đẳng
Mỗi lần gửi đều cần tiêu đề Idempotency-Key dài từ 1 đến 190 ký tự. Dùng chữ cái ASCII, chữ số, -, _, . và :, không có khoảng trắng đầu hoặc cuối: máy chủ tương thích loại bỏ khoảng trắng xung quanh và đo khóa theo byte, nên các ký tự khác có thể được đếm khác nhau trên từng máy chủ. Thiếu khóa hoặc khóa dài từ 191 ký tự trở lên bị từ chối với 400.
Khóa có phạm vi là tài khoản của bạn và dịch vụ chuyển giọng nói thành văn bản, trên cả hai máy chủ và mọi thông tin xác thực của tài khoản. Gửi lại cùng khóa với cùng tệp và ngôn ngữ sẽ trả về tác vụ hiện có với HTTP 200 và duplicate: true, bất kể trạng thái tác vụ, kể cả khi cơ chế xử lý đã được cập nhật sau lúc tạo tác vụ, mà không tính phí lần nữa. Dùng lại khóa với tệp hoặc ngôn ngữ khác trả về 409 idempotency_conflict. Khóa mới tạo tác vụ mới ngay cả với tệp giống hệt, và tính phí riêng nếu xử lý hoàn tất thành công.
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'Tác vụ mới trả về HTTP 202 với các trường bên dưới; gửi lại cùng yêu cầu trả về HTTP 200 với toàn bộ đối tượng tác vụ được mô tả trong Đọc bản chép lời. Đọc ID tác vụ, là một UUID, từ data.id. Phản hồi của tác vụ mới có dạng sau (mã định danh và giá trị chỉ là ví dụ):
{
"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"
}
}Khi tác vụ đang trong hàng đợi hoặc đang chạy, durationSeconds, billedSeconds và costUsd là các ước tính từ siêu dữ liệu của tệp. Phí cuối cùng dùng thời lượng sau giải mã.
Lần gửi cũng có thể trả về 402 insufficient_balance khi số dư trả trước không đủ chi trả tác vụ cùng các tác vụ chưa thanh toán khác, 429 transcription_queue_full khi tài khoản hoặc dịch vụ có quá nhiều tác vụ chưa hoàn tất, 429 audio_validation_busy khi công suất kiểm tra tệp đã đầy và 503 paid_transcription_not_enabled khi chép lời trả phí bị tắt. Thử lại các phản hồi 429 và 503 sau bằng cùng khóa.
Ước tính mà không tạo tác vụ
Gửi cùng nội dung JSON đến POST https://api.multi.tel/v3/speech_to_text/estimate. Không cần khóa lũy đẳng. Ước tính kiểm tra và đo tệp nhưng không chép lời, tạo tác vụ, giữ tiền, kiểm tra số dư hoặc tính phí tài khoản. Gợi ý language được chấp nhận nhưng không ảnh hưởng đến ước tính.
Ước tính thành công trả về HTTP 200 với estimate: true, charged: false, mode, realtime, durationSeconds, billedSeconds, pricePerMinuteUsd và costUsd nằm trong data. Ước tính dùng thời lượng trong siêu dữ liệu của tệp, trong khi tác vụ hoàn tất được tính phí theo thời lượng sau giải mã, nên hai giá trị có thể khác nhau. Ước tính áp dụng cùng bước kiểm tra tệp như khi gửi. Chỉ dùng được khi chép lời trả phí được bật (nếu không sẽ trả về 503 paid_transcription_not_enabled). Có thể trả về 429 audio_validation_busy khi công suất kiểm tra tệp đã đầy; đợi một chút rồi thử lại.
Đọc bản chép lời
Thăm dò GET /v3/speech_to_text/JOB_ID theo mô tả trong hướng dẫn quy trình tác vụ. Đối tượng tác vụ chứa các trường sau:
| Trường | Ý nghĩa |
|---|---|
id | UUID của tác vụ. |
status | queued, running, completed, failed hoặc awaiting_payment. |
progress | Phần trăm từ 0 đến 99 khi đang chạy, nếu có; 100 khi hoàn tất; nếu không là null. |
durationSeconds, billedSeconds | Thời lượng âm thanh và số giây nguyên được tính phí. Đây là ước tính từ siêu dữ liệu khi tác vụ đang chờ hoặc đang chạy; dùng thời lượng sau giải mã khi đã hoàn tất hoặc đang chờ thanh toán. |
costUsd, costIsEstimate | Chi phí bằng đô la Mỹ, dưới dạng chuỗi thập phân có chín chữ số sau dấu thập phân. costIsEstimate là true khi tác vụ đang chờ hoặc đang chạy. Tác vụ thất bại không bị tính phí, dù costUsd vẫn hiển thị ước tính. |
pricePerMinuteUsd | 0.005 cho tác vụ API và 0.000 cho tác vụ ghi âm Hosted PBX miễn phí. |
failureCode | Với tác vụ thất bại: decode_failed (không giải mã được âm thanh, chẳng hạn do có hơn hai kênh hoặc dài hơn 2 giờ sau giải mã), inference_timeout (xử lý quá lâu), service_error hoặc worker_lease_lost (xử lý bị gián đoạn). Các mã unsupported_audio và quality_check_failed cũng được định nghĩa. Tác vụ chờ thanh toán hiển thị insufficient_balance, mã này có thể vẫn còn sau khi thanh toán. |
source, modelVersion, createdAt | source là api với lượt gửi API, hoặc hpbx với tác vụ ghi âm Hosted PBX của tài khoản. modelVersion là chuỗi phiên bản xử lý nội bộ, không dùng để diễn giải. createdAt là thời điểm gửi. |
duplicate | true trên phản hồi trả về tác vụ hiện có. |
result | Chỉ có khi status là completed. |
| Trường kết quả | Ý nghĩa |
|---|---|
text | Toàn bộ bản chép lời: văn bản của mọi đoạn được nối bằng dấu xuống dòng, theo thứ tự đoạn. |
segments | Mảng các đoạn theo thứ tự thời gian bắt đầu. Mỗi đoạn bao phủ một phần âm thanh dài tối đa khoảng 29 giây. start và end của đoạn (số giây tính từ đầu âm thanh) đánh dấu phần đó, không phải từng từ hay câu; các phần liên tiếp có thể chồng lấn tối đa 1 giây. Mỗi đoạn cũng có text và language (mã ngôn ngữ, có thể rỗng), cùng channel cho kết quả hai kênh. |
channelCount | 1 hoặc 2. Có trong kết quả hiện tại; kết quả cũ có thể bỏ qua. |
audioDurationMs | Thời lượng sau giải mã tính bằng mili giây. Khi tính phí, giá trị được làm tròn lên số giây nguyên. |
qualityFlags | Rỗng, hoặc review_recommended cùng với repetition_detected (một cụm từ lặp lại thường xuyên bất thường trong một phần), no_speech (không có lời nói nào được chép lại), hoặc cả hai. |
pipelineVersion | Có thể xuất hiện. Mã định danh xử lý nội bộ, không dùng để diễn giải. |
Bản chép lời, dấu thời gian, nhãn ngôn ngữ và nhãn kênh được tạo tự động và không được bảo đảm chính xác. Hãy coi mọi cờ chất lượng là lý do để rà soát kết quả và đối chiếu tên, số liệu, cam kết quan trọng với âm thanh gốc. Khoảng im lặng dài và phần có âm lượng rất nhỏ được bỏ qua, không tạo đoạn. Kết quả không nhận diện từng người nói. Khi kết quả báo channelCount là 2, mỗi đoạn có channel là A (kênh đầu tiên, hay kênh trái) hoặc B (kênh thứ hai, hay kênh phải). Cách này chỉ tách người nói khi mỗi người được ghi trên một kênh riêng. Âm thanh hai kênh được tính phí một lần theo thời lượng trôi qua, không tính theo từng kênh. Kết quả mono không có nhãn kênh.
Dùng api.multitel.net
Điểm cuối tương thích POST https://api.multitel.net/v3/speech_to_text chấp nhận multipart/form-data với phần tệp audio và trường language không bắt buộc, thay vì JSON audioBase64. Giá trị language rỗng được coi là không có gợi ý. Gửi cùng tiêu đề Idempotency-Key. Nếu không có tiêu đề, máy chủ này cũng chấp nhận trường biểu mẫu idempotency_key. Các trường có tên source, free, billing_source, realtime hoặc stream bị từ chối với 400 unsupported_transcription_option; các trường biểu mẫu khác bị bỏ qua. Máy chủ này cũng trả về các lỗi sau:
- 400
idempotency_key_requiredkhi thiếu khóa hoặc khóa quá dài. - 400
audio_upload_requiredkhi thiếu tệp tải lên hoặc chưa nhận đủ tệp. - 400
invalid_languagekhi ngôn ngữ không hợp lệ. - 413
invalid_audio_sizekhi tệp rỗng hoặc quá lớn. - 400
invalid_jobkhi ID tác vụ sai định dạng.
Phản hồi từ dịch vụ chuyển giọng nói thành văn bản của máy chủ này dùng cấu trúc bao ngoài {"status":{"code":HTTP_STATUS},"response":{...}}. Lưu ý status là đối tượng, không phải chuỗi. Khi thành công, response chứa cùng đối tượng như data trên máy chủ chính, nên ID tác vụ là response.id. Khi có lỗi, response.code chứa mã lỗi; không có thông điệp hoặc ID yêu cầu. Lỗi xác thực (401) do bước kiểm tra đăng nhập chung của máy chủ trả về và có thể có nội dung khác, vì vậy hãy kiểm tra trạng thái HTTP trước khi phân tích. Không dùng lẫn mã hóa tải lên hoặc bộ phân tích phản hồi giữa các máy chủ.
Để ước tính trên máy chủ này, POST cùng các trường multipart đến /v3/speech_to_text/estimate. Không cần khóa lũy đẳng, và ước tính nằm trong 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'