Gladia, Deepgram, AssemblyAI, Speechmatics, Soniox e ElevenLabs, escolhidos por bot, com a sua própria chave de API, a sua própria região e repasse completo de cada opção específica do provedor.

Escolher um provedor de speech-to-text não é uma decisão que se toma uma vez só. Precisão no seu domínio, preço por hora, os idiomas de que você precisa, se o fornecedor vai assinar um DPA com os dados ficando na UE, e o quanto a diarização se sustenta quando três pessoas falam por cima uma da outra: tudo isso muda, e nada disso tem a mesma resposta para todo cliente.
Então paramos de escolher. Você escolhe o provedor por bot, e pode mudar de ideia sobre uma gravação que já tem.
O que você pode escolher
| Provedor | Batch | Ao vivo |
|---|---|---|
gladia | ✅ | ✅ |
deepgram | ✅ | ✅ |
assemblyai | ✅ | ✅ |
speechmatics | ✅ | ✅ |
soniox | ✅ | ✅ |
elevenlabs | — | ✅ |
O ElevenLabs é somente streaming. Os outros cinco fazem os dois.
Batch é o que a maioria das pessoas quer: a reunião termina, o áudio é enviado, um webhook traz de volta a transcrição com rótulos de quem falou e marcações de tempo por palavra. Ao vivo significa segmentos de transcrição chegando por um WebSocket enquanto a reunião ainda acontece, para qualquer coisa que precise reagir ali na sala.
Os dois são configurados de forma independente, e você pode rodar ambos no mesmo bot com provedores diferentes se quiser um feed ao vivo rápido e uma transcrição final mais precisa.
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
}
}Quatro campos. provider assume "gladia" se você omitir. region, api_key e custom_params são todos null por padrão e estão explicados abaixo.
transcription_config é obrigatório quando transcription_enabled é true, e ignorado quando é false.

Assim que o bot termina, transcription_provider e transcription_ids voltam no registro do bot e no payload do webhook, e GET /v2/bots/:bot_id/status reporta o transcription_status ao vivo, consultado do próprio provedor: not-applicable, not-started, queued, processing, done ou error.
Fixação de região
A maioria desses provedores roda em mais de uma região e, para muitos dos nossos clientes, é isso que decide tudo.
| Provedor | Regiões de batch | Regiões ao vivo |
|---|---|---|
gladia | somente endpoint global | us-west, eu-west |
deepgram | global, eu | global, eu |
assemblyai | us, eu | us, eu |
speechmatics | eu1, eu2, us1, us2, au1 | as mesmas |
soniox | us, eu, jp | as mesmas |
elevenlabs | — | global, us, eu, in |
Envie uma região que o provedor não tem e você recebe um 400 na criação do bot, com os valores permitidos listados, em vez de uma surpresa mais adiante. A API de batch da Gladia é somente global e, por isso, passar region com provider: "gladia" na configuração de batch é rejeitado. A API ao vivo dela, sim, tem regiões.
Deixe region em null e escolhemos um padrão sensato: eu para Deepgram e AssemblyAI, eu1 para Speechmatics, us para Soniox.
Se você precisa que o áudio nunca saia de uma jurisdição, combine isso com traga o seu próprio armazenamento. Os provedores buscam o áudio a partir de uma URL assinada no bucket, então a localização do bucket e a região do provedor juntas determinam para onde o áudio realmente vai.
Traga a sua própria chave
Passe api_key e usamos a sua conta naquele provedor em vez da nossa.
{
"transcription_config": {
"provider": "deepgram",
"region": "eu",
"api_key": "your-deepgram-key"
}
}As chaves são criptografadas com AES-256-GCM antes de serem armazenadas e continuam criptografadas em trânsito até o bot, que descriptografa no ponto de uso. Quando você exclui os dados de um bot, a chave armazenada é sobrescrita.
Há duas razões para usar isso. A primeira é custo: a transcrição na nossa chave é cobrada a 0,25 token por hora, na sua a 0,05. A segunda é que algumas coisas só são possíveis na sua própria conta, como um vocabulário personalizado que você treinou ou um contrato com termos que nós não temos.
O BYOK está disponível nos planos Pro e acima. Sem ele, você recebe FST_ERR_BYOK_TRANSCRIPTION_NOT_ENABLED_ON_PLAN.
Opções do provedor, repassadas direto
Deliberadamente não construímos uma camada normalizada de opções. Cada provedor tem recursos que os outros não têm, e achatá-los em um denominador comum significaria jogar fora justamente o motivo pelo qual você escolheu aquele provedor.
custom_params vai para o provedor mais ou menos como você escreveu:
{
"transcription_config": {
"provider": "speechmatics",
"region": "eu2",
"custom_params": {
"transcription_config": {
"language": "en",
"diarization": "speaker",
"operating_point": "enhanced"
}
}
}
}A notação de ponto também funciona, se for mais fácil de montar:
{ "custom_params": { "diarization_config.min_speakers": 2 } }Na configuração ao vivo, ela é desachatada antes da validação, então você valida o formato que o provedor vai de fato receber. Na configuração de batch, a chave achatada é validada como foi escrita e desachatada depois, no envio.
Na configuração ao vivo, quatro campos são definidos pelo pipeline e rejeitados se você os enviar: encoding, sample_rate, bit_depth, channels. A taxa de amostragem em especial é negociada por provedor a partir do áudio da reunião, então sobrescrevê-la quebraria o stream. Use streaming_config.audio_frequency no lugar.
A diarização vem ligada por padrão, porque sem ela você recebe uma parede de texto sem rótulos de quem falou, e pelo menos um provedor devolve silenciosamente nenhuma fala a menos que você peça. Um valor explícito em custom_params prevalece.
A pegadinha: batch e ao vivo aceitam formatos diferentes
Essa é a coisa que custa uma tarde às pessoas, então vale dizer com todas as letras. Para o mesmo provedor, a API ao vivo e a API de batch não aceitam o mesmo formato de parâmetros.
A Gladia é o exemplo mais claro. O batch recebe a configuração de tradução no nível superior. O ao vivo a quer aninhada sob 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"] }
}
}
}
}
}Os parâmetros ao vivo são validados em modo estrito, porque as APIs de sessão ao vivo rejeitam chaves desconhecidas de cara, e preferimos falhar na criação do seu bot a falhar na sua reunião. Quando você envia uma chave que pertence a um nível abaixo, o erro te diz para onde ela vai:
'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)Tanto os parâmetros de batch quanto os ao vivo são verificados contra o schema de cada provedor na criação do bot, então um erro de digitação volta como um 400 em um segundo, em vez de uma transcrição falha uma hora depois. Duas ressalvas sobre o quanto isso é estrito. A análise do batch é permissiva, então uma chave de batch desconhecida passa na validação e é encaminhada para o provedor lidar com ela; só o ao vivo rejeita chaves desconhecidas. E os parâmetros ao vivo do ElevenLabs são repassados sem validação, porque não existe schema publicado com o qual possamos conferi-los.
Saída ao vivo
Com mode: "transcription", abrimos a sessão do provedor, alimentamos ela com o áudio da reunião e encaminhamos os eventos para o seu output_url como 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": []
}
}Também há session.started com o provedor que foi usado, translation quando você pediu por ela, e error. Fazemos um ping a cada 30 segundos para impedir que intermediários fechem um socket ocioso.
Uma restrição: sessões ao vivo na nossa chave de plataforma ficam limitadas a um conjunto gerenciado de provedores, atualmente a Gladia. Qualquer outro provedor para transcrição ao vivo precisa de uma chave BYOK, e rejeitamos isso já na criação do bot com FST_ERR_STREAMING_TRANSCRIPTION_KEY_UNAVAILABLE, em vez de descobrir quando a reunião começa.
Mudando de ideia
POST /v2/bots/:bot_id/retranscribe{
"transcription": {
"provider": "assemblyai",
"region": "eu",
"api_key": "your-assemblyai-key"
}
}O áudio armazenado é reenviado a um provedor diferente e a configuração do bot é atualizada. É assim que você faz um teste A/B entre dois fornecedores nas suas próprias reuniões em vez de no áudio de demonstração deles, e é assim que você recupera uma transcrição que falhou.
Excluir os dados de um bot também tira a transcrição do provedor, com ?delete_from_provider=true (o padrão), usando a sua própria chave onde você forneceu uma.
O que acontece quando um provedor tem um dia ruim
Um envio que falha é repetido duas vezes, aos 5 e aos 15 segundos, três tentativas no total. Só erros em que uma nova tentativa poderia plausivelmente funcionar são elegíveis: limites de taxa, 5xx, timeouts de conexão e de polling, falhas de rede e o caso em que o provedor retornou um 2xx com um corpo sem nenhum id de job. Erros de autenticação, entrada inválida e operações não suportadas nunca são repetidos, porque falhariam de forma idêntica na segunda vez.
Cada nova tentativa rotaciona o segredo de callback antes de reenviar. Isso fecha uma corrida real: se o provedor de fato aceitou um job cuja resposta atingiu o tempo limite do nosso lado, o callback dele chega contra um segredo que não existe mais e é rejeitado, em vez de correr contra o job reenviado e produzir duas transcrições para um mesmo trecho.
Não existe failover automático para um segundo provedor, e prefiro dizer isso com todas as letras a deixar você descobrir durante um incidente. Se o provedor que você escolheu falhar depois das tentativas, o bot termina em failed com TRANSCRIPTION_FAILED, e a gravação e os artefatos de áudio continuam todos lá. A recuperação é uma chamada de retranscribe, opcionalmente indicando outro provedor. Trocar de fornecedor silenciosamente significaria uma transcrição em uma jurisdição com a qual você não concordou, a um preço com o qual você não concordou, então é uma decisão que deixamos com você.
Relacionados
- Traga o Seu Próprio Armazenamento — controle onde o áudio que o provedor lê realmente fica
- Referência da API do Meeting BaaS