Cette API transcrit des fichiers audio finalisés sous forme de tâches mises en file d’attente. Envoyez un fichier, conservez l’identifiant de tâche renvoyé et consultez la tâche jusqu’à la fin du traitement. Envoyez chaque requête en HTTPS avec les identifiants de votre compte, soit les identifiants HTTP Basic présentés dans les exemples, soit un jeton API, comme indiqué dans Authentification. Conservez les identifiants sur votre serveur.
Points de terminaison
Les deux serveurs API, https://api.multi.tel et le serveur de compatibilité https://api.multitel.net, partagent, au niveau du compte, les tâches, les clés d’idempotence, les limites et la facturation. Ils diffèrent par l’encodage des envois et l’enveloppe des réponses : utilisez donc toujours le même serveur avec un analyseur adapté.
| Opération | Méthode et chemin |
|---|---|
| Informations sur le service | GET /v3/speech_to_text |
| Soumettre une tâche | POST /v3/speech_to_text |
| Estimer sans créer de tâche | POST /v3/speech_to_text/estimate |
| Consulter une tâche | GET /v3/speech_to_text/JOB_ID |
| Régler une tâche en attente de paiement | POST /v3/speech_to_text/JOB_ID/settle |
| Utilisation | GET /v3/speech_to_text/usage |
Sur api.multi.tel, chaque chemin est également disponible avec le préfixe /v1/speech-to-text à la place de /v3/speech_to_text, par exemple POST /v1/speech-to-text/estimate. Sur api.multitel.net, utilisez les chemins /v3/speech_to_text.
La réponse d’information sur le service indique mode (batch), realtime (false), paidEnabled (si de nouvelles soumissions payantes sont actuellement acceptées), pricePerMinuteUsd (0.005), billingUnit (audio_second), maxAudioSeconds (7200) et maxUploadBytes (26214400), ainsi qu’une courte description. Sa consultation est gratuite et reste possible lorsque les soumissions payantes sont désactivées ; elle ne renvoie 503 transcription_unavailable que lorsque le service dans son ensemble est indisponible.
Préparer un fichier audio
Utilisez un fichier audio finalisé de 25 MiB (26,214,400 octets) maximum et d’une durée maximale de 2 heures (7,200 secondes). À l’envoi, le fichier doit être reconnu comme un média MP3, WAV, Ogg, FLAC, MOV ou Matroska contenant un flux audio, avec une durée indiquée dans ses métadonnées supérieure à zéro et ne dépassant pas 7,200 secondes. Un fichier reconnu qui échoue à ces contrôles est rejeté avec 422 unsupported_audio. Un fichier qui ne peut être lu dans aucun de ces formats peut actuellement être rejeté par une erreur serveur (500) à la place ; ne renvoyez pas un tel fichier sans le modifier. L’extension du fichier ne suffit pas à établir sa compatibilité.
Réussir ces contrôles ne garantit pas que l’audio puisse être décodé. L’audio est traité sur un ou deux canaux. Un fichier comportant plus de deux canaux audio, un fichier dont l’audio décodé dépasse 2 heures ou tout autre fichier dont le décodage échoue pendant le traitement aboutit à une tâche failed, généralement avec decode_failed, et n’est pas facturé. Convertissez l’audio multicanal en mono ou en stéréo avant l’envoi.
L’indication de langue facultative est un code de deux ou trois lettres minuscules pour la langue parlée, par exemple en. Pour ne pas donner d’indication, omettez le champ ; api.multi.tel rejette une chaîne vide. Cette indication guide le traitement, mais n’est pas vérifiée dans une liste de langues prises en charge : utilisez donc un code valide pour la langue parlée.
Soumettre une tâche de transcription
Envoyez du JSON avec Content-Type: application/json à POST https://api.multi.tel/v3/speech_to_text. Le corps de la requête peut atteindre 35 MiB, ce qui permet de transmettre un fichier de taille maximale après encodage en base64 ; un corps plus volumineux est rejeté avec 413.
| Champ | Signification |
|---|---|
audioBase64 | Obligatoire. Le fichier complet en base64 standard (A–Z, a–z, 0–9, +, /) avec un remplissage = si nécessaire. N’ajoutez ni préfixe d’URL de données, ni sauts de ligne, ni espaces, et n’utilisez pas l’alphabet adapté aux URL. La valeur décodée doit avoir une taille comprise entre 1 octet et 25 MiB, et son réencodage doit produire exactement le même texte. |
language | Indication de langue facultative, décrite ci-dessus. |
Toute autre propriété JSON, y compris idempotency_key, est rejetée avec 400 invalid_transcription_request. Envoyez la clé dans un en-tête.
Clé d’idempotence
Chaque soumission nécessite un en-tête Idempotency-Key de 1 à 190 caractères. Utilisez des lettres ASCII, des chiffres, -, _, . et :, sans espaces au début ni à la fin : le serveur de compatibilité supprime les espaces autour de la clé et mesure sa longueur en octets. D’autres caractères peuvent donc être comptés différemment selon le serveur. Une clé absente ou d’au moins 191 caractères est rejetée avec 400.
Les clés sont limitées à votre compte et à la transcription, sur les deux serveurs et pour tous les identifiants de votre compte. Renvoyer la même clé avec le même fichier et la même langue renvoie la tâche existante avec HTTP 200 et duplicate: true, quel que soit son état, même si le traitement a été mis à jour depuis sa création, sans nouvelle facturation. Réutiliser une clé avec un fichier ou une langue différents renvoie 409 idempotency_conflict. Une nouvelle clé crée une nouvelle tâche même pour un fichier identique, avec une facturation distincte si le traitement se termine avec succès.
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'Une nouvelle tâche renvoie HTTP 202 avec les champs ci-dessous ; un nouvel envoi de la même requête renvoie HTTP 200 avec l’objet de tâche complet décrit dans Consulter la transcription. Lisez l’identifiant de tâche, un UUID, dans data.id. La réponse à une nouvelle tâche se présente ainsi (l’identifiant et les valeurs sont des exemples) :
{
"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"
}
}Tant qu’une tâche est en file d’attente ou en cours, durationSeconds, billedSeconds et costUsd sont des estimations issues des métadonnées du fichier. La facturation finale utilise la durée décodée.
Une soumission peut aussi renvoyer 402 insufficient_balance si le solde prépayé ne couvre pas la tâche et vos autres tâches en cours, 429 transcription_queue_full si votre compte ou le service a trop de tâches en cours, 429 audio_validation_busy si la capacité de validation des fichiers est atteinte, et 503 paid_transcription_not_enabled lorsque la transcription payante est désactivée. En cas de réponse 429 ou 503, réessayez plus tard avec la même clé.
Estimer sans créer de tâche
Envoyez le même corps JSON à POST https://api.multi.tel/v3/speech_to_text/estimate. Aucune clé d’idempotence n’est nécessaire. Une estimation valide et mesure le fichier, mais ne le transcrit pas, ne crée pas de tâche, ne réserve pas de fonds, ne vérifie pas votre solde et ne facture pas votre compte. Une indication language est acceptée, mais ne modifie pas l’estimation.
Une estimation réussie renvoie HTTP 200 avec estimate: true, charged: false, mode, realtime, durationSeconds, billedSeconds, pricePerMinuteUsd et costUsd sous data. Elle utilise la durée indiquée dans les métadonnées du fichier, alors qu’une tâche terminée est facturée selon la durée décodée, qui peut différer. Les estimations appliquent les mêmes contrôles de fichier que les soumissions. Elles ne sont disponibles que lorsque la transcription payante est activée (sinon 503 paid_transcription_not_enabled). Elles peuvent renvoyer 429 audio_validation_busy si la capacité de validation des fichiers est atteinte ; réessayez après une courte attente.
Consulter la transcription
Interrogez régulièrement GET /v3/speech_to_text/JOB_ID comme indiqué dans le guide du déroulement des tâches. L’objet de tâche contient les champs suivants :
| Champ | Signification |
|---|---|
id | L’UUID de la tâche. |
status | queued, running, completed, failed ou awaiting_payment. |
progress | Un pourcentage de 0 à 99 pendant le traitement, s’il est disponible ; 100 une fois terminé ; sinon null. |
durationSeconds, billedSeconds | Durée audio et secondes entières facturées. Il s’agit d’estimations tirées des métadonnées tant que la tâche est en file d’attente ou en cours. Une fois terminée ou en attente de paiement, elles utilisent la durée décodée. |
costUsd, costIsEstimate | Le coût en dollars américains, sous forme de chaîne décimale à neuf décimales. costIsEstimate vaut true tant que la tâche est en file d’attente ou en cours. Une tâche en échec n’est pas facturée, même si son champ costUsd affiche toujours l’estimation. |
pricePerMinuteUsd | 0.005 pour les tâches API, et 0.000 pour les tâches gratuites d’enregistrement Hosted PBX. |
failureCode | Pour une tâche en échec : decode_failed (l’audio n’a pas pu être décodé, par exemple parce qu’il comporte plus de deux canaux ou dépasse 2 heures après décodage), inference_timeout (le traitement a pris trop de temps), service_error ou worker_lease_lost (le traitement a été interrompu). Les codes unsupported_audio et quality_check_failed sont aussi définis. Une tâche en attente de paiement affiche insufficient_balance, qui peut rester après le règlement de la tâche. |
source, modelVersion, createdAt | source vaut api pour les soumissions API, ou hpbx pour une tâche d’enregistrement Hosted PBX de votre compte. modelVersion est une chaîne opaque indiquant la version du traitement. createdAt est l’heure de soumission. |
duplicate | true dans les réponses qui renvoient une tâche existante. |
result | Présent uniquement lorsque status vaut completed. |
| Champ du résultat | Signification |
|---|---|
text | La transcription complète : tous les textes des segments réunis par des sauts de ligne, dans l’ordre des segments. |
segments | Un tableau de segments classés par instant de début. Chaque segment couvre une portion audio d’environ 29 secondes au maximum. Ses champs start et end (en secondes depuis le début de l’audio) délimitent cette portion, pas des mots ou phrases individuels, et des portions consécutives peuvent se chevaucher d’au plus 1 seconde. Chaque segment contient aussi text et language (un code de langue, qui peut être vide), ainsi que channel pour les résultats à deux canaux. |
channelCount | 1 ou 2. Présent dans les résultats actuels ; les anciens résultats peuvent l’omettre. |
audioDurationMs | La durée décodée en millisecondes. La facturation l’arrondit à la seconde entière supérieure. |
qualityFlags | Vide, ou review_recommended accompagné de repetition_detected (une expression se répète anormalement souvent dans une portion), no_speech (aucune parole n’a été transcrite), ou les deux. |
pipelineVersion | Peut apparaître. Un identifiant opaque du traitement. |
Les transcriptions, horodatages, étiquettes de langue et de canal sont produits automatiquement et leur exactitude n’est pas garantie. Tout indicateur de qualité doit vous inciter à vérifier le résultat ; comparez les noms, nombres et engagements importants avec l’audio original. Les longs silences et passages très peu audibles sont ignorés et ne produisent aucun segment. Les résultats n’identifient pas les locuteurs individuellement. Lorsqu’un résultat indique un channelCount de 2, chaque segment possède un channel valant A (le premier canal, ou canal gauche) ou B (le second canal, ou canal droit). Cela ne distingue les locuteurs que si chacun a été enregistré sur un canal séparé. L’audio à deux canaux est facturé une seule fois selon sa durée écoulée, et non par canal. Les résultats mono n’ont pas d’étiquettes de canal.
Utiliser api.multitel.net
Le point de terminaison de compatibilité POST https://api.multitel.net/v3/speech_to_text accepte multipart/form-data avec une partie fichier audio et un champ facultatif language, plutôt que du JSON audioBase64. Une valeur language vide est traitée comme l’absence d’indication. Envoyez le même en-tête Idempotency-Key. Si l’en-tête est absent, ce serveur accepte aussi un champ de formulaire idempotency_key. Les champs nommés source, free, billing_source, realtime ou stream sont rejetés avec 400 unsupported_transcription_option ; les autres champs du formulaire sont ignorés. Ce serveur renvoie aussi les erreurs suivantes :
- 400
idempotency_key_requiredpour une clé absente ou trop longue. - 400
audio_upload_requiredpour un fichier absent ou dont la réception est incomplète. - 400
invalid_languagepour une langue non valide. - 413
invalid_audio_sizepour un fichier vide ou trop volumineux. - 400
invalid_jobpour un identifiant de tâche mal formé.
Les réponses du service de transcription de ce serveur utilisent l’enveloppe {"status":{"code":HTTP_STATUS},"response":{...}}. Notez que status est un objet, et non une chaîne. En cas de succès, response contient le même objet que data sur le serveur principal ; l’identifiant de tâche est donc response.id. En cas d’erreur, response.code contient le code d’erreur ; ni message ni identifiant de requête ne sont inclus. Les échecs d’authentification (401) sont renvoyés par le contrôle général de connexion du serveur et peuvent avoir un corps différent : vérifiez donc le statut HTTP avant l’analyse. Ne permutez pas l’encodage des envois ou l’analyseur de réponse entre les serveurs.
Pour une estimation sur ce serveur, envoyez les mêmes champs multipart par POST à /v3/speech_to_text/estimate. Aucune clé d’idempotence n’est nécessaire et l’estimation se trouve sous 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'