- name
- api
- description
- Deepgram API reference for speech-to-text, text-to-speech, voice agents, audio intelligence, and account management. Use whenever building with Deepgram APIs — REST or WebSocket. Covers authentication, all endpoints, query parameters, request/response schemas, and WebSocket message formats. Reference files are organized by domain: listen (STT — Nova and Flux STT), speak (TTS — Aura and Flux TTS), agent (voice agents), read (text/audio intelligence), models, projects, auth, and self-hosted.
# Deepgram API
Build with Deepgram's speech-to-text, text-to-speech, voice agent, and audio intelligence APIs.
> **"Flux" names two separate products.** **Flux STT** is conversational speech-to-text on `/v2/listen` (`model=flux-general-en`). **Flux TTS** is turn-based speech synthesis on `/v2/speak` (`model=flux-{voice}-{language}`). They share a name and a design philosophy — turn-aware, built for voice agents — but they are different endpoints with different models, params, and messages. When a request just says "Flux", check whether it is about transcribing audio or producing it.
## Getting Started
All API requests require authentication via API key or JWT:
- **API Key**: `Authorization: Token <API_KEY>`
- **JWT**: `Authorization: Bearer <JWT>`
Base servers:
- REST & STT/TTS WebSocket: `https://api.deepgram.com`
- Voice Agent WebSocket **and `GET /v1/agent/settings/think/models`**: `https://agent.deepgram.com`
`GET /v1/agent/settings/think/models` lives on the `agent.` host too, not on `api.`: it
returns 404 on `api.deepgram.com` and 200 on `agent.deepgram.com`. Everything else REST
stays on `api.deepgram.com`.
### Regional endpoints
To keep processing inside a geography, swap the host. Same API keys, same paths, same SDKs —
only the base URL changes. Requests are never routed out of region: if the region is
unavailable they fail rather than fall back.
| Region | Host |
|---|---|
| EU | `api.eu.deepgram.com` |
| Australia | `api.au.deepgram.com` |
| India | `api.in.deepgram.com` |
**The data plane is regional; the Projects management API is not.** On all three regional hosts:
| Endpoint | Regional |
|---|---|
| `POST /v1/listen`, `wss://…/v1/listen` | Yes |
| `wss://…/v2/listen` | Yes |
| `POST /v1/speak`, `wss://…/v1/speak` | Yes |
| `POST /v2/speak`, `wss://…/v2/speak` | Yes |
| `POST /v1/read` | Yes |
| `wss://…/v1/agent/converse` | Yes |
| `GET /v1/models` | Yes |
| `POST /v1/auth/grant` | Yes |
| `/v1/projects/*` (keys, members, usage, billing) | **No — 404** |
Two host rules that catch people out:
1. **Voice Agent moves onto the `api.` host regionally.** There is no `agent.eu.deepgram.com`
(the name does not resolve). Use `wss://api.eu.deepgram.com/v1/agent/converse`. `GET /v1/agent/settings/think/models` moves with it. Globally it stays on `agent.deepgram.com`.
2. **Keep management calls on `api.deepgram.com`.** Point a client's management calls at a
regional host and `/v1/projects` returns 404, so split the base URL by call type if your
app both transcribes and manages keys.
Whisper models are not served in any of the three regions — use Nova or Flux STT models there.
For Deepgram Dedicated and self-hosted hosts, see
[Custom Endpoints](https://developers.deepgram.com/reference/custom-endpoints);
for the full per-region feature matrix and SDK snippets, see
[Regional Endpoints](https://developers.deepgram.com/reference/regional-endpoints).
## How Deepgram's APIs Fit Together
```
┌──────────────────────────────┐
│ api.deepgram.com │
└──────────────────────────────┘
│
┌───────────┬───────────┬─────┴─────┬───────────┬───────────┐
▼ ▼ ▼ ▼ ▼ ▼
/v1/listen /v2/listen /v1/speak /v2/speak /v1/read /v1/projects/*
Nova — STT Flux — STT Aura — TTS Flux — TTS Text AI Management
REST + WSS WSS only REST + WSS REST + WSS REST only REST only
┌──────────────────────────────┐
│ agent.deepgram.com │
└──────────────────────────────┘
│
▼
/v1/agent/converse
WebSocket only
audio ──▶ STT ──▶ LLM ──▶ TTS ──▶ audio
(Deepgram orchestrates the full pipeline)
```
## Which API Should I Use?
```
Audio → text (transcription)?
├─ General-purpose transcription (captions, batch, call logs, live streams with custom turn logic)
│ └─ Nova models via /v1/listen
│ ├─ Pre-recorded file → REST POST https://api.deepgram.com/v1/listen?model=nova-3
│ └─ Live stream → WSS wss://api.deepgram.com/v1/listen?model=nova-3
│
└─ Conversational audio / voice-agent-style turn detection
└─ Flux STT models via /v2/listen
└─ Live stream → WSS wss://api.deepgram.com/v2/listen?model=flux-general-en
Text → audio (speech synthesis)?
├─ General-purpose TTS (broadest voice catalog, compressed/containerized audio)
│ └─ Aura models via /v1/speak
│ ├─ One-shot → REST POST https://api.deepgram.com/v1/speak?model=aura-2-thalia-en
│ └─ Low-latency stream → WSS wss://api.deepgram.com/v1/speak?model=aura-2-thalia-en
│
└─ Voice-agent TTS (turn-based lifecycle, barge-in, cross-turn consistency)
└─ Flux TTS models via /v2/speak — model is REQUIRED, and must be flux-*
├─ Pre-render a block → REST POST https://api.deepgram.com/v2/speak?model=flux-alexis-en
└─ Live conversation → WSS wss://api.deepgram.com/v2/speak?model=flux-alexis-en
Full conversational voice agent (audio in, audio out)?
└─ WSS wss://agent.deepgram.com/v1/agent/converse
Deepgram handles STT + your configured LLM + TTS internally
Analyze text for insights?
└─ REST POST /v1/read
(summaries, sentiment, topics, intents)
```
## Speech-to-Text: Nova (`/v1/listen`) vs Flux STT (`/v2/listen`)
Both model families are actively maintained and industry-leading. They solve different problems — pick the one that matches your use case.
| | Nova (`/v1/listen`) | Flux STT (`/v2/listen`) |
|---|---|---|
| Endpoint | `/v1/listen` | `/v2/listen` |
| Available models | `nova-3` (also `nova-3-medical`, `nova-3-pharma`), `nova-2`, `nova`, `enhanced`, `base` | `flux-general-en`, `flux-general-multi` |
| Best for | General transcription — captions, subtitles, call logs, batch | Conversational audio — voice agents, interactive assistants, turn-taking UIs |
| Output | Continuous transcript stream | Structured turn events + transcripts (built-in turn state machine) |
| Turn detection | Manual (`utterance_end_ms`, VAD events) | Built-in (EOT, eager-EOT, turn_index) |
| Transports | REST + WebSocket | WebSocket only |
| Intelligence overlays | Yes — `summarize`, `sentiment`, `topics`, `intents`, `diarize_model`, `redact`, etc. | No — smaller focused param set; no `smart_format` / `diarize_model` / `punctuate` |
| Mid-session reconfig | No (reconnect to change) | Yes (`Configure` message updates EOT thresholds, keyterms, language hints, and `numerals` live) |
**Pick Nova (`/v1/listen`, `model=nova-3`) when:**
- Generating captions, subtitles, or transcripts for recorded media
- Running batch transcription over files (REST)
- You need analytics overlays (`summarize`, `sentiment`, `topics`, `intents`, `diarize_model`, `redact`)
- You want WebSocket streaming with your own turn-detection logic
**Pick Flux STT (`/v2/listen`, `model=flux-general-en`) when:**
- Building an interactive voice agent or assistant
- You want end-of-turn detection handled for you
- You need low-latency turn signals and barge-in support
- You want to update EOT thresholds, keyterms, language hints, or `numerals` mid-session without reconnecting
Migrating from Nova 3 to Flux STT? See the official [Nova 3 → Flux migration guide](https://developers.deepgram.com/docs/flux/nova-3-migration).
## Text-to-Speech: Aura (`/v1/speak`) vs Flux TTS (`/v2/speak`)
Both TTS families are actively maintained. `/v2/speak` is a **new endpoint, not a replacement** — `/v1/speak` is unchanged, and there is no aliasing, redirect, or deprecation. The families do not overlap: Aura voices are served only on `/v1/speak`, Flux TTS voices only on `/v2/speak`.
| | Aura (`/v1/speak`) | Flux TTS (`/v2/speak`) |
|---|---|---|
| Endpoint | `/v1/speak` | `/v2/speak` |
| Models | `aura-2-*` (en, es, de, nl, fr, it, ja), `aura-*` | `flux-{voice}-{language}`, e.g. `flux-alexis-en` — English at launch |
| `model` param | Optional (defaults to `aura-asteria-en`) | **Required**; an `aura-*` string is rejected |
| Best for | Broadest voice catalog, multilingual, compressed audio, one-shot synthesis | Voice agents — streaming LLM output, barge-in, multi-turn conversations |
| Mental model | Text buffer → audio stream | Streaming-first, turn-based conversation |
| Turn lifecycle | None | `SpeechStarted` → audio → `Flushed` → `SpeechMetadata` per turn (server-assigned `speech_id`) |
| Cross-turn context | None (reconnect to reset) | Prosody persists across turns automatically — no API surface |
| Transports | REST + WebSocket | REST (batch) + WebSocket (streaming) |
| Streaming encodings | `linear16`, `mulaw`, `alaw` | `linear16`, `mulaw`, `alaw` — raw audio only |
| Batch encodings | `mp3`, `opus`, `flac`, `aac`, `linear16`, `mulaw`, `alaw` + `container` / `bit_rate` | Same — but batch-only; the socket rejects them |
| Interruption | `Clear` discards the buffer, no feedback | `Interrupt` → `SpeechInterrupted` with `text_spoken` / `text_remaining` |
| Mid-stream reconfig | No (fixed at connection) | Yes — `Configure` updates `speed` only |
| `speed` | `0.7` to `1.5`, Aura-2, English and Spanish only | `0.5` to `1.5` in `0.05` steps; capped at `1.15` when the text carries a pause marker (`PAUSE_SPEED_CAP_EXCEEDED` above that); see Inline controls for the pronunciation rule |
| `expressivity` | Not supported | `-2`…`2`, default `0` (beta; fixed for the connection) |
| Inline controls | Pronunciation `\{"word":"...","pronounce":"<IPA>"\}` (GA on Aura-2, English and Spanish, input up to 2000 characters, combinable with `speed`); no pause control | Pronunciation (Early Access, both transports) only with `speed` exactly `1.0`: `CONTROL_COMBINATION_INVALID` on batch, `DATA-0002` on the socket; pause `\{pause:500ms\}` on batch only, 500 to 3000 ms in 100 ms steps, at most 8 per request |
| Voice Agent `provider.version` | `v1` (the default when a provider is specified) | `v2` (required) |
**Pick Aura (`/v1/speak`) when:**
- You need a language other than English, or a specific Aura voice
- You need compressed output (`mp3`, `opus`, `flac`, `aac`) inside a Voice Agent, where Flux TTS returns `INVALID_SETTINGS`; on batch REST both families serve those encodings
- You're already on Aura and nothing in Flux TTS is pulling you over — v1 is unchanged
**Pick Flux TTS (`/v2/speak`) when:**
- Building a voice agent, phone assistant, or customer-service bot
- You're streaming LLM tokens to a speaker in real time and want the lowest time-to-first-audio
- The user may barge in mid-response and you need to know what they actually heard
- You want tone to carry across turns without managing state yourself
- You're pre-rendering fixed audio (IVR prompts, notifications) with a Flux TTS voice — use the batch REST transport
Migrating from Aura? See the official [Migrating from Aura to Flux TTS](https://developers.deepgram.com/docs/flux-tts/migrating) guide and [Batch vs Streaming](https://developers.deepgram.com/docs/flux-tts/batch-vs-streaming).
## API Domains
| Domain | REST | WebSocket | Reference |
|--------|------|-----------|-----------|
| Listen v1 — STT, Nova models | `POST /v1/listen` | `wss://api.deepgram.com/v1/listen` | [listen.md](references/listen.md) |
| Listen v2 — STT, Flux STT (conversational) | — | `wss://api.deepgram.com/v2/listen` | [listen.md](references/listen.md) |
| Speak v1 — TTS, Aura models | `POST /v1/speak` | `wss://api.deepgram.com/v1/speak` | [speak.md](references/speak.md) |
| Speak v2 — TTS, Flux TTS (turn-based) | `POST /v2/speak` | `wss://api.deepgram.com/v2/speak` | [speak.md](references/speak.md) |
| Voice Agent | `GET agent.deepgram.com/v1/agent/settings/think/models`; reusable agent configurations at `/v1/projects/{project_id}/agents` (`GET`, `POST`) and `/v1/projects/{project_id}/agents/{agent_id}` (`GET`, `PUT`, `DELETE`); agent variables at `/v1/projects/{project_id}/agent-variables` (`GET`, `POST`) and `/v1/projects/{project_id}/agent-variables/{variable_id}` (`GET`, `PATCH`, `DELETE`) | `wss://agent.deepgram.com/v1/agent/converse` | [agent.md](references/agent.md) |
| Read (Intelligence) | `POST /v1/read` | — | [read.md](references/read.md) |
| Models | `GET /v1/models`, `GET /v1/models/{model_id}`, `GET /v1/projects/{project_id}/models`, `GET /v1/projects/{project_id}/models/{model_id}`; `include_outdated=true` on either list call also returns non-latest model versions | none | [models.md](references/models.md) |
| Projects | `/v1/projects/*` | — | [projects.md](references/projects.md) |
| Auth | `POST /v1/auth/grant` | — | [auth.md](references/auth.md) |
| Self-Hosted | `/v1/projects/*/self-hosted/*` | — | [self-hosted.md](references/self-hosted.md) |
## Common Mistakes to Avoid
### All APIs
GitHub에서 보기