Sviluppatori

API di trascrizione audio

Trascrivi file audio completi con attività in coda, stime gratuite, invii idempotenti e monitoraggio dell’utilizzo su entrambi i server API.

Su questa pagina
  1. Endpoint
  2. Preparare un file audio
  3. Inviare un’attività di trascrizione
  4. Chiave di idempotenza
  5. Ottenere una stima senza creare un’attività
  6. Leggere la trascrizione
  7. Usare api.multitel.net

Questa API trascrive file audio completi tramite attività in coda. Invia un file, conserva l’ID dell’attività restituito e consulta l’attività finché l’elaborazione non è terminata. Invia ogni richiesta tramite HTTPS con le credenziali del tuo account: credenziali HTTP Basic come negli esempi oppure un token API, come descritto in Autenticazione. Conserva le credenziali sul tuo server.

Endpoint

I due server API, https://api.multi.tel e il server di compatibilità https://api.multitel.net, condividono attività, chiavi di idempotenza, limiti e fatturazione nell’ambito dello stesso account. Differiscono per codifica dei caricamenti e struttura esterna delle risposte: usa quindi sempre lo stesso server con un parser corrispondente.

OperazioneMetodo e percorso
Informazioni sul servizioGET /v3/speech_to_text
Inviare un’attivitàPOST /v3/speech_to_text
Ottenere una stima senza creare un’attivitàPOST /v3/speech_to_text/estimate
Consultare un’attivitàGET /v3/speech_to_text/JOB_ID
Saldare un’attività in attesa di pagamentoPOST /v3/speech_to_text/JOB_ID/settle
UtilizzoGET /v3/speech_to_text/usage

Su api.multi.tel, ogni percorso è disponibile anche con il prefisso /v1/speech-to-text al posto di /v3/speech_to_text, ad esempio POST /v1/speech-to-text/estimate. Su api.multitel.net, usa i percorsi /v3/speech_to_text.

La risposta con le informazioni sul servizio riporta mode (batch), realtime (false), paidEnabled (se al momento sono accettati nuovi invii a pagamento), pricePerMinuteUsd (0.005), billingUnit (audio_second), maxAudioSeconds (7200) e maxUploadBytes (26214400), insieme a una breve description. Consultarla è gratuito ed è possibile anche quando gli invii a pagamento sono disabilitati; restituisce 503 transcription_unavailable solo quando l’intero servizio non è disponibile.

Preparare un file audio

Usa un file audio completo di massimo 25 MiB (26,214,400 byte) e massimo 2 ore (7,200 secondi). Al momento dell’invio, il file deve essere riconosciuto come un contenuto multimediale MP3, WAV, Ogg, FLAC, MOV o Matroska con un flusso audio e una durata nei metadati maggiore di zero e non superiore a 7,200 secondi. Un file riconosciuto che non supera questi controlli viene rifiutato con 422 unsupported_audio. Un file che non può essere letto in nessuno di questi formati può attualmente essere rifiutato con un errore del server (500); non inviare nuovamente un file del genere senza modificarlo. La sola estensione non dimostra la compatibilità del file.

Il superamento di questi controlli non garantisce che l’audio sia decodificabile. L’audio viene elaborato su uno o due canali. Un file con più di due canali audio, con una durata decodificata superiore a 2 ore o con qualsiasi altro errore di decodifica durante l’elaborazione termina come attività failed, in genere con decode_failed, e non viene addebitato. Converti l’audio multicanale in mono o stereo prima dell’invio.

L’indicazione facoltativa della lingua è un codice di due o tre lettere minuscole per la lingua parlata, ad esempio en. Per non fornire alcuna indicazione, ometti il campo; api.multi.tel rifiuta una stringa vuota. L’indicazione orienta l’elaborazione, ma non viene verificata rispetto a un elenco di lingue supportate: usa quindi un codice valido per la lingua parlata.

Inviare un’attività di trascrizione

Invia JSON con Content-Type: application/json a POST https://api.multi.tel/v3/speech_to_text. Il corpo della richiesta può arrivare a 35 MiB, sufficienti per un file della dimensione massima dopo la codifica base64; un corpo più grande viene rifiutato con 413.

CampoSignificato
audioBase64Obbligatorio. Il file completo in base64 standard (A–Z, a–z, 0–9, +, /) con riempimento = quando necessario. Non aggiungere un prefisso data-URL, interruzioni di riga o spazi e non usare l’alfabeto sicuro per gli URL. La decodifica del valore deve produrre tra 1 byte e 25 MiB e la ricodifica deve restituire esattamente lo stesso testo.
languageIndicazione facoltativa della lingua, come descritto sopra.

Qualsiasi altra proprietà JSON, inclusa idempotency_key, viene rifiutata con 400 invalid_transcription_request. Invia la chiave come intestazione.

Chiave di idempotenza

Ogni invio richiede un’intestazione Idempotency-Key di lunghezza compresa tra 1 e 190 caratteri. Usa lettere ASCII, cifre, -, _, . e :, senza spazi iniziali o finali: il server di compatibilità rimuove gli spazi circostanti e misura la chiave in byte, quindi gli altri caratteri possono essere conteggiati diversamente dai due server. Una chiave assente o di almeno 191 caratteri viene rifiutata con 400.

Le chiavi sono limitate al tuo account e alla trascrizione, su entrambi i server e per tutte le credenziali dell’account. Reinviare la stessa chiave con lo stesso file e la stessa lingua restituisce l’attività esistente con HTTP 200 e duplicate: true, qualunque sia il suo stato e anche se l’elaborazione è stata aggiornata dopo la creazione, senza un nuovo addebito. Riutilizzare una chiave con un file o una lingua diversi restituisce 409 idempotency_conflict. Una nuova chiave crea una nuova attività anche per un file identico, con un addebito separato se l’elaborazione termina correttamente.

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'

Una nuova attività restituisce HTTP 202 con i campi riportati sotto; una ripetizione restituisce HTTP 200 con l’oggetto completo dell’attività descritto in Leggere la trascrizione. Leggi l’ID dell’attività, un UUID, da data.id. La risposta di una nuova attività ha questo aspetto (l’identificatore e i valori sono esempi):

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

Quando un’attività è in coda o in elaborazione, durationSeconds, billedSeconds e costUsd sono stime ricavate dai metadati del file. L’addebito finale usa la durata decodificata.

Un invio può anche restituire 402 insufficient_balance quando il saldo prepagato non copre l’attività insieme alle altre attività in sospeso, 429 transcription_queue_full quando l’account o il servizio hanno troppe attività in sospeso, 429 audio_validation_busy quando la validazione dei file è al limite della capacità e 503 paid_transcription_not_enabled quando la trascrizione a pagamento è disabilitata. In caso di risposta 429 o 503, riprova più tardi con la stessa chiave.

Ottenere una stima senza creare un’attività

Invia lo stesso corpo JSON a POST https://api.multi.tel/v3/speech_to_text/estimate. Non serve una chiave di idempotenza. Una stima valida e misura il file, ma non lo trascrive, non crea un’attività, non riserva fondi, non controlla il saldo e non comporta addebiti sul tuo account. Un’indicazione language è accettata, ma non influisce sulla stima.

Una stima riuscita restituisce HTTP 200 con estimate: true, charged: false, mode, realtime, durationSeconds, billedSeconds, pricePerMinuteUsd e costUsd in data. Usa la durata nei metadati del file, mentre un’attività completata viene addebitata in base alla durata decodificata, che può essere diversa. Le stime applicano gli stessi controlli sui file degli invii. Sono disponibili solo quando la trascrizione a pagamento è abilitata (altrimenti 503 paid_transcription_not_enabled). Possono restituire 429 audio_validation_busy quando la validazione dei file è al limite della capacità; riprova dopo una breve attesa.

Leggere la trascrizione

Interroga periodicamente GET /v3/speech_to_text/JOB_ID come descritto nella guida al flusso delle attività. L’oggetto dell’attività contiene questi campi:

CampoSignificato
idL’UUID dell’attività.
statusqueued, running, completed, failed o awaiting_payment.
progressUna percentuale da 0 a 99 durante l’elaborazione, se disponibile; 100 al completamento; altrimenti null.
durationSeconds, billedSecondsDurata dell’audio e secondi interi fatturati. Sono stime dei metadati quando l’attività è in coda o in elaborazione; una volta completata o in attesa di pagamento, usano la durata decodificata.
costUsd, costIsEstimateIl costo in dollari statunitensi, come stringa decimale con nove cifre decimali. costIsEstimate è true quando l’attività è in coda o in elaborazione. Un’attività non riuscita non viene addebitata, anche se il suo costUsd mostra ancora la stima.
pricePerMinuteUsd0.005 per le attività API e 0.000 per le attività gratuite relative alle registrazioni Hosted PBX.
failureCodePer un’attività non riuscita: decode_failed (l’audio non è stato decodificato, ad esempio perché ha più di due canali o dura più di 2 ore una volta decodificato), inference_timeout (l’elaborazione ha richiesto troppo tempo), service_error o worker_lease_lost (l’elaborazione è stata interrotta). Sono definiti anche i codici unsupported_audio e quality_check_failed. Un’attività in attesa di pagamento mostra insufficient_balance, che può rimanere dopo il saldo dell’attività.
source, modelVersion, createdAtsource è api per gli invii API oppure hpbx per un’attività relativa a una registrazione Hosted PBX del tuo account. modelVersion è una stringa opaca che indica la versione dell’elaborazione. createdAt è l’istante dell’invio.
duplicatetrue nelle risposte che restituiscono un’attività esistente.
resultPresente solo quando status è completed.
Campo del risultatoSignificato
textLa trascrizione completa: i testi di tutti i segmenti uniti da interruzioni di riga, nell’ordine dei segmenti.
segmentsUn array di segmenti ordinati per istante di inizio. Ogni segmento copre una sezione audio lunga al massimo circa 29 secondi. I suoi campi start e end (secondi dall’inizio dell’audio) delimitano quella sezione, non singole parole o frasi, e sezioni consecutive possono sovrapporsi fino a 1 secondo. Ogni segmento contiene anche text e language (un codice di lingua, che può essere vuoto), oltre a channel nei risultati a due canali.
channelCount1 o 2. Presente nei risultati attuali; quelli più vecchi possono ometterlo.
audioDurationMsLa durata decodificata in millisecondi. La fatturazione la arrotonda per eccesso a secondi interi.
qualityFlagsVuoto, oppure review_recommended insieme a repetition_detected (un’espressione si ripete insolitamente spesso in una sezione), no_speech (non è stato trascritto alcun parlato) o entrambi.
pipelineVersionPuò essere presente. Un identificatore opaco dell’elaborazione.

Le trascrizioni e i relativi timestamp, le etichette di lingua e di canale sono generati automaticamente e la loro accuratezza non è garantita. Considera ogni indicatore di qualità come un motivo per rivedere il risultato e confronta nomi, numeri e impegni importanti con l’audio originale. I silenzi lunghi e i passaggi molto deboli vengono saltati e non producono segmenti. I risultati non identificano i singoli interlocutori. Quando un risultato riporta un channelCount pari a 2, ogni segmento ha un channel pari a A (il primo canale, o canale sinistro) oppure B (il secondo canale, o canale destro). Questo separa gli interlocutori solo se ognuno è stato registrato su un canale distinto. L’audio a due canali viene fatturato una sola volta sulla durata trascorsa, non per canale. I risultati mono non hanno etichette di canale.

Usare api.multitel.net

L’endpoint di compatibilità POST https://api.multitel.net/v3/speech_to_text accetta multipart/form-data con una parte file audio e un campo facoltativo language, anziché il campo JSON audioBase64. Un valore language vuoto viene trattato come assenza di indicazione. Invia la stessa intestazione Idempotency-Key. Se l’intestazione manca, questo server accetta anche un campo di modulo idempotency_key. I campi denominati source, free, billing_source, realtime o stream vengono rifiutati con 400 unsupported_transcription_option; gli altri campi del modulo vengono ignorati. Questo server restituisce anche questi errori:

  • 400 idempotency_key_required per una chiave assente o troppo lunga.
  • 400 audio_upload_required per un caricamento assente o non ricevuto completamente.
  • 400 invalid_language per una lingua non valida.
  • 413 invalid_audio_size per un file vuoto o troppo grande.
  • 400 invalid_job per un ID dell’attività non correttamente formato.

Le risposte del servizio di trascrizione di questo server usano la struttura esterna {"status":{"code":HTTP_STATUS},"response":{...}}. Nota che status è un oggetto, non una stringa. In caso di successo, response contiene lo stesso oggetto di data sul server principale, quindi l’ID dell’attività è response.id. In caso di errore, response.code contiene il codice di errore; non sono inclusi un messaggio o un ID della richiesta. Gli errori di autenticazione (401) vengono restituiti dal controllo generale di accesso del server e possono avere un corpo diverso: controlla quindi lo stato HTTP prima del parsing. Non scambiare la codifica di caricamento o il parser delle risposte tra i server.

Per una stima su questo server, invia tramite POST gli stessi campi multipart a /v3/speech_to_text/estimate. Non serve una chiave di idempotenza e la stima è in 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'