All posts
Speech to Text

Deepgram API: Your First Nova-3 Transcript in Minutes

A working Deepgram API request for Nova-3 on each::labs, when to pick standard or Pro, the options that change your transcript, and three pipelines that put it to work: subtitles, dubbing and a searchable archive.

By Eftal Yurtseven · Nov 11, 2026 · 9 min read

Deepgram API: Your First Nova-3 Transcript in Minutes

Getting words out of audio isn't the hard part any more. Getting the right words, split by the right speaker, stamped with times you can actually cut video against: that's where a weekend project turns into a week. The Deepgram API is a strong answer to that problem, and Nova-3 is the model doing the listening. The catch is that a good transcript is only useful if it lands in a pipeline that does something with it.

This guide is the practical version. You'll send your first request to Deepgram Nova-3 on each::labs, pick between the standard and Pro endpoints without guessing, set the handful of options that change your output, and then wire the transcript into three workflows that ship: burned-in subtitles, a dubbed and lipsynced cut, and a video archive you can search by what people said.

If you want the background first (keyterm prompting, code-switching, redaction), our earlier post on nine things to know about Deepgram Nova-3 covers the model itself. This one is about building with it.

Two Nova-3 Endpoints, One Decision

The Deepgram family on each::labs gives you two ways into Nova-3, and they aren't a quality ladder. Both run the same speech recognition. The difference is how much the API does to the transcript after it hears it.

Nova-3 Speech to Text is the lean one. It takes a media URL and gives you back the transcript with word-level timestamps, speaker diarization and automatic language detection. Its options are short on purpose: language, diarization, multichannel, smart formatting, punctuation, and a model switch between nova-3 and nova-2. If your job is "turn this audio into accurate, timed text", that's the whole job, and this is the endpoint.

Nova-3 Speech to Text Pro is the one that reads the transcript back to you. On top of everything in standard, it adds summaries, topic detection, intent detection, sentiment, entity extraction, utterance and paragraph segmentation, acoustic search, redaction, find-and-replace, filler-word control, numeral and measurement conversion, dictation mode and, crucially, keyterms.

Here's the rule I'd use. Pick standard when the transcript is the product: subtitles, captions, a text file for an editor. Pick Pro when the transcript is raw material for a decision: a support call you need to classify, a meeting you need summarized, a podcast you want to index by topic. And pick Pro the moment your audio is full of words a general model has never heard, because keyterm boosting lives only there.

The first request is short. Getting it right is the whole trick.
The first request is short. Getting it right is the whole trick.

Your First Deepgram API Request on each::labs

Every model on each::labs runs through the same prediction API, so this is the same call you'd make for an image or video model. You create a prediction with the model slug and an input object, get back a prediction ID, then fetch the result once it finishes. Authentication is your each::labs API key in a header.

The only required input is media_url, a publicly reachable link to the file (or one you've uploaded to each::labs). The schema lists mp3, wav, m4a, flac, ogg, webm and mp4 among the accepted formats, so you can usually point it straight at a video file without extracting the audio first.

curl -X POST https://api.eachlabs.ai/v1/prediction/ \
  -H "X-API-Key: $EACHLABS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "deepgram-nova-3-speech-to-text",
    "version": "0.0.1",
    "input": {
      "media_url": "https://example.com/interview.mp4",
      "language_code": "auto",
      "diarize": true,
      "smart_format": true,
      "punctuate": true
    }
  }'

The response carries a predictionID. Poll it until the status is success, and the transcript is in output:

curl https://api.eachlabs.ai/v1/prediction/PREDICTION_ID \
  -H "X-API-Key: $EACHLABS_API_KEY"

Polling is fine for a script. For anything running in production, pass a webhook_url (and optionally a webhook_secret to sign the callback) in the create request, and let each::labs call you when the transcript is ready.

Switching to Pro is a one-line change: set "model": "deepgram-nova-3-speech-to-text-pro" and add whichever Pro options you want. The model page's API tab shows the full schema for both, with every field, type and default.

Read the whole response once. Then build on what is really there.
Read the whole response once. Then build on what is really there.

Read the Response Before You Build On It

Before you write a single line of downstream code, run one real file and read the whole output. Not the transcript string. The whole object.

With diarization on, each word in the response carries a speaker ID and a speaker confidence score alongside its timestamps. That word-level timing is the most valuable thing in the payload, more valuable than the transcript itself, because it's what lets you cut, caption and jump to a moment. Treat the flat transcript as a convenience and the word list as the source of truth.

Pro adds structure on top. With utterances on (the Pro default), you get results.utterances: segments with start and end times, speaker, channel and transcript, split wherever there's a pause longer than utt_split seconds (0.8 by default). With paragraphs on, you get paragraphs broken into sentences with speaker and word counts. Summaries come back in results.summary, topics in results.topics, intents in results.intents, sentiment in results.sentiments.

My advice: save that first response as a fixture in your repo. Every parser you write later should be tested against real output, not against what you assume the output looks like.

The Options That Actually Change Your Transcript

Most of the schema you can leave on defaults. A few fields change the result enough that you should set them on purpose.

language_code defaults to auto, which detects the language for you. That's the right call for a single-language file in an unknown language. If speakers switch languages mid-conversation, set it to multi, which the schema describes as multilingual audio with up to 10 languages. And if you already know the language, say so: an explicit code like es or tr takes a guess out of the pipeline.

diarize is on by default in both endpoints. Keep it on for interviews, meetings and calls. Turn it off for a single narrator, where speaker labels add nothing.

multichannel is off by default and is the most underused switch in the schema. If your recording puts each speaker on their own channel (stereo call recordings are the classic case), turn it on and every channel is transcribed independently, up to five. That's cleaner than asking diarization to separate voices that were never mixed in the first place.

smart_format and punctuate are both on by default and should usually stay that way. Smart formatting turns spoken phone numbers, emails and dates into the written form a reader expects.

keyterm (Pro only) is a comma-separated list of words to boost: product names, jargon, acronyms, the surname of the CEO who talks on every earnings call. Deepgram's own Nova-3 documentation frames this as vocabulary adaptation without retraining, and its keyterm guide recommends focusing on your most important 20 to 50 terms rather than dumping a dictionary. Skip common words; they're rarely misheard and they dilute the boost.

Listen for the words that matter, not every word in the room.
Listen for the words that matter, not every word in the room.

Turn Pro On Only for What You'll Use

Here's the trap with the Pro endpoint: a lot of its analysis is on by default. Summaries, topics, intents, sentiment, entity detection, utterances, paragraphs and filler words all default to true. That's generous for exploration and noisy for production. If you never read the sentiment field, switch it off and keep your payloads lean.

A few Pro options earn their place in most pipelines. filler_words is on by default, which is great for conversation analysis and bad for subtitles nobody wants to read ("um, so, uh"). Set it to false for captions. redact takes pci (card numbers), pii, phi or numbers and scrubs those from the transcript, which matters if transcripts get stored or shown to people who shouldn't see an account number read aloud. replace takes old:new pairs, handy for a brand name that keeps getting spelled the generic way.

custom_topic and custom_intent let you name the labels you care about ("refund request, cancellation, shipping delay"). Set the matching mode to strict and you get only your labels back, which is what a dashboard wants. Leave it on extended and the model also proposes its own, which is what a researcher wants.

Then there's search: up to 25 comma-separated terms matched acoustically against the audio, with hit timestamps and confidence in the response. It finds a word by how it sounds, not by how the transcript spelled it, which is exactly the property you want when the transcript might have spelled it wrong.

{
  "model": "deepgram-nova-3-speech-to-text-pro",
  "version": "0.0.1",
  "input": {
    "media_url": "https://example.com/support-call.wav",
    "language_code": "en",
    "multichannel": true,
    "keyterm": "each::labs,Nova-3,webhook",
    "redact": "pci",
    "custom_intent": "cancel subscription,report bug,request refund",
    "custom_intent_mode": "strict",
    "sentiment": false,
    "filler_words": false
  }
}

Workflow One: Subtitles From a Single Upload

The shortest useful pipeline is transcript to captions. Send your video to standard Nova-3, take the word timings, and group them into caption lines: break on a pause, a speaker change, or a character limit that fits your frame. Write that out as an SRT file, host it, and hand both files to Subtitle Burn In, which takes the source video plus a subtitle_file_url (or plain subtitle_text) and lets you set font, size and position.

Two settings matter more than the rest here. Leave smart formatting on so numbers read like numbers on screen. And if you're on Pro for the keyterms, turn filler words off, or your captions will transcribe every hesitation faithfully.

The part people skip: your own grouping logic is where captions look professional or amateur. Short lines, breaks at natural pauses, never a caption that straddles two speakers. Nova-3 gives you the timing precision to do it properly. Use it.

A good dub hands the voice over without losing the speaker.
A good dub hands the voice over without losing the speaker.

Workflow Two: Dub It, Then Sync the Lips

Dubbing is a chain, and transcription is link one. Run the source video through Nova-3 with diarization on, so you know who says what and when. Translate each utterance with whatever text step you prefer, keeping the timing and speaker labels attached. Then voice each line with a text-to-speech model such as MiniMax Speech 2.8 HD, picking a different voice per speaker ID and using its speed control to fit each line into the slot the original occupied.

Stitch the dubbed lines into one audio track and send it with the original footage to Sync 3 Lipsync, which takes a video_url and an audio_url and moves the mouths to match. The diarization you turned on in step one is what keeps this from collapsing into one voice reading everyone's lines.

Our longer guide to the AI dubbing and lipsync API for video localization goes deeper on the translation and timing step. For more voices to try in the middle, browse the text-to-voice models.

This is the one most teams don't build and should. Every webinar, interview, product demo and all-hands you've ever recorded is sitting in storage, unsearchable, because nobody remembers which video had the bit about the migration plan.

Run each file through Nova-3 Pro once. Store the utterances (with start and end times) in a search index, alongside the summary, topics and entities. Now a search for "migration plan" returns not just the right video but the right timestamp, and the result card can show the summary instead of a filename. Entities give you an "every recording that mentions this customer" view without anyone tagging anything.

For terms that must not be missed (a product codename, a competitor's name in a sales call), add them to the search option at ingest. Acoustic hits come back with timestamps, so you can flag those moments even where the transcript spelled the word differently.

Once a chain like this works, don't keep it as a script on someone's laptop. Build it as a flow in each::labs AI Flows, so transcription, formatting and the next model run as one pipeline you can trigger with a single call.

Frequently Asked Questions

How do I call the Deepgram API through each::labs?

Send a POST to the each::labs prediction endpoint with "model": "deepgram-nova-3-speech-to-text" (or the Pro slug) and an input object containing at least media_url. You get a prediction ID back, then fetch the result or receive it on a webhook.

Should I use Nova-3 standard or Pro?

Ask what happens to the text next. If a human reads it as captions or a transcript, standard has everything you need. If software reads it to classify, summarize, redact or search, Pro saves you a second model call. Pro is also the only one with keyterm boosting, so domain-heavy audio points you there regardless.

Can Nova-3 handle audio that mixes languages?

Yes. Set language_code to multi, which the each::labs schema describes as covering multilingual audio with up to 10 languages. For a file that's entirely in one language, auto detection or an explicit code is the better fit.

Does Nova-3 accept video files directly?

It does. The media_url field accepts mp4 and webm alongside audio formats like mp3, wav, m4a, flac and ogg, so you can point it at the same video you'll later caption or dub.

Start with what you need.

Scale when you’re ready.