Gladia, Deepgram, AssemblyAI, Speechmatics, Soniox et ElevenLabs, sélectionnés par bot, avec votre propre clé API, votre propre région, et transmission intégrale de chaque option spécifique au fournisseur.

Choisir un fournisseur de speech-to-text n'est pas une décision que vous prenez une seule fois. La précision sur votre domaine, le prix à l'heure, les langues dont vous avez besoin, si le fournisseur signera un DPA avec les données restant dans l'UE, et la qualité de la séparation des interlocuteurs lorsque trois personnes parlent en même temps — tout cela évolue, et la réponse n'est pas la même pour chaque client.
Nous avons donc arrêté de choisir. Vous sélectionnez le fournisseur par bot, et vous pouvez changer d'avis sur un enregistrement déjà effectué.
Ce que vous pouvez choisir
| Fournisseur | Batch | Live |
|---|---|---|
gladia | ✅ | ✅ |
deepgram | ✅ | ✅ |
assemblyai | ✅ | ✅ |
speechmatics | ✅ | ✅ |
soniox | ✅ | ✅ |
elevenlabs | — | ✅ |
ElevenLabs fonctionne uniquement en streaming. Les cinq autres proposent les deux modes.
Le mode batch est ce que la plupart des personnes souhaitent : le meeting se termine, l'audio est soumis, un webhook renvoie la transcription avec les labels des interlocuteurs et les timings au niveau du mot. Le mode live signifie que des segments de transcription arrivent via un WebSocket pendant que le meeting est encore en cours, pour tout ce qui doit réagir en temps réel.
Ils sont configurés indépendamment, et vous pouvez exécuter les deux sur le même bot avec des fournisseurs différents si vous souhaitez un flux live rapide et une transcription finale plus précise.
Batch
{
"meeting_url": "https://meet.google.com/abc-defg-hij",
"bot_name": "Recording Bot",
"transcription_enabled": true,
"transcription_config": {
"provider": "speechmatics",
"region": "eu2",
"api_key": null,
"custom_params": null
}
}Quatre champs. provider prend par défaut la valeur "gladia" si vous l'omettez. region, api_key et custom_params sont tous null par défaut et sont couverts ci-dessous.
transcription_config est requis lorsque transcription_enabled est true, et ignoré lorsqu'il est false.

Une fois le bot terminé, transcription_provider et transcription_ids sont renvoyés dans l'enregistrement du bot et dans le payload du webhook, et GET /v2/bots/:bot_id/status rapporte le transcription_status live interrogé directement auprès du fournisseur : not-applicable, not-started, queued, processing, done, ou error.
Épinglage de région
La plupart de ces fournisseurs opèrent dans plusieurs régions, et pour beaucoup de nos clients, c'est l'essentiel.
| Fournisseur | Régions batch | Régions live |
|---|---|---|
gladia | endpoint global uniquement | us-west, eu-west |
deepgram | global, eu | global, eu |
assemblyai | us, eu | us, eu |
speechmatics | eu1, eu2, us1, us2, au1 | identique |
soniox | us, eu, jp | identique |
elevenlabs | — | global, us, eu, in |
Envoyez une région qu'un fournisseur ne possède pas et vous obtiendrez une erreur 400 à la création du bot avec les valeurs autorisées listées, plutôt qu'une mauvaise surprise plus tard. L'API batch de Gladia est uniquement globale, et passer region avec provider: "gladia" dans la configuration batch est rejeté pour cette raison. Son API live dispose bien de régions.
Laissez region à null et nous choisissons une valeur par défaut sensée : eu pour Deepgram et AssemblyAI, eu1 pour Speechmatics, us pour Soniox.
Si vous avez besoin que l'audio ne quitte jamais une juridiction, combinez ceci avec bring your own storage. Les fournisseurs récupèrent l'audio depuis une URL signée sur le bucket, donc l'emplacement du bucket et la région du fournisseur déterminent ensemble où l'audio va réellement.
Apportez votre propre clé
Passez api_key et nous utilisons votre compte auprès de ce fournisseur plutôt que le nôtre.
{
"transcription_config": {
"provider": "deepgram",
"region": "eu",
"api_key": "your-deepgram-key"
}
}Les clés sont chiffrées avec AES-256-GCM avant d'être stockées et restent chiffrées en transit vers le bot, qui déchiffre au point d'utilisation. Lorsque vous supprimez les données d'un bot, la clé stockée est écrasée.
Deux raisons de l'utiliser. La première est le coût : la transcription sur notre clé est facturée à 0,25 tokens par heure, sur la vôtre à 0,05. La seconde est que certaines fonctionnalités ne sont possibles que sur votre propre compte, comme un vocabulaire personnalisé que vous avez entraîné ou un contrat avec des conditions que nous ne proposons pas.
BYOK est disponible sur tous les plans, y compris le Pay as You Go. Passez votre clé API fournisseur dans transcription_config ; aucune mise à niveau de plan n'est requise.
Options du fournisseur, transmises telles quelles
Nous n'avons délibérément pas construit une couche d'options normalisée. Chaque fournisseur dispose de fonctionnalités que les autres n'ont pas, et les aplanir au plus petit dénominateur commun signifierait abandonner la raison pour laquelle vous avez choisi ce fournisseur.
custom_params est envoyé au fournisseur plus ou moins tel que vous l'avez écrit :
{
"transcription_config": {
"provider": "speechmatics",
"region": "eu2",
"custom_params": {
"transcription_config": {
"language": "en",
"diarization": "speaker",
"operating_point": "enhanced"
}
}
}
}La notation pointée fonctionne aussi, si elle est plus facile à construire :
{ "custom_params": { "diarization_config.min_speakers": 2 } }Dans la configuration live, elle est dépliée avant la validation, vous validez donc la forme que le fournisseur recevra réellement. Dans la configuration batch, la clé plate est validée telle qu'écrite et dépliée plus tard, lors de la soumission.
Dans la configuration live, quatre champs sont définis par le pipeline et rejetés si vous les envoyez : encoding, sample_rate, bit_depth, channels. Le sample rate en particulier est négocié par fournisseur à partir de l'audio du meeting, donc le remplacer casserait le flux. Utilisez plutôt streaming_config.audio_frequency.
La séparation des interlocuteurs est activée par défaut, car sans elle vous obtenez un bloc de texte sans labels d'interlocuteurs, et au moins un fournisseur renvoie silencieusement aucune utterance si vous ne le demandez pas explicitement. Une valeur explicite dans custom_params prend le dessus.
Le piège : batch et live n'acceptent pas les mêmes structures
C'est ce qui coûte une après-midi à certaines personnes, il vaut donc la peine de le dire clairement. Pour le même fournisseur, l'API live et l'API batch n'acceptent pas la même structure de paramètres.
Gladia est l'exemple le plus clair. Le batch prend la configuration de traduction au niveau supérieur. Le live veut qu'elle soit imbriquée sous realtime_processing :
{
"streaming_config": {
"mode": "transcription",
"output_url": "wss://your-app.example.com/transcripts",
"audio_frequency": 24000,
"transcription": {
"provider": "gladia",
"region": "eu-west",
"api_key": "your-gladia-key",
"custom_params": {
"language_config": { "languages": ["ru"] },
"realtime_processing": {
"translation": true,
"translation_config": { "target_languages": ["en"] }
}
}
}
}
}Les paramètres live sont validés en mode strict, car les API de session live rejettent directement les clés inconnues et nous préférons échouer à la création de votre bot plutôt qu'à votre meeting. Lorsque vous envoyez une clé qui appartient un niveau plus bas, l'erreur vous indique où elle doit aller :
'translation' is not a top-level field of the gladia live API —
did you mean 'realtime_processing.translation'?
(the live API shape differs from batch)Les paramètres batch et live sont tous deux vérifiés par rapport au schéma propre à chaque fournisseur lors de la création du bot, de sorte qu'une faute de frappe revient sous forme de 400 en une seconde plutôt qu'une transcription échouée une heure plus tard. Deux réserves sur la rigueur de cette vérification. L'analyse batch est permissive, donc une clé batch inconnue passe la validation et est transmise pour que le fournisseur la gère ; seul le live rejette les clés inconnues. Et les paramètres live d'ElevenLabs sont transmis sans validation, car il n'existe pas de schéma publié contre lequel les vérifier.
Sortie live
Avec mode: "transcription", nous ouvrons la session fournisseur, lui alimentons l'audio du meeting, et transmettons les événements à votre output_url en JSON :
{
"event": "transcript.segment",
"bot_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"data": {
"text": "so the migration lands Thursday",
"isFinal": true,
"utteranceStart": 12.44,
"utteranceEnd": 14.91,
"confidence": 0.97,
"speaker": { "name": "Alice", "id": 1 },
"words": []
}
}Également session.started avec le fournisseur utilisé, translation lorsque vous l'avez demandé, et error. Nous envoyons un ping toutes les 30 secondes pour éviter que les intermédiaires ne ferment un socket inactif.
Une contrainte : les sessions live sur notre clé de plateforme sont limitées à un ensemble géré de fournisseurs, actuellement Gladia. Tout autre fournisseur pour la transcription live nécessite une clé BYOK, et nous le rejetons à la création du bot avec FST_ERR_STREAMING_TRANSCRIPTION_KEY_UNAVAILABLE plutôt que de le découvrir lorsque le meeting commence.
Changer d'avis
POST /v2/bots/:bot_id/retranscribe{
"transcription": {
"provider": "assemblyai",
"region": "eu",
"api_key": "your-assemblyai-key"
}
}L'audio stocké est resoumis à un fournisseur différent et la configuration du bot est mise à jour. C'est ainsi que vous comparez deux fournisseurs sur vos propres meetings plutôt que sur leur audio de démonstration, et c'est ainsi que vous récupérez une transcription qui a échoué.
La suppression des données d'un bot retire également la transcription du fournisseur, avec ?delete_from_provider=true (la valeur par défaut), en utilisant votre propre clé si vous en avez fourni une.
Ce qui se passe lorsqu'un fournisseur a une mauvaise journée
Une soumission échouée est réessayée deux fois, à 5 et 15 secondes, pour un total de trois tentatives. Seules les erreurs pour lesquelles une nouvelle tentative pourrait plausiblement fonctionner sont éligibles : les rate limits, les erreurs 5xx, les timeouts de connexion et de polling, les échecs au niveau réseau, et le cas où le fournisseur a renvoyé un 2xx avec un body ne contenant aucun job id. Les erreurs d'authentification, les entrées invalides et les opérations non supportées ne sont jamais réessayées, car elles échoueront de façon identique la deuxième fois.
Chaque nouvelle tentative fait pivoter le callback secret avant de resoumettre. Cela ferme une vraie course : si le fournisseur a effectivement accepté un job dont la response a expiré de notre côté, son callback arrive avec un secret qui n'existe plus et est rejeté, au lieu de faire la course avec le job retenté et de produire deux transcriptions pour un seul chunk.
Il n'y a pas de basculement automatique vers un second fournisseur, et je préfère le dire clairement plutôt que vous le laisser découvrir lors d'un incident. Si le fournisseur que vous avez choisi échoue après les nouvelles tentatives, le bot se termine avec failed et TRANSCRIPTION_FAILED, et l'enregistrement ainsi que les artefacts audio sont toujours présents. La récupération se fait via un appel retranscribe, en nommant optionnellement un fournisseur différent. Changer silencieusement de fournisseur signifierait une transcription dans une juridiction que vous n'avez pas acceptée, à un prix que vous n'avez pas accepté — c'est donc une décision que nous vous laissons.
En relation
- Bring Your Own Storage — contrôlez où réside réellement l'audio que le fournisseur lit
- Référence API Meeting BaaS