Цей API транскрибує завершені аудіофайли як завдання в черзі. Надішліть файл, збережіть повернений ID завдання й запитуйте завдання, доки обробку не буде завершено. Надсилайте всі запити через 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 із повним об’єктом завдання, описаним у розділі Отримання транскрипції. Прочитайте ID завдання, 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, якщо ID завдання має неправильний формат.
Відповіді сервісу транскрибування мовлення на цьому сервері використовують обгортку {"status":{"code":HTTP_STATUS},"response":{...}}. Зверніть увагу: status є об’єктом, а не рядком. У разі успіху response містить той самий об’єкт, що й data на основному сервері, тому ID завдання — response.id. У разі помилки response.code містить код помилки; повідомлення та ID запиту не додаються. Помилки автентифікації (401) повертає загальна перевірка входу сервера, і вони можуть мати інше тіло, тому перевіряйте статус HTTP перед розбором. Не використовуйте кодування завантаження чи парсер відповіді одного сервера для іншого.
Щоб отримати оцінку на цьому сервері, надішліть ті самі multipart-поля методом POST на /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'