Hyperscaler APIs promise convenience, but they lock you into fragmented pipelines. Google Speech-to-Text V2 handles transcription well for clean English audio inside Google Cloud Platform (GCP), but the moment your product touches accented speech, multilingual audio, or noisy real-world recordings, accuracy degrades and cost modeling becomes opaque. This guide provides the exact parameter mappings, code refactoring steps, and edge-case mitigations needed for a stable production cutover.
Why migrate from Google Speech-to-Text to Gladia?
Google STT remains a rational choice if your team is already deep in GCP contracts and processing clean, formal English audio at moderate volume. Switch to us when your audio is noisy, multi-speaker, or multilingual, when downstream systems like Customer Relationship Management (CRM) sync, coaching scorecards, or Large Language Model (LLM) summaries are absorbing transcript errors, or when you're stitching together separate vendors for recording, transcription, and enrichment. We replace that fragmented stack with a single API call, eliminating every seam where data degrades.
| Operational surface |
Google STT V2 |
Gladia |
| Audio recording |
Separate provider or Google Cloud Storage (GCS) |
Included in API |
| Diarization |
Requires diarizationConfig, not always clearly priced |
Included, async (pyannoteAI Precision-2) |
| Translation |
Separate Cloud Translation API |
Included at base rate |
| Summarization / Named Entity Recognition (NER) |
Not part of Google STT V2. Requires a separate NLP service (e.g., Google Cloud Natural Language API) |
Included at base rate |
| Authentication |
Service account JSON + IAM/OAuth2 |
Single x-gladia-key header |
| Multilingual code-switching |
Pre-specified languageCodes |
Automatic, mid-conversation |
Eliminating hidden transcription costs
Google STT V2 bases pricing at $16/1,000 minutes (approximately $0.96/hr) for the first 500,000 minutes. Volume tiers reduce that rate significantly at scale (to as low as $0.004/min at high volumes). The Google column below reflects volume-discounted totals, not a flat $0.96/hr calculation. Translation, summarization, and NER require separate API calls and billing surfaces. Our Starter and Growth plans include diarization, translation, sentiment analysis, NER, summarization, and custom vocabulary at the base rate, with no separate billing per feature. The Gladia column below uses the Growth floor rate of $0.20/hr, the rate available at maximum upfront commitment.
| Monthly volume (hours) |
Google STT V2 (transcription only, no enrichment add-ons) |
Gladia Growth plan (all-in, at $0.20/hr floor rate, commitment-dependent) |
Monthly savings |
| 1,000 hrs |
~$960 |
~$200 |
~$760+ |
| 10,000 hrs |
~$9,000 |
~$2,000 |
~$7,000+ |
| 50,000 hrs |
~$25,000 |
~$10,000 |
~$15,000+ |
The Google column above excludes translation and NLP enrichment. Add those surfaces and the gap widens further.
Validating WER on production audio
Benchmark your own audio before committing. Solaria-3 ranks #1 on Switchboard, the most demanding conversational telephone dataset in our suite, and scores 6.4% word error rate (WER) on Earnings22 financial calls, the only model under 7% across every provider we tested. Full methodology is at our async benchmark. Transcription accuracy sets the ceiling for everything downstream: a wrong name becomes a wrong CRM entry, and a missed entity produces a misleading coaching score. For your own audio, the blind comparison tool tests files across six providers with ELO-ranked results, no integration work required. Use it as a gut check, then follow it with a reproducible benchmark on your full audio distribution before committing.
Eliminating self-hosted STT maintenance
GPU provisioning, cold-start latency, and version management overhead on self-hosted models consume 1-2 engineers who should be building product. Moving to our managed API offloads that entire maintenance surface. Gravite reduced call quality review time by 93% using our transcription, and Aircall cut transcription time by 95% processing 1M+ calls/week. Proof points from comparable teams carry more weight than any benchmark we can cite.
Mapping Google STT parameters to Gladia
Every Google STT V2 RecognitionConfig field maps directly to our request body, and most configuration is optional because we auto-detect audio properties by default. Our speech recognition docs are the canonical reference throughout this section.
Mapping Google STT model parameters
| Google STT model |
Use case |
Gladia recommendation |
telephony / telephony_short |
Call center, phone audio |
For contact-center and post-call audio in European languages (EN, FR, DE, ES, IT), Solaria-3 is the most accurate Gladia model (async-only) |
chirp / chirp_2 / chirp_3 |
Multilingual |
For maximum language breadth, automatic code-switching, and real-time streaming, Solaria-1 is the matching Gladia model (100+ supported languages, partials under 103ms) |
| Streaming configurations |
Real-time, low-latency workflows |
For real-time streaming workflows requiring low-latency transcription, Solaria-1 is the Gladia model for this use case: ~300ms final latency, partials under 103ms, delivered over standard WebSocket |
Solaria-3 is async-only. For real-time streaming, Solaria-1 delivers partials under 103ms. Run Solaria-3 for post-call European business audio, Solaria-1 for live agent assist or global language breadth. The Solaria-3 benchmark page covers model tradeoffs in detail.
Configuring language and locale parameters
Google V2 collapses locale handling into a single languageCodes array. List every candidate language and the API returns the most likely match. We handle this automatically: setting code_switching: true inside language_config replaces that array with continuous automatic detection across all 100+ supported languages.
```json
// Google STT V2 : a single repeated language_codes field replaces V1's languageCode + alternativeLanguageCodes
{
"config": {
"languageCodes": ["en-US", "fr-FR", "de-DE"]
}
}
// Gladia equivalent
{
"language_config": {
"languages": ["en", "fr", "de"],
"code_switching": true
}
}
```
For mid-conversation language switching, language_config.code_switching: true means you don't need to pre-specify which language pairs to expect, though per our code-switching docs, pass your candidate languages in the languages array rather than leaving it empty, or detection accuracy drops.
Audio sample rate migration guide
Google STT V2 requires sampleRateHertz for raw and headerless audio formats. For FLAC and WAV files where the sample rate is embedded in the file header, the field is optional and the API reads it from the header directly, and mismatches return an error. Sample rate and channel count default to 16000 Hz and 1 channel respectively. Override these in the request body if your source audio differs.
```json
// Google STT V2 : explicit decoding parameters nest under explicitDecodingConfig, not flat on config
{
"config": {
"explicitDecodingConfig": {
"encoding": "LINEAR16",
"sampleRateHertz": 16000,
"audioChannelCount": 1
}
}
}
// Gladia : no sample rate config required
{
"audio_url": "https://your-storage.com/audio.wav"
}
```
Diarization API parameter setup
```json
// Google STT V2 : diarizationConfig nests under config.features; V2 has no separate "enable" flag, including the config enables it
{
"config": {
"features": {
"diarizationConfig": {
"minSpeakerCount": 2,
"maxSpeakerCount": 4
}
}
}
}
// Gladia equivalent
{
"diarization": true,
"diarization_config": {
"number_of_speakers": 2,
"min_speakers": 2,
"max_speakers": 4
}
}
```
Critical guardrail: Our diarization (powered by pyannoteAI Precision-2) is async-only. If your existing integration relies on speaker labels during live streaming, speaker attribution must be handled in post-processing. Do not attempt to enable diarization in a real-time WebSocket session. pyannoteAI Precision-2 requires the full recording to produce reliable speaker labels and turn-boundary timestamps.
Mapping response JSON structures
Google STT returns nested results arrays with alternatives. Our response is flatter and includes speaker ID, language tag, and float timestamps by default, giving your downstream LLM what it needs to attribute action items without additional processing.
```json
// Google STT V2 response : word timing fields are startOffset/endOffset in V2, not V1's startTime/endTime
{
"results": [{
"alternatives": [{
"transcript": "Hello world",
"confidence": 0.97,
"words": [{"word": "Hello", "startOffset": "0s", "endOffset": "0.500s"}]
}]
}]
}
// Gladia response : utterances include a "text" field, speaker ID, language tag, and float timestamps by default`
{
"result": {
"transcription": {
"full_transcript": "Hello world",
"utterances": [{
"speaker": 0,
"language": "en",
"start": 0.0,
"end": 0.5,
"confidence": 0.97,
"text": "Hello world",
"words": [{"word": "Hello", "start": 0.0, "end": 0.5, "confidence": 0.97}]
}]
}
}
}
```
Configuring custom vocabulary and context
Google STT V1 used speechContexts. V2 replaces it with inline adaptation.phraseSets. Our equivalent is the custom_vocabulary parameter. Phrase-level boosting strategies matter most when brand names or domain jargon need to survive high background noise reliably.
```json
// Google STT V2 : speechContexts is a V1 concept; V2 replaces it with inline adaptation.phraseSets
{
"config": {
"adaptation": {
"phraseSets": [{
"inlinePhraseSet": {
"phrases": [
{"value": "Gladia", "boost": 10},
{"value": "Solaria-3", "boost": 10},
{"value": "pyannoteAI", "boost": 10}
]
}
}]
}
}
}
// Gladia equivalent
{
"custom_vocabulary": ["Gladia", "Solaria-3", "pyannoteAI"]
}
```
Custom vocabulary is included at the base rate on Starter and Growth plans.
Mapping Google STT requests to Gladia endpoints
We expose two surfaces: POST /v2/pre-recorded for async batch jobs and POST /v2/live (followed by a WebSocket connection) for streaming. Both authenticate via the x-gladia-key header, and the full request schema for both endpoints is versioned and machine-readable.
Mapping Google STT REST endpoints
| Operation |
Google STT V2 |
Gladia |
| Sync transcription |
POST speech.googleapis.com/v2/projects/{project}/locations/{location}/recognizers/{recognizer}:recognize |
POST api.gladia.io/v2/pre-recorded |
| Long-running (batch) |
:batchRecognize |
Same endpoint, poll via GET /v2/pre-recorded/{id} |
| Real-time |
gRPC streaming only (StreamingRecognize) |
POST api.gladia.io/v2/live (returns WebSocket URL) |
Our async endpoint accepts audio URLs. For direct file uploads, first upload via the /upload endpoint to receive a URL, then pass that URL to /v2/pre-recorded.
Configuring real-time audio pipelines
Google's streaming STT runs over gRPC (StreamingRecognize). Our real-time API uses standard WebSockets, which removes the gRPC dependency entirely. The workflow: POST /v2/live to create a session, receive a WebSocket URL and session token, then open exactly one WebSocket per session and stream audio chunks until the session ends. Solaria-1 powers all real-time streaming with final transcript latency around 300ms and partials under 103ms, and the same WebSocket session pattern applies to browser-side React and TypeScript implementations.
Gladia API authentication setup
Replace Google's service account JSON, IAM role assignments, and OAuth2 token refresh logic with a single header.
```python
# Google STT V2 : google.cloud.speech is the V1 module; V2 lives in google.cloud.speech_v2
from google.cloud import speech_v2
client = speech_v2.SpeechClient.from_service_account_file("service-account.json")
# Gladia
headers = {"x-gladia-key": "YOUR_GLADIA_API_KEY"}
```
No token refresh cycle, no IAM policy to maintain, no service account file to rotate. Store your API key in a secrets manager and follow key-rotation practices rather than committing it to source code.
Refactoring integration logic for Gladia
Gladia SDK for batch audio workflows
Install the SDK and run a sanity check against your existing audio before touching production.
```python
# curl sanity check
# curl -X POST https://api.gladia.io/v2/pre-recorded \
# -H "x-gladia-key: YOUR_KEY" \
# -H "Content-Type: application/json" \
# -d '{"audio_url": "https://your-storage.com/sample.wav", "diarization": true}'
from gladiaio_sdk import GladiaClient
gladia_client = GladiaClient(api_key="YOUR_GLADIA_API_KEY")
transcription = gladia_client.prerecorded().transcribe(
"https://your-storage.com/sample.wav",
{
"diarization": True,
"language_config": {
"languages": ["en"],
"code_switching": True,
},
"summarization": True,
"translation": True,
},
)
print(transcription.result.transcription.full_transcript)
```
Python code for live transcription
```python
import asyncio
import websockets
import json
import requests
import base64
API_KEY = "YOUR_GLADIA_API_KEY"
async def live_transcription(audio_source):
session = requests.post(
"https://api.gladia.io/v2/live",
headers={"x-gladia-key": API_KEY, "Content-Type": "application/json"},
json={
"sample_rate": 16000,
"bit_depth": 16,
"channels": 1,
"language_config": {"languages": ["en", "fr", "de"], "code_switching": True}
}
).json()
async with websockets.connect(session["url"]) as ws:
# audio_source should yield raw Pulse Code Modulation (PCM) audio chunks (bytes)
# matching the sample_rate and bit_depth specified above
async for chunk in audio_source:
await ws.send(json.dumps({
"type": "audio_chunk",
"data": {
"chunk": base64.b64encode(chunk).decode("utf-8")
}
}))
message = json.loads(await ws.recv())
if message.get("type") == "transcript" and message["data"]["is_final"]:
utterance = message["data"]["utterance"]
print(f"[{utterance['language']}]: {utterance['text']}")
```
Refactoring async transcription logic
The key difference from Google's SDK: a single payload triggers transcription plus all audio intelligence enrichments, removing the GCS upload step required for files over 10MB in Google STT.
```python
# Google STT V2 (batch/async)
from google.cloud import speech_v2
from google.cloud.speech_v2.types import cloud_speech
client = speech_v2.SpeechClient()
config = cloud_speech.RecognitionConfig(
auto_decoding_config=cloud_speech.AutoDetectDecodingConfig(),
language_codes=["en-US"],
model="telephony",
features=cloud_speech.RecognitionFeatures(
diarization_config=cloud_speech.SpeakerDiarizationConfig(
min_speaker_count=2,
max_speaker_count=2,
),
),
)
request = cloud_speech.BatchRecognizeRequest(
recognizer="projects/my-project/locations/global/recognizers/_",
config=config,
files=[cloud_speech.BatchRecognizeFileMetadata(uri="gs://my-bucket/audio.wav")],
recognition_output_config=cloud_speech.RecognitionOutputConfig(
inline_response_config=cloud_speech.InlineOutputConfig(),
),
)
operation = client.batch_recognize(request=request)
result = operation.result()
# Gladia equivalent : single payload, all features
import requests
response = requests.post(
"https://api.gladia.io/v2/pre-recorded",
headers={"x-gladia-key": "YOUR_KEY", "Content-Type": "application/json"},
json={
"audio_url": "https://your-storage.com/audio.wav",
"diarization": True,
"language_config": {"languages": [], "code_switching": False},
"summarization": True,
"sentiment_analysis": True,
"named_entity_recognition": True
}
)
```
Handling live streams in Node.js
Set your API key as an environment variable (`export GLADIA_API_KEY=your_key_here`) before running this script.
```javascript
const WebSocket = require('ws');
const axios = require('axios');
async function startLiveStream(audioStream) {
const { data: session } = await axios.post(
'https://api.gladia.io/v2/live',
{
sample_rate: 16000,
bit_depth: 16,
channels: 1,
language_config: { languages: ['en', 'fr', 'de'], code_switching: true }
},
{ headers: { 'x-gladia-key': process.env.GLADIA_API_KEY } }
);
const ws = new WebSocket(session.url);
ws.on('open', () => {
audioStream.on('data', (chunk) => {
ws.send(JSON.stringify({
type: 'audio_chunk',
data: { chunk: chunk.toString('base64') }
}));
});
});
ws.on('message', (data) => {
const message = JSON.parse(data);
if (message.type === 'transcript' && message.data.is_final) {
const { utterance } = message.data;
console.log(`[${utterance.language}]: ${utterance.text}`);
}
});
}
```
Parsing JSON payloads and schema transitions
Mapping Google STT JSON to Gladia
The structural shift is from results[0].alternatives[0].transcript to result.transcription.utterances. Update your parsers to iterate over utterances rather than alternatives, and switch from Google's per-word speakerLabel to our utterance-level speaker integer.
Timestamp and confidence scores
Google V2 returns word timestamps as string durations ("startOffset": "1.2s"). We return float values in seconds ("start": 1.2), which simplifies downstream alignment with video frames or LLM context windows. Confidence scores appear at both the utterance and per-word level without additional config, and sit alongside entities, sentiment, and summaries in the full enriched output schema.
Parsing diarization output objects
Google's diarization attaches a speakerLabel to each word object within alternatives[0].words. Our output groups words into utterances with a single speaker label per utterance, which makes segment-level operations (routing by speaker, attributing action items) more direct.
```python
for utterance in response["result"]["transcription"]["utterances"]:
print(f"Speaker {utterance['speaker']} at {utterance['start']:.2f}s: {utterance['text']}")
```
Standardizing API error responses
Google STT uses gRPC status codes (INVALID_ARGUMENT, RESOURCE_EXHAUSTED). We return standard HTTP status codes: 400 for malformed requests, 401 for invalid API key, 413 for files exceeding size limits, and 429 for rate limit breaches. Update your retry logic accordingly.
Critical edge cases for a stable speech recognition migration
These five configuration edges account for most silent production failures during STT migrations.
File size and duration limits
Google STT caps direct synchronous requests at 10MB or 60 seconds of audio, whichever comes first. Anything beyond either limit requires Cloud Storage. We accept files up to 1,000MB and 135 minutes in duration on standard plans via the /upload endpoint, then transcribe from the returned URL. Supported formats are documented at limits and specifications. This removes the GCS bucket dependency for most production audio.
Reducing inference latency in production
For async workflows, we process approximately 1 hour of audio in under 60 seconds. For real-time, configure encoding, sample_rate, and channels in the session initialization request (see the Python live transcription example above) to match your source audio exactly, avoiding server-side format detection overhead and keeping final latency closer to 300ms.
Configuring language detection settings
Set language_config: {"languages": [...], "code_switching": true} for any audio where speakers may switch languages, listing the languages you expect rather than leaving the array empty. Without code-switching enabled, mid-sentence language changes will be transcribed as if they were still in the initial language, producing incorrect words rather than detecting the switch. The multilingual customer support guide covers production patterns for multilingual contact centers, the highest-risk audio category for language detection failures.
Mapping supported codecs and containers
We accept WAV, M4A, FLAC, and AAC natively, removing the manual transcoding step that Google's pipeline often requires for non-standard formats. If your audio comes from a telephony provider in a proprietary format, verify against the supported formats docs before migration.
Handling rate limits at scale
We scale to thousands of parallel sessions without pre-provisioning. Aircall processes 1M+ calls per week on our infrastructure. If you hit a 429 during a load test, contact us via the Slack channel provided in your onboarding email, or reach out through the support widget at docs.gladia.io.
Executing a post-migration accuracy audit
Before routing production traffic, validate transcription quality on audio samples that match your actual distribution.
Assess output quality on production clips
Select audio covering your highest-risk categories: accented speakers, noisy environments, and multi-speaker calls with language switching. Run the same clips through both integrations side by side before cutting over. This surfaces differences in accented speech and noisy audio that aggregate WER figures alone can miss.
Solaria-3 improves WER across French, Italian, Spanish, and German audio compared to Solaria-1, and ranks #1 on Switchboard against all providers in our benchmark suite. For teams serving European users, run your accented audio samples through our async benchmark before choosing a model.
Evaluating model robustness in real-world audio
Test specifically on noisy recordings: call center audio with background noise, conference calls with cross-talk, and Voice over Internet Protocol (VoIP)-compressed recordings with codec artifacts. Solaria-3 ranks #1 on Switchboard telephony audio in our async benchmarks.
Quantify API performance metrics
Instrument your test harness to capture time-to-first-transcript for async jobs, final transcript latency for real-time sessions, and WER against human-annotated ground truth for your top audio categories.
Resolving common hurdles during platform switch
Planning your migration schedule
- Day 1: API key setup, SDK installation, and a sanity-check curl against a sample file. Start with €50 in free credits to run your first transcript. For developers using AI coding assistants like Cursor or Claude Code, running
npx skills add gladiaio/skills provides structured context files that reduce API integration errors. - Days 2-3: Parameter mapping, code refactoring, and side-by-side accuracy audit on production audio samples.
- Days 3-5: Shadow mode (routing duplicate traffic to us while Google STT remains primary).
- Day 5+: Gradual traffic cutover with monitoring.
Managing concurrent API endpoints
During shadow mode, route a copy of production audio to both endpoints simultaneously. Log our transcript alongside Google's for the same request ID, then compare WER against your ground truth on a rolling basis. Keep Google STT as primary until our WER on your actual audio distribution meets your acceptance threshold.
How Gladia handles data residency
One configuration detail to clarify upfront: Our standard cloud-hosted deployment runs on dedicated clusters in EU and US regions. If your compliance requirements include a hard on-prem clause, flag this before beginning the migration. Our deployment is limited to dedicated cloud clusters in EU and US regions.
Our compliance stack covers SOC 2 Type II, ISO 27001, GDPR, HIPAA, and PCI DSS. Full documentation is at our compliance hub. On Growth and Enterprise plans, your audio is never used for model training by default, with no opt-out clause to negotiate. On the Starter plan, data can be used for training by default.
Transitioning custom vocabulary lists
Export your existing phrase list, whether from V1's speechContexts or V2's adaptation.phraseSets, and pass the phrase values directly as a custom_vocabulary array in the Gladia request body. No reformatting is required beyond the JSON key rename. Combine custom_vocabulary with named_entity_recognition: true to get both boosted accuracy and structured entity extraction in one pass.
Defining a production rollback strategy
Before cutting over, verify the following:
- Google STT credentials and service account JSON remain active and accessible
- A feature flag or environment variable controls which STT provider receives production traffic
- Monitoring alert thresholds are set for WER degradation and latency spikes on the Gladia path
- Gladia API key is stored in your secrets manager with rotation procedure documented
- On-call runbook updated with rollback procedure (revert feature flag, verify Google STT response within 5 minutes)
Our status page provides real-time uptime data, independently verifiable without relying on vendor-reported claims. Start with €50 in free credits and have your integration in production in less than a day.
FAQs
Does Gladia support on-premises or air-gapped deployment?
No. On-premises or air-gapped deployment is not available on any plan, including Enterprise. We run on dedicated cloud clusters in EU and US regions only. If your compliance requirements include a hard on-prem clause, surface this before starting your evaluation. It is a deployment constraint that applies across all tiers.
Is speaker diarization available in real-time streaming?
No, diarization is an async-only feature powered by pyannoteAI Precision-2. For real-time workflows, speaker attribution must be handled in post-processing.
Does Gladia use my audio data to train its models?
On Growth and Enterprise plans, your data is never used for model training by default. On the Starter plan, user data can be used for training unless you upgrade to a paid tier.
What is the maximum file size Gladia accepts for async transcription?
We accept file uploads up to 1,000MB and 135 minutes in duration on standard plans. Upload files via the /upload endpoint to receive a URL, then pass that URL to /v2/pre-recorded, eliminating the need for intermediate cloud storage like GCS.
How does model selection work between Solaria-1 and Solaria-3?
Use Solaria-3 for European business audio (EN, FR, DE, ES, IT) in async workflows. Use Solaria-1 for broad language coverage, code-switching, real-time streaming, or clean read-speech. Solaria-1 is the better fit for non-European languages, formal read-speech, and any real-time streaming workflow, as it's built for breadth. Solaria-3 is built for depth on European business audio: noisy, conversational, and accented.
What compliance certifications does Gladia hold?
Our certifications cover SOC 2 Type II, ISO 27001, GDPR, HIPAA, and PCI DSS. Full documentation is at our compliance hub.
Key terms glossary
Word Error Rate (WER): The standard metric for speech recognition accuracy, calculated by dividing the sum of insertions, deletions, and substitutions by the total number of words spoken. Lower is better.
Named Entity Recognition (NER): A natural language processing technique that identifies and classifies key entities (names, dates, locations, organizations) in text. We include NER in the base transcription output for structured data extraction.
Diarization Error Rate (DER): The metric for speaker diarization performance, measuring the percentage of audio time attributed to the wrong speaker or missed entirely. Full diarization benchmark methodology is at our async benchmark page.
Code-switching: The practice of alternating between two or more languages within a single conversation. We detect this automatically when code_switching: true is set inside language_config.
Solaria-3: Our speech-to-text model optimized for real-world, noisy European business and contact-center audio across English, French, German, Spanish, and Italian. Async only.
Solaria-1: Our broad-coverage model built for wide language coverage, real-time streaming with partials under 103ms, and mid-conversation code-switching.