Programiści

API transkrypcji mowy

Transkrybuj gotowe pliki audio za pomocą zadań w kolejce, z bezpłatną wyceną, idempotentnym przesyłaniem i śledzeniem wykorzystania na obu serwerach API.

Na tej stronie
  1. Punkty końcowe
  2. Przygotowanie pliku audio
  3. Przesłanie zadania transkrypcji
  4. Klucz idempotencji
  5. Wycena bez tworzenia zadania
  6. Odczyt transkrypcji
  7. Korzystanie z api.multitel.net

Ten interfejs API transkrybuje gotowe pliki audio jako zadania w kolejce. Prześlij plik, zachowaj zwrócony identyfikator zadania i pobieraj zadanie do zakończenia przetwarzania. Każde żądanie wysyłaj przez HTTPS z danymi uwierzytelniającymi swojego konta: danymi HTTP Basic jak w przykładach lub tokenem API, zgodnie z opisem w sekcji Uwierzytelnianie. Przechowuj dane uwierzytelniające na swoim serwerze.

Punkty końcowe

Dwa serwery API, https://api.multi.tel i serwer zgodności https://api.multitel.net, współdzielą te same zadania, klucze idempotencji, limity i rozliczenia w obrębie konta. Różnią się kodowaniem przesyłanych danych i zewnętrzną strukturą odpowiedzi, dlatego konsekwentnie używaj jednego serwera z odpowiednim parserem.

OperacjaMetoda i ścieżka
Informacje o usłudzeGET /v3/speech_to_text
Przesłanie zadaniaPOST /v3/speech_to_text
Wycena bez tworzenia zadaniaPOST /v3/speech_to_text/estimate
Odczyt zadaniaGET /v3/speech_to_text/JOB_ID
Rozliczenie zadania oczekującego na płatnośćPOST /v3/speech_to_text/JOB_ID/settle
WykorzystanieGET /v3/speech_to_text/usage

Na api.multi.tel każda ścieżka jest również dostępna z prefiksem /v1/speech-to-text zamiast /v3/speech_to_text, na przykład POST /v1/speech-to-text/estimate. Na api.multitel.net używaj ścieżek /v3/speech_to_text.

Odpowiedź z informacjami o usłudze zawiera mode (batch), realtime (false), paidEnabled (czy obecnie przyjmowane są nowe płatne zgłoszenia), pricePerMinuteUsd (0.005), billingUnit (audio_second), maxAudioSeconds (7200) i maxUploadBytes (26214400) oraz krótki opis description. Odczyt jest bezpłatny i działa także przy wyłączonych płatnych zgłoszeniach; zwraca 503 z kodem transcription_unavailable tylko wtedy, gdy cała usługa jest niedostępna.

Przygotowanie pliku audio

Użyj gotowego pliku audio o rozmiarze nie większym niż 25 MiB (26,214,400 bajtów) i długości nie większej niż 2 godziny (7,200 sekund). Podczas przesyłania plik musi zostać rozpoznany jako materiał MP3, WAV, Ogg, FLAC, MOV lub Matroska zawierający strumień audio, o czasie trwania w metadanych większym od zera i nieprzekraczającym 7,200 sekund. Rozpoznany plik, który nie przejdzie tych kontroli, jest odrzucany z kodem 422 unsupported_audio. Plik, którego nie można odczytać w żadnym z tych formatów, może obecnie zostać odrzucony zamiast tego z błędem serwera (500); nie przesyłaj go ponownie bez zmian. Samo rozszerzenie pliku nie potwierdza zgodności.

Przejście tych kontroli nie gwarantuje, że audio da się zdekodować. Audio jest przetwarzane jako jeden lub dwa kanały. Plik zawierający więcej niż dwa kanały audio, plik, którego zdekodowane audio trwa ponad 2 godziny, lub dowolny inny plik, którego dekodowanie zakończy się błędem podczas przetwarzania, kończy jako zadanie ze statusem failed, zwykle z kodem decode_failed, i nie jest naliczana za niego opłata. Przed przesłaniem przekonwertuj audio wielokanałowe na mono lub stereo.

Opcjonalna wskazówka językowa to dwu- lub trzyliterowy kod języka wypowiedzi zapisany małymi literami, na przykład en. Jeśli nie chcesz podawać wskazówki, pomiń pole; api.multi.tel odrzuca pusty ciąg znaków. Wskazówka ukierunkowuje przetwarzanie, ale nie jest sprawdzana względem listy obsługiwanych języków, dlatego użyj poprawnego kodu języka wypowiedzi.

Przesłanie zadania transkrypcji

Wyślij JSON z nagłówkiem Content-Type: application/json do POST https://api.multi.tel/v3/speech_to_text. Treść żądania może mieć do 35 MiB, co mieści plik o maksymalnym rozmiarze po zakodowaniu w base64; większa treść jest odrzucana z kodem 413.

PoleZnaczenie
audioBase64Wymagane. Cały plik w standardowym base64 (A–Z, a–z, 0–9, +, /) z dopełnieniem = w razie potrzeby. Nie dodawaj prefiksu data URL, znaków nowego wiersza ani spacji i nie używaj alfabetu URL-safe. Po zdekodowaniu wartość musi mieć od 1 bajta do 25 MiB, a ponowne zakodowanie musi dać dokładnie ten sam tekst.
languageOpcjonalna wskazówka językowa opisana powyżej.

Każda inna właściwość JSON, w tym idempotency_key, jest odrzucana z kodem 400 invalid_transcription_request. Wyślij klucz jako nagłówek.

Klucz idempotencji

Każde zgłoszenie wymaga nagłówka Idempotency-Key o długości od 1 do 190 znaków. Używaj liter ASCII, cyfr, -, _, . i : bez spacji na początku i końcu: serwer zgodności usuwa otaczające białe znaki i mierzy klucz w bajtach, więc inne znaki mogą być liczone inaczej przez każdy serwer. Brak klucza lub klucz o długości 191 znaków lub większej powoduje odrzucenie z kodem 400.

Klucze są przypisane do Twojego konta i usługi transkrypcji, wspólnie dla obu serwerów i wszystkich danych uwierzytelniających konta. Ponowne przesłanie tego samego klucza z tym samym plikiem i językiem zwraca istniejące zadanie z HTTP 200 i duplicate: true, niezależnie od jego statusu, nawet jeśli przetwarzanie zostało zaktualizowane od utworzenia zadania, bez kolejnej opłaty. Ponowne użycie klucza z innym plikiem lub językiem zwraca 409 idempotency_conflict. Nowy klucz tworzy nowe zadanie nawet dla identycznego pliku, z osobną opłatą po pomyślnym zakończeniu przetwarzania.

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'

Nowe zadanie zwraca HTTP 202 z polami pokazanymi poniżej, a powtórzenie żądania zwraca HTTP 200 z pełnym obiektem zadania opisanym w sekcji Odczyt transkrypcji. Odczytaj identyfikator zadania, UUID, z pola data.id. Odpowiedź nowego zadania wygląda tak (identyfikator i wartości są przykładowe):

{
  "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"
  }
}

Gdy zadanie jest w kolejce lub w trakcie przetwarzania, pola durationSeconds, billedSeconds i costUsd są szacunkami z metadanych pliku. Ostateczna opłata opiera się na zdekodowanej długości.

Zgłoszenie może również zwrócić 402 insufficient_balance, gdy saldo przedpłacone nie pokrywa zadania wraz z innymi zadaniami w toku, 429 transcription_queue_full, gdy konto lub usługa mają zbyt wiele zadań w toku, 429 audio_validation_busy, gdy walidacja plików osiągnęła limit wydajności, oraz 503 paid_transcription_not_enabled, gdy płatna transkrypcja jest wyłączona. Po odpowiedziach 429 i 503 ponów próbę później z tym samym kluczem.

Wycena bez tworzenia zadania

Wyślij tę samą treść JSON do POST https://api.multi.tel/v3/speech_to_text/estimate. Klucz idempotencji nie jest wymagany. Wycena weryfikuje i mierzy plik, ale nie transkrybuje go, nie tworzy zadania, nie rezerwuje środków, nie sprawdza salda i nie obciąża konta. Wskazówka w polu language jest przyjmowana, ale nie wpływa na wycenę.

Pomyślna wycena zwraca HTTP 200 z polami estimate: true, charged: false, mode, realtime, durationSeconds, billedSeconds, pricePerMinuteUsd i costUsd w data. Używa długości z metadanych pliku, podczas gdy ukończone zadanie jest rozliczane według zdekodowanej długości, która może być inna. Wyceny przeprowadzają te same kontrole plików co zgłoszenia. Są dostępne tylko przy włączonej płatnej transkrypcji (w przeciwnym razie 503 paid_transcription_not_enabled). Mogą zwrócić 429 audio_validation_busy, gdy walidacja plików osiągnęła limit wydajności; spróbuj ponownie po krótkim oczekiwaniu.

Odczyt transkrypcji

Odpytuj okresowo GET /v3/speech_to_text/JOB_ID zgodnie z opisem w przewodniku po obsłudze zadań. Obiekt zadania zawiera następujące pola:

PoleZnaczenie
idUUID zadania.
statusqueued, running, completed, failed lub awaiting_payment.
progressProcent od 0 do 99 podczas przetwarzania, jeśli jest dostępny; 100 po ukończeniu; w pozostałych przypadkach null.
durationSeconds, billedSecondsDługość audio i rozliczane pełne sekundy. Są to szacunki z metadanych, gdy zadanie jest w kolejce lub w trakcie przetwarzania. Po ukończeniu lub podczas oczekiwania na płatność używana jest długość zdekodowana.
costUsd, costIsEstimateKoszt w dolarach amerykańskich zapisany jako ciąg znaków z dziewięcioma miejscami po przecinku. costIsEstimate ma wartość true, gdy zadanie jest w kolejce lub w trakcie przetwarzania. Zadanie zakończone błędem nie jest płatne, mimo że jego costUsd nadal pokazuje szacunkowy koszt.
pricePerMinuteUsd0.005 dla zadań API i 0.000 dla bezpłatnych zadań nagrań Hosted PBX.
failureCodeDla zadania zakończonego błędem: decode_failed (nie udało się zdekodować audio, na przykład ma ono więcej niż dwa kanały lub po dekodowaniu trwa ponad 2 godziny), inference_timeout (przetwarzanie trwało zbyt długo), service_error lub worker_lease_lost (przetwarzanie zostało przerwane). Zdefiniowane są także kody unsupported_audio i quality_check_failed. Zadanie oczekujące na płatność pokazuje insufficient_balance, co może pozostać również po rozliczeniu zadania.
source, modelVersion, createdAtsource ma wartość api dla zgłoszeń API lub hpbx dla zadania nagrania Hosted PBX z Twojego konta. modelVersion to nieprzezroczysty ciąg identyfikujący wersję przetwarzania. createdAt to czas przesłania zadania.
duplicatetrue w odpowiedziach zwracających istniejące zadanie.
resultObecne tylko wtedy, gdy status ma wartość completed.
Pole wynikuZnaczenie
textPełna transkrypcja: teksty wszystkich segmentów połączone znakami nowego wiersza, w kolejności segmentów.
segmentsTablica segmentów uporządkowanych według czasu rozpoczęcia. Każdy segment obejmuje fragment audio o długości do około 29 sekund. Jego pola start i end (sekundy od początku audio) wyznaczają ten fragment, a nie poszczególne słowa lub zdania. Kolejne fragmenty mogą nakładać się na siebie do 1 sekundy. Każdy segment ma także text i language (kod języka, który może być pusty) oraz channel w wynikach dwukanałowych.
channelCount1 lub 2. Obecne w aktualnych wynikach; starsze mogą pomijać to pole.
audioDurationMsZdekodowana długość w milisekundach. Na potrzeby rozliczenia jest zaokrąglana w górę do pełnych sekund.
qualityFlagsPuste lub review_recommended wraz z repetition_detected (wyrażenie powtarza się nietypowo często w jednym fragmencie), no_speech (nie przetranskrybowano żadnej mowy) lub oboma.
pipelineVersionMoże się pojawić. Nieprzezroczysty identyfikator przetwarzania.

Transkrypcje oraz ich znaczniki czasu, etykiety języków i kanałów powstają automatycznie i nie ma gwarancji ich poprawności. Każda flaga jakości powinna skłonić do sprawdzenia wyniku; porównaj ważne nazwiska i nazwy, liczby oraz zobowiązania z oryginalnym audio. Długie fragmenty ciszy i bardzo ciche fragmenty są pomijane i nie tworzą segmentów. Wyniki nie identyfikują poszczególnych mówców. Gdy wynik podaje channelCount o wartości 2, każdy segment ma channel o wartości A (pierwszy, czyli lewy kanał) lub B (drugi, czyli prawy kanał). Rozdziela to mówców tylko wtedy, gdy każdy był nagrany na osobnym kanale. Audio dwukanałowe jest rozliczane raz według czasu trwania, nie za każdy kanał. Wyniki mono nie mają etykiet kanałów.

Korzystanie z api.multitel.net

Punkt końcowy zgodności POST https://api.multitel.net/v3/speech_to_text przyjmuje multipart/form-data z częścią plikową audio i opcjonalnym polem language, zamiast pola JSON audioBase64. Pusta wartość language jest traktowana jako brak wskazówki. Wyślij ten sam nagłówek Idempotency-Key. Jeśli nagłówka nie ma, ten serwer przyjmuje również pole formularza idempotency_key. Pola o nazwach source, free, billing_source, realtime lub stream są odrzucane z kodem 400 unsupported_transcription_option; pozostałe pola formularza są ignorowane. Ten serwer zwraca również te błędy:

  • 400 idempotency_key_required przy braku klucza lub zbyt długim kluczu.
  • 400 audio_upload_required przy braku przesłanego pliku lub niepełnym odbiorze.
  • 400 invalid_language dla nieprawidłowego języka.
  • 413 invalid_audio_size dla pustego lub zbyt dużego pliku.
  • 400 invalid_job dla identyfikatora zadania o nieprawidłowym formacie.

Odpowiedzi usługi transkrypcji na tym serwerze używają zewnętrznej struktury {"status":{"code":HTTP_STATUS},"response":{...}}. Zwróć uwagę, że status jest obiektem, a nie ciągiem znaków. Przy powodzeniu response zawiera ten sam obiekt co data na serwerze głównym, więc identyfikator zadania to response.id. Przy błędzie response.code zawiera kod błędu; nie ma komunikatu ani identyfikatora żądania. Błędy uwierzytelniania (401) zwraca ogólna kontrola logowania serwera i mogą mieć inną treść odpowiedzi, dlatego przed parsowaniem sprawdź status HTTP. Nie zamieniaj między serwerami kodowania przesyłanych danych ani parsera odpowiedzi.

Aby uzyskać wycenę na tym serwerze, wyślij metodą POST te same pola multipart do /v3/speech_to_text/estimate. Klucz idempotencji nie jest wymagany, a wycena jest w 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'