Migrating Speech-to-Text from Deepgram to Sarvam
Migrating Speech-to-Text from Deepgram to Sarvam
This guide covers migrating Deepgram speech-to-text (transcription) API calls to Sarvam. If you’re building a full voice agent rather than transcribing audio directly, start from the LiveKit or Pipecat voice agent build guides instead: they aren’t a 1:1 API swap and aren’t covered here.
In short: swap model for model, read the transcript from a flatter response shape, and pick the right Sarvam API for the job: REST for short synchronous requests, Batch for diarized or very long audio, and WebSocket for real-time streaming.
Quick start
Base URL and auth header change the same way for every Deepgram migration, so they’re folded in here rather than in a separate page:
With that, replace the transcription call:
Before (Deepgram)
After (Sarvam)
The rest of this page covers the full endpoint and parameter mapping, diarization via the Batch API, streaming, and common mistakes.
Endpoint map
The tables below aren’t a checklist to apply field-by-field: Quick Start above already shows the whole call swapped over in one go. Use these tables as a reference for what changed and why, not as a sequence of edits to make yourself.
Parameter concept map
Deepgram’s response also supports optional sentiment, topic, intent, and summary detection, and content redaction, layered on top of the transcript. Sarvam’s Speech-to-Text focuses on transcription accuracy, output modes (transcribe, translate, verbatim, translit, codemix), and Indian-language coverage; if you need that kind of downstream text analysis, run Sarvam’s transcript through Chat Completion as a second step.
Diarization and long-form audio
Deepgram enables diarization on the same synchronous call via diarize_model; Sarvam’s Batch API handles both diarization and long-form audio instead:
See the Batch API guide for webhook setup and its Speaker Diarization section for the current per-job speaker limit.
Streaming
Deepgram also offers Flux (flux-general-en/flux-general-multi), a separate GET /v2/listen endpoint purpose-built for conversational turn detection, with its own tuning params (eager_eot_threshold, eot_threshold). Sarvam’s turn-detection features (high_vad_sensitivity, vad_signals) live in the same WebSocket API used for regular transcription, so there’s no separate model or endpoint to choose between for conversational use.
What’s different by design
- One current model, not a version-and-domain matrix. Deepgram’s
nova-3,nova-2-medical,nova-2-finance, and similar domain-specific variants become a singlesaaras:v3, used the same way across REST, Batch, and Streaming. - A flatter response shape.
response.transcriptreads directly, rather than walkingresults.channels[0].alternatives[0].transcript. - Diarization and long-form audio share one workflow. The Batch API handles speaker diarization, files up to 2 hours, and multiple files per job in a single job-based flow, with the same
with_diarization/num_speakersparameters either way. - Flexible output modes on one model.
saaras:v3supportstranscribe,translate,verbatim,translit, andcodemixmodes on the same endpoint. - Indian language depth is Sarvam’s specific strength. Saaras v3 covers 22 Indian languages, including Assamese, Konkani, Kashmiri, Sindhi, Sanskrit, Santali, Manipuri, Bodo, Maithili, and Dogri, with native handling for code-mixed speech like Hinglish.
Full example
A small wrapper function, before and after, showing the complete set of changes together:
Before (Deepgram)
After (Sarvam)
Common mistakes
Passing an open file handle instead of bytes
Sarvam’s file parameter takes the open file object directly (file=open(path, "rb")), unlike Deepgram’s request, which expects the bytes already read out (request=f.read()). Passing a file handle where Deepgram’s SDK expects bytes, or vice versa, is the most common porting slip.
Expecting diarization on the fast REST endpoint
Deepgram enables diarization on the same synchronous call via diarize_model. Sarvam’s with_diarization is a Batch API parameter instead, so diarized requests need to go through the Batch workflow even for a short file.
Walking the nested channels/alternatives path out of habit
Sarvam’s response is flat: response.transcript, not response.results.channels[0].alternatives[0].transcript. Update any code that destructures the Deepgram response shape.
Sending Batch parameters as top-level fields
Calling the Batch endpoints directly over HTTP (rather than through the SDK) requires nesting parameters under job_parameters, e.g. {"job_parameters": {"model": "saaras:v3", ...}}. A flat body modeled on Deepgram’s request shape won’t be picked up.
See also
- Migration overview: base URL, auth, and SDK client changes
- Which Speech-to-Text API to Use
- Batch API
- Streaming API
- Speaker Diarization
- Errors & Troubleshooting