AssemblyAI's Universal-2 base rate of $0.15 per hour looks competitive until you start enabling the features your production pipeline actually needs. Their current flagship, Universal-3.5 Pro, carries a $0.21/hr base rate and adds native code-switching, but add-ons stack on top at the same rates, so it's worth modelling the full feature stack if you're evaluating their current offering rather than the legacy tier. Speaker diarization, sentiment analysis, and entity detection each carry separate charges, and the LLM layer is billed on top as a token-based product at significantly higher cost. At 5,000+ hours per month, that stack compounds fast. Beyond cost, if you're serving non-English speakers or multilingual teams, accuracy gaps on accented and code-switched audio surface in production before they surface in your metrics.
This guide is a technical blueprint for migrating your production workloads to our unified audio infrastructure: endpoint mappings, JSON payload comparisons, WebSocket reconfiguration, and a zero-downtime cutover strategy. We cover the exact parameter changes for diarization, PII redaction, summarization, and sentiment analysis, along with a rollback plan you can execute in minutes if anything breaks in staging.
Pre-migration checklist
Before changing a line of code, spend two to four hours on preparation. Migrations fail when teams jump straight to API calls without understanding their current footprint.
Quantify your AssemblyAI API consumption
Pull your last 90 days of AssemblyAI invoices and extract three numbers: total async audio hours per month, peak concurrent real-time streams, and the add-on features enabled per call. Then rebuild your true cost per hour by summing the base rate plus each feature's separate charge. The cost comparison in this guide uses AssemblyAI's Universal-2 tier, which remains available and is the basis for the published add-on rates below. Their current flagship model, Universal-3.5 Pro, is priced at $0.21/hr base, with the same add-on rates stacking on top. The equivalent four-feature stack (diarization, sentiment, entity detection, summarization) runs $0.36/hr on Universal-3.5 Pro. If you are on or evaluating Universal-3.5 Pro, substitute that total into the model below. Per AssemblyAI's public pricing, the Universal-2 base rate is $0.15/hr, with diarization adding $0.02/hr, sentiment analysis $0.02/hr, entity detection $0.08/hr, and summarization $0.03/hr. A typical production stack with diarization, sentiment, entities, and summarization runs $0.30/hr before any LLM features.
Map AssemblyAI features to Gladia
The table below maps AssemblyAI parameters to our equivalents. All features in the Gladia column are included in our base rate on Starter and Growth plans, with no separate add-on charges.
Table 1: API parameter mapping (AssemblyAI to Gladia)
| AssemblyAI parameter |
Gladia equivalent |
Notes |
audio_url |
audio_url |
Direct URL accepted. For file uploads, use the /upload endpoint first. |
speaker_labels: true |
diarization: true |
Async only. Powered by pyannoteAI's Precision-2 model. |
speaker_count |
diarization_config.number_of_speakers |
Optional hint to improve attribution accuracy. |
entity_detection: true |
named_entity_recognition: true |
Included in base rate. |
sentiment_analysis: true |
sentiment_analysis: true |
Text-based inference from the transcript, not acoustic analysis. |
redact_pii: true |
pii_redaction: true |
Must be explicitly enabled on every request. Off by default on all plans. |
summarization: true |
summarization: true |
Enable in the same API call, priced into the base rate. |
word_boost: [...] |
custom_vocabulary_config + custom_spelling_config |
Two separate mechanisms providing more granular control. |
language_code |
language |
Auto-detection available without specifying a language. |
webhook_url |
callback_config.url |
Per-request or global webhook configuration. |
Defining your migration rollback plan
Build your rollback plan before writing migration code. The cleanest approach is an abstraction layer between your application and the speech-to-text (STT) provider, a TranscriptProvider interface that both AssemblyAI and Gladia implement behind the scenes. If anomalies appear in staging, you flip a single environment variable and traffic reverts with no application code changes:
```python
# Abstraction layer interface
class TranscriptProvider:
def submit_job(self, audio_url: str, config: dict) -> str:
"""Returns job_id"""
pass
def get_result(self, job_id: str) -> dict:
"""Returns transcript with standardized internal schema"""
pass
# Switch provider via environment variable
provider = GladiaProvider() if USE_GLADIA else AssemblyAIProvider()
```
Wrap the vendor response in a standard internal schema on day one and you can swap providers at the abstraction layer without touching application code. During the dual-write phase, store both vendors' transcript_id values against the same source audio record in your database so you can compare outputs without corrupting downstream systems.
Configuring your Gladia API connection
Access your developer API key
Sign up at our getting started page to retrieve your API key from the developer console. The Starter plan includes a €50 in free credits for testing your migration before committing to a production volume.
Map credentials to Gladia
The only environment variable you need to update for authentication is the header name. The header changes from AssemblyAI's authorization to the x-gladia-key:
```python
# AssemblyAI - old header name
headers = {"authorization": "YOUR_ASSEMBLYAI_KEY"}
# Gladia - new header name
headers = {"x-gladia-key": "YOUR_GLADIA_API_KEY"}
```
Update both the header and the base URL (https://api.gladia.io/v2/) in your environment config before making your first request.
Mapping AssemblyAI batch processing to Gladia API
Async transcription is our primary workflow and where the accuracy and cost advantages are most pronounced. The pre-recorded transcription flow follows a two-step pattern: submit the job, then retrieve the result via polling or webhook.
Mapping AssemblyAI endpoints
| Step |
AssemblyAI |
Gladia |
| Submit job |
POST /v2/transcript |
POST /v2/pre-recorded |
| Poll result |
GET /v2/transcript/{id} |
GET {result_url} |
| Auth header |
authorization |
x-gladia-key |
| File upload |
Inline in POST body |
POST /v2/upload first, then pass audio_url |
The /v2/pre-recorded endpoint accepts audio URLs only. If your current pipeline sends raw file bytes to AssemblyAI, add an upload step using our multipart upload endpoint to get an audio_url first. In the async pipeline, one hour of audio reaches completed status in under 60 seconds of wall-clock time from initial POST submission to transcript availability. Factor that into your end-to-end timing model.
Configure webhooks for audio events
Our webhook system supports two patterns. You can set a global webhook in the account console that fires on all completed transcriptions, or pass a per-request callback_config.url in the POST body for finer-grained routing. Implement polling on result_url until the status field returns done as your automatic fallback for cases where webhook delivery times out.
Adapting JSON response payloads
The response schema is where most teams spend their first debugging sprint.
AssemblyAI returns a top-level utterances array (populated when speaker_labels is enabled), each containing the speaker's text and a nested words array. We nest the same information one level deeper, under result.transcription.utterances, and rename the word-level text field. The field mapping for your JSON parser is: utterances[].text to result.transcription.utterances[].text, utterances[].speaker to result.transcription.utterances[].speaker, utterances[].words[].text to result.transcription.utterances[].words[].word, and timing keys start and end remain at the same positions within each word object.
```json
// AssemblyAI response (excerpt)
{
"id": "transcript_id",
"status": "completed",
"text": "Call center transcription.",
"language_code": "en",
"audio_duration": 5.2,
"confidence": 0.97,
"utterances": [
{
"speaker": "A",
"text": "Call center transcription.",
"confidence": 0.97,
"words": [
{ "text": "Call", "start": 0.08, "end": 0.32, "confidence": 0.98, "speaker": "A" }
]
}
]
}
// Gladia response (equivalent)
{
"result": {
"transcription": {
"utterances": [
{
"text": "Call center transcription.",
"speaker": 0,
"words": [
{ "word": "Call", "start": 0.08, "end": 0.32 }
]
}
]
}
}
}
```
Streaming audio: switching to Gladia WebSockets
Real-time transcription runs on Solaria-1, which handles 100+ languages with true code-switching and delivers partials under 103ms. Solaria-3 is async-only for now.
Configuring the WebSocket connection
Our current live transcription API uses a two-step initialization. First, POST to /v2/live to receive a session token, then connect to the WebSocket endpoint using that token:
```python
import asyncio
import base64
import json
import requests
import websockets
GLADIA_API_KEY = "YOUR_GLADIA_API_KEY"
# Step 1: initialise the session.
# receive_partial_transcripts must be set explicitly.
# Without it the server sends final transcripts only and your
# partial handler never fires.
init_payload = {
"model": "solaria-1",
"encoding": "wav/pcm",
"sample_rate": 16000,
"bit_depth": 16,
"channels": 1,
"messages_config": {
"receive_partial_transcripts": True,
},
}
init_response = requests.post(
"https://api.gladia.io/v2/live",
headers={
"Content-Type": "application/json",
"x-gladia-key": GLADIA_API_KEY, # New header name
},
json=init_payload,
)
init_response.raise_for_status()
session = init_response.json()
ws_url = session["url"] # e.g. "wss://api.gladia.io/v2/live?token=<session_id>"
# Step 2: stream audio in, read messages out.
async def send_audio(ws, audio_source):
for chunk in audio_source:
await ws.send(json.dumps({
"type": "audio_chunk",
"data": {"chunk": base64.b64encode(chunk).decode("utf-8")},
}))
await asyncio.sleep(0.1)
# Signals end of stream. The server flushes remaining audio,
# then sends post_final_transcript.
await ws.send(json.dumps({"type": "stop_recording"}))
async def receive_messages(ws):
async for event in ws:
message = json.loads(event)
if message.get("type") == "transcript":
data = message["data"]
utterance = data["utterance"]
# is_final is the partial/final discriminator, not the type field.
if data["is_final"]:
commit_to_downstream(utterance) # CRM, LLM context, coaching
else:
update_live_display(utterance["text"]) # UI only, never persisted
elif message.get("type") == "post_final_transcript":
break # Session complete
async def stream_audio(audio_source):
async with websockets.connect(ws_url) as ws:
await asyncio.gather(
send_audio(ws, audio_source),
receive_messages(ws),
)
```
Input requirements for Gladia APIs
The real-time API requires a specific audio configuration. Mismatches here are the most common source of garbled output on migration day:
- Encoding: WAV/PCM
- Sample rate: 16,000 Hz (resample from 44.1kHz if needed before sending frames)
- Bit depth: 16-bit
- Channels: 1 (mono)
Handle partial vs. final transcripts
Each WebSocket message includes a type field with two possible values: "partial" or "final". Partials arrive during an active utterance for low-latency display updates. Final transcripts are emitted when the model detects silence above the endpointing threshold, at which point the utterance is fully committed. Process partials for UI display and hold final transcripts for downstream system writes (CRM entries, LLM context, coaching scores). Never write a partial to a database record without overwriting it with the final.
Bridging feature gaps for migration
Mapping AssemblyAI diarization logic
Map AssemblyAI's speaker_labels: true to our diarization: true parameter. Our diarization feature is powered by pyannoteAI's Precision-2 model and is strictly available in async workflows only. Do not request diarization on a WebSocket connection. If your real-time pipeline requires speaker attribution, buffer the audio during the live session, then submit it to the async API with diarization: true immediately after the call ends for post-call speaker labeling.
```json
{
"audio_url": "https://your-bucket.s3.amazonaws.com/call.wav",
"diarization": true,
"diarization_config": {
"number_of_speakers": 2,
"min_speakers": 1,
"max_speakers": 5
}
}
```
Mapping PII redaction logic
The PII redaction feature must be explicitly configured on every request, not just account-level setup. It is off by default on every plan and does not run automatically. When explicitly enabled via pii_redaction: true, detected entities such as names, phone numbers, and emails are replaced with placeholder tokens directly in the transcript output.
If you're migrating regulated audio (healthcare, financial services), verify your compliance posture and data residency configuration before routing production traffic. On Growth and Enterprise plans, customer audio is never used to retrain our models by default, with no opt-out action required.
Mapping summarization and sentiment
The summarization runs as an optional feature in the same API call when summarization: true is included in the request body, and is priced into the base rate on Starter and Growth plans with no separate metering. AssemblyAI's LLM Gateway operates at a separate LLM layer billed as a token-based product on top of transcription costs. For LLM-driven enrichment beyond summarization, the Audio-to-LLM pipeline routes structured transcripts to any model, or you can bring your own.
Our sentiment analysis is text-based inference applied to the transcript. It is not acoustic emotion detection and does not analyze vocal characteristics in the raw audio waveform.
Configuring custom word lists
AssemblyAI's word_boost maps to two separate mechanisms on our side, both available via the custom vocabulary docs. Use custom vocabulary for terms that are phonetically unusual (product names, acronyms, brand terms). Use custom spelling for terms the model transcribes but misspells. Start with an intensity of 0.4 (a boost strength parameter ranging from 0 to 1) and test each term individually, because higher intensity values can cause false positives where phonetically similar common words get incorrectly replaced.
Benchmarking against your audio data
Verify WER performance on target audio
Measure word error rate on your actual production audio, not on benchmark datasets that may not reflect your speaker demographics, background noise levels, or domain vocabulary. If your audio is primarily English, French, German, Spanish, or Italian business recordings, Solaria-3 is the model to test first. It achieves 6.4% WER on Earnings22 financial calls and 33.9% on Switchboard conversational audio, ranking #1 against AssemblyAI, ElevenLabs, Deepgram, Mistral, and Speechmatics. For languages outside that five-language set or for real-time streaming, Solaria-1 is the correct model.
Verify multilingual transcription performance
If your user base spans multiple languages or includes speakers who switch mid-conversation, test code-switching detection explicitly with multilingual audio samples. Enable it by setting "enable_code_switching": true in the request body.
Validate throughput under peak load
Run a load test mirroring your 95th-percentile peak concurrent session count before flipping the feature flag to 100%. We've validated the infrastructure at 800 concurrent sessions for a fintech customer and at over 1 million calls per week for Aircall. If you hit rate limit errors during your load test, contact us directly via Slack and we'll adjust your limits before cutover day.
Managing your cutover
Using feature flags for safe cutover
Implement the cutover as a graduated traffic shift using a feature flag rather than a hard cutover. A typical safe ramp schedule:
- Start with a small percentage of traffic and monitor error rates and WER divergence closely.
- Gradually increase the percentage over several days, expanding to more audio types and languages.
- Continue ramping up and increase traffic further and hold at that level until throughput validates at near-production load.
- Move to full traffic once all anomaly thresholds are clear.
Monitor HTTP 5xx error rates against a threshold appropriate to your production environment, WER divergence on your test set compared to your AssemblyAI baseline, and p99 latency compared to your current baseline. Set thresholds appropriate to your production environment and requirements. If any threshold triggers, flip the flag back to AssemblyAI and investigate. The abstraction layer built in the pre-migration checklist makes this a one-variable operation.
Monitor Gladia API status and errors
Monitor integration health against our public status page during and after cutover. Set up alerts on HTTP 4xx and 5xx response rates alongside your normal application error dashboards. Standard retry logic with exponential backoff handles transient errors. For persistent errors, your circuit breaker should automatically reroute traffic to AssemblyAI until the primary recovers.
Comparing AssemblyAI and Gladia costs
The TCO difference becomes meaningful at scale specifically because of the add-on pricing model. The table below models three volume tiers with diarization, sentiment analysis, entity detection, and summarization enabled on both platforms. AssemblyAI figures sum the base Universal-2 rate ($0.15/hr) with published add-on rates for diarization, sentiment, entity detection, and summarization per their public pricing, totaling approximately $0.30/hr. Our Growth plan pricing uses the lowest available rate at volume.
Table 2: TCO comparison (AssemblyAI vs. Gladia) with diarization, sentiment, entities, and summarization enabled
| Monthly volume (hours) |
AssemblyAI Universal-2 tier est. cost |
Gladia Growth est. cost (all-inclusive at $0.20/hr) |
Monthly savings |
| 1,000 hours |
$300 |
$200 |
$100 |
| 5,000 hours |
$1,500 |
$1,000 |
$500 |
| 10,000 hours |
$3,000 |
$2,000 |
$1,000 |
The table above is based on AssemblyAI's Universal-2 base rate ($0.15/hr) plus published add-ons: diarization (+$0.02/hr), sentiment (+$0.02/hr), entity detection (+$0.08/hr), summarization (+$0.03/hr) (legacy add-on: AssemblyAI now directs summarization use cases to LLM Gateway)= $0.30/hr. AssemblyAI's current flagship, Universal-3.5 Pro, carries a $0.21/hr base rate, but the same add-ons stack on top. The equivalent four-feature stack (diarization, sentiment, entity detection, summarization) runs $0.36/hr, which would widen the gap in Table 2 if substituted for Universal-2.
Per the pricing support documentation, Growth plan volume commitments bring rates down to as low as $0.20/hr for async, representing up to 67% savings compared to the Starter plan rate of $0.61/hr. These figures exclude LLM Gateway, which adds token-based costs on top of AssemblyAI's per-feature rates and would widen the gap further for teams using it for summarization or LLM enrichment.
Table 3: Decision matrix (AssemblyAI vs. Gladia)
| Use case |
AssemblyAI |
Gladia |
Best fit |
| English-only, US customer base |
Strong WER, mature docs |
Strong WER via Solaria-3 |
Either |
| European business audio (EN, FR, DE, ES, IT) |
Competitive but no dedicated model |
Solaria-3 ranks #1 on Earnings22 and Switchboard |
Gladia |
| Mid-conversation code-switching |
Limited on Universal-2. Native code-switching on Universal-3.5 Pro |
Native support via Solaria-1, including 42 languages not covered by other APIs |
Gladia |
| All-inclusive async pricing |
Add-ons billed separately |
Diarization, sentiment, NER in base rate |
Gladia |
| Structured outputs for downstream LLMs |
Transcription plus LLM Gateway, a separate token-billed LLM layer |
Audio-to-LLM pipeline, BYO model or integrated |
Depends on whether you want the LLM layer bundled or replaceable |
| Data sovereignty (EU-hosted) |
Limited |
EU-west region, GDPR, SOC 2 Type II, ISO 27001 |
Gladia |
| Pure-play infrastructure partner |
Builds an LLM layer that moves AssemblyAI into the application layer alongside its API customers |
Infrastructure-only, no competing applications |
Gladia for teams building voice products |
When you're ready, start with €50 in free credits on the Starter plan and build the abstraction layer outlined in the pre-migration checklist. Multiple customers independently report a working integration in production within a day, and the rollback path keeps your risk near zero.
FAQs
How long does migrating from AssemblyAI to Gladia take?
Multiple customers independently report going live in production in under a day for the initial async integration. Real-time WebSocket migration with audio format changes (resampling from 44.1kHz to 16kHz) typically requires additional configuration and testing work depending on your existing audio pipeline architecture.
How do you run AssemblyAI and Gladia in parallel during migration?
Route all transcription requests through a TranscriptProvider abstraction layer that calls both APIs and stores each vendor's transcript_id against the same source audio record in your database. Compare outputs at the utterance level using a diffing script before promoting Gladia results to downstream systems. This prevents duplicate writes to CRM entries or coaching records during the transition.
How should I handle historical AssemblyAI transcripts?
Export your historical transcripts via AssemblyAI's list and get endpoints, then archive them as JSON to your own cloud storage (S3 or GCS). Maintain a mapping table of AssemblyAI transcript_id values to Gladia transcript_id values for compliance audit trails. Do this before decommissioning your AssemblyAI integration to avoid lock-in on historical data.
What are the key parameter mappings between AssemblyAI and Gladia?
The critical mappings are: auth header (authorization to x-gladia-key), batch endpoint (POST /v2/transcript to POST /v2/pre-recorded), diarization (speaker_labels: true to diarization: true), and response structure (Gladia nests the utterances[] array one level deeper, at result.transcription.utterances[], and renames the word-level field from text to word. AssemblyAI's utterances[].words[].text maps to Gladia's result.transcription.utterances[].words[].word). PII redaction requires explicit enablement via pii_redaction: true on every request and is off by default on all plans.
Does Gladia diarization work in real-time?
No. Our speaker diarization powered by pyannoteAI's Precision-2 model is available in async (pre-recorded) workflows only. Real-time diarization would require sacrificing the full-context analysis that drives our lower diarization error rate compared to streaming alternatives. For real-time pipelines, buffer the audio and run async diarization immediately post-call for higher attribution accuracy.
What audio format does the Gladia WebSocket API require?
The real-time API requires WAV/PCM encoding, 16,000 Hz sample rate, 16-bit depth, and mono channel configuration. Mismatches on any of these settings produce garbled output. If your current pipeline captures at a higher sample rate, add a resampling step before sending WebSocket frames.
Key terms
STT (speech-to-text): The process and infrastructure layer that converts spoken audio into written text transcripts, either in real-time or batch mode.
PII (personally identifiable information): Data that can identify an individual, such as names, phone numbers, email addresses, social security numbers, or credit card details, which may require redaction in regulated environments.
WER (word error rate): The percentage of words in a transcript that differ from the reference ground truth. Lower is better. Measured per language and audio condition.
DER (diarization error rate): The percentage of audio incorrectly attributed to a speaker, including missed speech, false alarms, and speaker confusion errors.
Code-switching: Mid-conversation language changes where a speaker switches from one language to another, sometimes within a single sentence, requiring the model to handle the transition without breaking the session.
Abstraction layer: An interface in your codebase that decouples your application logic from a specific vendor's API, allowing you to swap providers without rewriting application code.
Circuit breaker: An architectural pattern that monitors API health and automatically reroutes traffic to a fallback provider when error rates or latency exceed a defined threshold.
TCO (total cost of ownership): The full cost of a vendor integration at production scale, including base API rates, per-feature add-ons, infrastructure overhead, and engineering maintenance time.