Skip to content
Back to skills

Deepgram Speech To Text

ASecurity

Start here for Deepgram speech-to-text. Use when a task says "speech to text", "STT", "transcribe", "transcription", "live transcription", "captions", "diarization", "nova-3", "Flux", "turn detection", or "end of turn". Picks the model family (Nova on /v1/listen for general transcription, Flux STT on /v2/listen for conversational audio with built-in turn detection), gets a first request working, and routes to the api, docs, recipes, starters, examples, and per-language SDK skills for everythi...

  • 2 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added November 7, 2026
ai-agentsjavascriptpythonrustgojavashellbashgitapidocumentation

Works with

  • cli
  • api
  • mcp

Security analysis

A100/100

Scanned November 7, 2026

npx -y skills add Rachit-Sharma08/coding-agent-skills --skill deepgram-speech-to-text --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Deepgram Speech To Text?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Deepgram Speech To Text
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/rachit-sharma08-deepgram-speech-to-text/badge)](https://www.skillsdirectory.com/skills/rachit-sharma08-deepgram-speech-to-text)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: deepgram-speech-to-text
description: >
  Start here for Deepgram speech-to-text. Use when a task says "speech to text", "STT",
  "transcribe", "transcription", "live transcription", "captions", "diarization", "nova-3",
  "Flux", "turn detection", or "end of turn". Picks the model family (Nova on /v1/listen for
  general transcription, Flux STT on /v2/listen for conversational audio with built-in turn
  detection), gets a first request working, and routes to the api, docs, recipes, starters,
  examples, and per-language SDK skills for everything else.
metadata:
  opencode/autoinvoke: true
---

# Deepgram Speech-to-Text

Deepgram transcribes audio with two model families on two endpoints. Pick the family first; the endpoint, the parameters, and the message shapes all follow from that choice. This skill gets a first request working and names the skill to open next. It does not repeat the full parameter reference; that lives in the `api` skill.

## Pick the model family first

| | Nova | Flux STT |
|---|---|---|
| Model names | `nova-3` (alias of `nova-3-general`), `nova-3-medical`, `nova-3-pharma` | `flux-general-en` (English), `flux-general-multi` (10 languages) |
| Endpoint | `/v1/listen`, REST and WebSocket | `/v2/listen`, WebSocket only |
| Output | A transcript stream | `TurnInfo` events carrying turn state and a transcript per turn |
| Turn detection | None built in; you use endpointing and your own logic | Built in: `StartOfTurn`, `EagerEndOfTurn`, `TurnResumed`, `EndOfTurn` |
| Formatting and analysis | `smart_format`, `diarize_model`, `summarize`, `sentiment`, `topics`, `intents`, redaction | Word timestamps, `numerals`, `redact` (`numbers` or `aggressive_numbers`), `keyterm`, `profanity_filter`, `mip_opt_out`, `tag`; no smart formatting, no diarization |
| Language | `language=<code>`, or `language=multi` for code-switching | The model name selects the language; `language_hint` biases `flux-general-multi` |

Decision rule:

- Choose Nova when you transcribe recorded files, generate captions or subtitles, need speaker labels, need summaries or sentiment, or stream audio where your own code decides when a phrase ends.
- Choose Flux STT when a person is talking to software and the software must know when they stopped: voice agents, phone assistants, IVR, agent assist. Flux has no prerecorded mode.
- Choose neither when you want Deepgram to also run the language model and speak the reply. That is the Voice Agent API, served from a separate host, `agent.deepgram.com`. Open the `voice-agent` skill.

## First request: Nova on a prerecorded file

Create a key at https://console.deepgram.com and export it as `DEEPGRAM_API_KEY`. The key goes in the `Authorization` header with the `Token` scheme. Always pass `model`; without it the API falls back to `base`.

```bash
curl -s -X POST 'https://api.deepgram.com/v1/listen?model=nova-3&smart_format=true' \
  -H "Authorization: Token $DEEPGRAM_API_KEY" \
  -H 'Content-Type: application/json' \
  -d '{"url":"https://dpgr.am/spacewalk.wav"}'
```

The transcript is at `results.channels[0].alternatives[0].transcript`. To send a local file instead, set `Content-Type` to the audio type (for example `audio/wav`) and pass `--data-binary @file.wav` with no JSON body.

Nova options you will reach for, all query parameters on `/v1/listen`:

- `smart_format=true` adds punctuation, paragraphs, and number formatting. It turns on `punctuate`, so do not set both.
- `diarize_model=latest` labels speakers. It replaces the deprecated `diarize=true`; a request that sets both is rejected. Streaming accepts `latest` and `v1` only.
- `language=multi` transcribes code-switched speech across the ten Nova-3 multilingual languages. Any single language code works too; the default is `en`.
- `keyterm=<term>` boosts names, product terms, and jargon. It is accepted on Nova-3 and Flux STT only; other models, Nova-2 for example, use `keywords` instead. Repeat the parameter once per term. The limit is 500 tokens across all keyterms in a request, and exceeding it fails the request with `Keyterm limit exceeded`; Deepgram's guidance is to stay well under it with the 20 to 50 terms that matter. Commas, semicolons, and `term:weight` are not rejected; the API treats the whole value as one literal term, so nothing you intended gets boosted.
- `summarize=v2`, `sentiment=true`, `topics=true`, and `intents=true` add audio intelligence. They run on prerecorded English audio only.
- Live streaming uses `wss://api.deepgram.com/v1/listen?model=nova-3`, the same `Authorization` header, and binary audio frames. Send `{"type":"KeepAlive"}` as a text frame every 3 to 5 seconds during silence, as the keep-alive page says; after 10 seconds without audio or `KeepAlive` the connection closes with `NET-0001`. Finish with `{"type":"CloseStream"}`. Regional hosts take the same path and the same key: `wss://api.eu.deepgram.com/v1/listen`, `wss://api.au.deepgram.com/v1/listen`, `wss://api.in.deepgram.com/v1/listen`.

## Flux STT: conversational audio with turn detection

Connect over WebSocket. Flux has no REST path.

```
wss://api.deepgram.com/v2/listen?model=flux-general-en&encoding=linear16&sample_rate=16000
```

Send the same `Authorization: Token` header. Audio must be mono. For raw audio (`linear16`, `linear32`, `mulaw`, `alaw`, `opus`, `ogg-opus`) `encoding` and `sample_rate` are required; for WAV, Ogg, or WebM containers omit both. Send 80 ms chunks. Flux STT has no `KeepAlive` message: WebSocket pings replace it, with a 60-second timeout. For in-region processing use `wss://api.eu.deepgram.com/v2/listen`, `wss://api.au.deepgram.com/v2/listen`, or `wss://api.in.deepgram.com/v2/listen` with the same key.

Two query parameters on `/v2/listen` to note:

- `redact` takes `numbers` or `aggressive_numbers`; any other value fails the handshake with 400. Each redacted span becomes a single `*`, not `[REDACTED]` or an entity tag.
- `profanity_filter=true` works on `/v2/listen`, `language=multi` included.

The server sends `Connected`, then a stream of `TurnInfo` messages. Each carries `event`, `turn_index`, `transcript`, `words` with timestamps, and `end_of_turn_confidence`. The `event` values:

- `Update`: roughly every 0.25 s of audio while a turn is in progress.
- `StartOfTurn`: the speaker began. Use it to interrupt your agent (barge-in).
- `EndOfTurn`: the speaker finished. Send the transcript to your language model. It carries `trigger`: `model`, `manual`, or `timeout`.
- `EagerEndOfTurn` and `TurnResumed`: emitted only when you set `eager_eot_threshold`. Start drafting a reply on the first; cancel it on the second. The `EndOfTurn` transcript matches the `EagerEndOfTurn` transcript exactly. Expect 50 to 70% more LLM calls in exchange for roughly 100 to 200 ms less end-to-end latency; start with `EndOfTurn` only.

Three query parameters tune turn detection, and all three can change mid-stream through the `Configure` message below:

| Parameter | Range | Default | Effect |
|---|---|---|---|
| `eot_threshold` | 0.5 to 1.0 | 0.7 | Confidence needed for `EndOfTurn`. `1.0` suppresses model detection. |
| `eager_eot_threshold` | 0.3 to 0.9 | unset | Enables `EagerEndOfTurn`. Lower values fire earlier with more false starts. Must be less than or equal to `eot_threshold`. |
| `eot_timeout_ms` | 500 to 60000 | 5000 | Silence that forces `EndOfTurn` regardless of confidence. |

Client control messages, each a JSON text frame:

- `{"type":"Configure","thresholds":{"eot_threshold":0.8},"keyterms":["Deepgram"],"numerals":true}` changes thresholds, keyterms, `language_hints`, or `numerals` without reconnecting.
  - Shape and atomicity: the turn-detection thresholds go under `thresholds`, as in the example; omitted fields keep their values. All fields in one message apply together or not at all: if one fails validation, none take effect.
  - `keyterms`: the array replaces the whole list and holds at most 100 plain terms (no `term:weight` syntax).
  - `language_hints`: `[]` clears the hints and reverts to auto-detect, while omitting the field or sending `null` keeps them.
  - `numerals`: starts from the `numerals` query parameter and applies to transcripts Flux STT sends after it processes the update, never to transcripts already sent. It must be a JSON boolean: the string `"true"` fails schema validation, Flux STT returns an `Error` with code `UNPARSABLE_CLIENT_MESSAGE`, and the connection closes.
  - The reply is `ConfigureSuccess`, which echoes the full active configuration including `numerals`, or `ConfigureFailure`, which carries `code` and `description` naming the rejected field and leaves the previous configuration in place.
- `{"type":"ForceEndTurn"}` (added August 28, 2026) ends the current turn on your own signal: a push-to-talk release, a DTMF tone, a send button. Flux STT emits `EndOfTurn` with `"trigger":"manual"`. With no active turn the message is ignored and a `Warning` with code `FORCE_END_TURN_NO_ACTIVE_TURN` comes back. Set `eot_threshold=1.0` to drive every turn yourself, keeping `eot_timeout_ms` high as a backstop (`"trigger":"timeout"`).
  - SDK methods: JS 5.9.0 `sendForceEndTurn`, Python 7.8.0 `send_force_end_turn`, Java 0.9.0 `sendForceEndTurn`, Go 3.8.0 `ForceEndTurn()`, Rust 0.10.1 `force_end_turn()`, .NET 7.1.0 `SendForceEndTurn()` on the concrete `FluxWebSocketClient`, not the interface.
- `{"type":"CloseStream"}` finishes decoding the audio already received, emits the matching `Update` messages, and closes the connection without a WebSocket close status code. It does not finalize the active turn: no `EndOfTurn` is emitted, so the last message is an interim `Update`. To end on a final transcript send `ForceEndTurn` first, then `CloseStream`; messages are processed in order, so the turn ends and then the connection closes. Sent the other way round, the `ForceEndTurn` has no effect.

For non-English or mixed-language calls use `model=flux-general-multi`, optionally with repeated `language_hint=<code>` parameters (for example `language_hint=en&language_hint=es`). Without hints the model detects the language itself. `TurnInfo` then includes `languages` and `languages_hinted`. `numerals` formats every number on `flux-general-en`; on `flux-general-multi` it formats English, Spanish, French, German, Russian, Portuguese, Italian, and Dutch, and leaves Hindi and Japanese numbers as spoken.

## Common mistakes

1. `Authorization: Bearer <api key>` returns 401. API keys use `Authorization: Token <key>`. `Bearer` is only for the short-lived JWT that `POST /v1/auth/grant` issues.
2. A 403 with `{"err_code":"INSUFFICIENT_PERMISSIONS","err_msg":"Project does not have access to the requested model."}` comes back both for a misspelled model name and for a real model the project cannot use. The body carries a `request_id`. Check the spelling before asking for access. `GET https://api.deepgram.com/v1/models` lists the public catalog; `GET /v1/projects/{project_id}/models` lists your project's models. There is no model named `nova-3-conversational`; conversational audio is Flux, `flux-general-en`. The public catalog does not list the Flux model names, so the Flux docs are the source for those.
3. Flux on `/v1/listen` does not work, and `model=flux` is not a valid value. Use `/v2/listen` with `flux-general-en` or `flux-general-multi`.
4. `language=en` or `language=multi` on Flux is wrong. The model name selects the language. `language_hint` is accepted only by `flux-general-multi` and returns 400 on any other model.
5. Setting `encoding` or `sample_rate` for containerized audio (WAV, Ogg, WebM) causes errors or garbled output. Omit both and let the container declare the format.
6. `ForceEndTurn` on `/v1/listen` returns an error; it exists only on Flux.
7. `smart_format`, `diarize`, and the intelligence parameters are not available on `/v2/listen`. Speaker labels and summaries are a Nova job.
8. A `KeepAlive` sent as a binary frame is mishandled. Send control messages as text frames and audio as binary frames.
9. `{"type":"Configure","features":{"numerals":true}}` is the `/v1/listen` form. Flux STT rejects the `features` nesting and closes the connection; on `/v2/listen` send `numerals` as a top-level field, `{"type":"Configure","numerals":true}`.

## Pricing

Deepgram bills speech-to-text per minute of audio. Figures change, so read them at https://deepgram.com/pricing rather than from any skill.

## Use a different skill when

- You need every parameter, response schema, or message field: `api` skill, file `references/listen.md`.
- You want the documentation page for a topic: `docs` skill. The pages this skill leans on are listed under Sources.
- You want a runnable app with a UI: `starters` skill (the `transcription`, `live-transcription`, and `flux` features).
- You want a one-feature snippet under 50 lines: `recipes` skill, https://github.com/deepgram/recipes.
- You are wiring Deepgram into Twilio, LiveKit, Pipecat, LangChain, or another platform: `examples` skill.
- You want language-idiomatic SDK code: install `deepgram-{js,python,java,go,rust,dotnet}-speech-to-text` for Nova and `deepgram-{lang}-conversational-stt` for Flux STT from the matching SDK repository (`npx skills add deepgram/deepgram-python-sdk`, and so on).
- You want mid-stream `numerals` through `Configure` from an SDK: the `deepgram-{lang}-conversational-stt` skills do not cover it, so take the message shape from the `Configure` bullet in this skill. The JavaScript SDK sends it from 5.13.0 (`socket.sendConfigure({type:"Configure", numerals:true})`), the Python SDK from 7.11.0 (`connection.send_configure(ListenV2Configure(numerals=True))`), and the Java SDK from 0.10.2 (`sendConfigure(ListenV2Configure.builder().numerals(true).build())`).
- You want mid-stream `numerals` on the Go 3.8.0, Rust 0.11.0, or .NET 7.1.1 SDK: their Configure types carry no `numerals` field, so send the raw JSON Configure message or set `numerals` on the connection URL.
- You want analysis and not just the transcript (`summarize`, `sentiment`, `topics`, `intents`, `detect_entities` on `/v1/listen`): `audio-intelligence` skill. For text you already have, `/v1/read` and the `text-intelligence` skill.
- You want text-to-speech or a full voice agent: the `text-to-speech` or `voice-agent` skill.
- You want a shell command rather than application code: `cli` skill.
- You want the docs queryable from your coding tool: `setup-mcp` skill.

## Sources

- Getting started: https://developers.deepgram.com/docs/stt/getting-started
- Nova prerecorded: https://developers.deepgram.com/docs/pre-recorded-audio
- Nova live streaming: https://developers.deepgram.com/docs/live-streaming-audio and https://developers.deepgram.com/docs/audio-keep-alive
- Models and languages: https://developers.deepgram.com/docs/models-languages-overview
- Multilingual code switching: https://developers.deepgram.com/docs/multilingual-code-switching
- Smart Format, diarization, keyterms: https://developers.deepgram.com/docs/smart-format, https://developers.deepgram.com/docs/diarization, https://developers.deepgram.com/docs/keyterm
- Audio intelligence: https://developers.deepgram.com/docs/audio-intelligence and https://developers.deepgram.com/docs/stt-intelligence-feature-overview
- Flux quickstart: https://developers.deepgram.com/docs/flux/quickstart
- Flux compared with Nova-3: https://developers.deepgram.com/docs/flux/flux-nova-3-comparison
- Nova-3 to Flux migration: https://developers.deepgram.com/docs/flux/nova-3-migration
- Flux state machine: https://developers.deepgram.com/docs/flux/state
- Flux STT turn-detection parameters (the threshold table): https://developers.deepgram.com/docs/flux/configuration
- Flux control messages: https://developers.deepgram.com/docs/flux/configure, https://developers.deepgram.com/docs/flux/force-end-turn, https://developers.deepgram.com/docs/flux/close-stream
- Flux STT feature matrix (profanity filter, redaction scope, control messages): https://developers.deepgram.com/docs/flux/feature-overview
- Profanity filter, including Flux STT `language=multi`: https://developers.deepgram.com/docs/profanity-filter
- Bring your own turn detection (`eot_threshold=1.0` plus `ForceEndTurn`): https://developers.deepgram.com/docs/flux/own-turn-detection
- Flux STT in a voice agent and eager end of turn (LLM call cost): https://developers.deepgram.com/docs/flux/agent and https://developers.deepgram.com/docs/flux/voice-agent-eager-eot
- Redaction, including the Flux STT `*` placeholder: https://developers.deepgram.com/docs/redaction
- Regional endpoints (EU, AU, India hosts for `/v1/listen` and `/v2/listen`): https://developers.deepgram.com/reference/regional-endpoints
- Numerals, including the Flux STT language list and mid-stream toggling: https://developers.deepgram.com/docs/numerals
- ForceEndTurn release note: https://developers.deepgram.com/changelog/2026/8/28
- Flux multilingual: https://developers.deepgram.com/docs/flux/language-prompting
- Authentication: https://developers.deepgram.com/guides/fundamentals/authenticating and https://developers.deepgram.com/guides/fundamentals/token-based-authentication
- Models endpoint: https://developers.deepgram.com/guides/fundamentals/model-metadata
- Error codes: https://developers.deepgram.com/docs/errors
- Voice Agent host (agent.deepgram.com): https://developers.deepgram.com/docs/build-a-voice-agent
- API reference: https://developers.deepgram.com/reference/speech-to-text/listen-pre-recorded, https://developers.deepgram.com/reference/speech-to-text/listen-streaming, https://developers.deepgram.com/reference/speech-to-text/listen-flux

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.