Migrating from /v1/speak to Flux TTS

A step-by-step path from the /v1/speak WebSocket to the streaming-first /v2/speak Flux TTS surface, with a side-by-side of what changes.

Flux TTS ships on a new endpoint, /v2/speak. The /v1/speak endpoint stays available and unchanged, and all Aura model strings continue to work on it — there is no aliasing, redirect, or deprecation. You migrate when you’re ready to build on the streaming-first surface.

Which should you use?

Use Flux TTS for new voice-agent work: streaming LLM output, barge-in, and multi-turn conversations where tone should carry across turns.

Stay on Aura if you’re using Aura voices, or you need something not yet in the Early Access surface. Aura voices are served only on /v1/speak; Flux voices only on /v2/speak (where a flux-* model is required).

What changes

Dimension/v1/speak/v2/speak (Flux TTS)
Mental modelText buffer → audio streamStreaming-first, turn-based conversation
Text inputSpeak messages into a global bufferSpeak messages; server tracks the active turn and assigns speech_id (informational)
FlushingManual Flush + customer-facing flush togglesFlush signals no more text is coming for the turn; once its synthesis completes, you get the turn’s SpeechMetadata
InterruptionClear discards the buffer, no feedbackInterrupt with spoken-text feedback (planned for GA)
Context resetNone (reconnect the WebSocket)Not needed — prosody carries across turns automatically (no API surface)
Turn metadataNoneYou mark end-of-turn with Flush and get per-turn SpeechMetadata (billing, timing) back
Dynamic configNone (fixed at connection)Mid-stream Configure for speed (planned for GA)
Cross-turn contextNoneModel state persists across turns

Migration steps

  1. Change the endpoint. Point your WebSocket at /v2/speak (was /v1/speak). The Python (deepgram-sdk) and JavaScript (@deepgram/sdk) SDKs expose a speak.v2 client — see Getting Started and the template apps — or integrate against the WebSocket directly.
  2. Keep your Speak messages. The Speak shape is unchanged. Do not specify speech_id — the server assigns it and returns it for debuggability.
  3. Require a model. model is required on every /v2/speak connection. Use a Flux TTS voice string (e.g. flux-alexis-en); Aura voices are served by /v1/speak, not /v2/speak.
  4. Drop Clear. At Early Access, end each turn with Flush. Barge-in handling — Interrupt returning text_spoken / text_remaining — is planned for GA.
  5. Treat Flush as end-of-turn, and read SpeechMetadata. Flush marks the end of a turn (there’s no separate Finalize). The turn’s SpeechMetadata reports billing and timing — use it as your end-of-turn signal (not Flushed), and drop any client-side character-count or audio-duration tracking.
  6. Drop the flush toggles. The v1 flush_send-style toggles don’t exist on v2 — audio starts streaming for a turn on its own, and you Flush only to mark the end of the turn.
  7. Drop reconnect-to-reset logic. Prosody carries across turns automatically; there’s no reset step to port.
  8. Insert whitespace between distinct LLM responses. The server doesn’t add whitespace between Speak messages — see Text handling.

Message mapping

The /v2/speak column mixes messages you send (Speak, Flush, Close) with messages the server sends back (Connected, Flushed, SpeechMetadata, SessionMetadata). See Client Messages and Server Messages for the full split.

/v1/speak/v2/speak
SpeakSpeak (unchanged)
Flush (buffer flush)Flush (ends the turn)
ClearInterrupt (planned for GA)
Finalizefolded into Flush
Metadata (on open)Connected
Flushed / ClearedFlushed, SpeechMetadata, SessionMetadata
CloseClose (+ final SessionMetadata)

Behaviors carried forward

  • The Speak message shape is unchanged from v1.
  • 1-hour max session duration carries over from v1. New on v2: a 60s inactivity timeout (NET-0004) — send a WebSocket Ping (or Pong) to keep long-idle sessions alive.

Inline pronunciations, markup handling, and their warning codes are planned for GA — see the Feature Overview.