Skip to main content
This guide uses tuner-stt-observer. It assumes you have a TunerSession set up — see the Quickstart for the session lifecycle and credentials.
tuner-stt-observer hooks into your STT provider’s native event system to capture the user side of the conversation. It never proxies or modifies your audio stream — it listens to the same events your application already receives.

Supported adapters

ProviderAdapterStatus
DeepgramDeepgramAdapter✅ Supported
SpeechmaticsSpeechmaticsAdapter✅ Supported
AssemblyAISOON
Need a provider that isn’t listed? Extend BaseSTTAdapter — see Custom providers below.

Install

Each provider adapter lives behind an optional extra so you only pull in the SDKs you actually use:

Deepgram

DeepgramAdapter registers on Deepgram’s Open, Transcript, and UtteranceEnd events. speech_final transcript fragments are buffered internally and flushed as a single joined utterance when UtteranceEnd fires — you get one complete user turn per utterance, not one per fragment. Attach it to the Deepgram connection you already have:
Send audio to Deepgram exactly as you normally would — the adapter only listens on the connection’s events, it never touches audio:
Your LiveOptions must set utterance_end_ms (e.g. "1000") and vad_events=True. Without them, UtteranceEnd never fires and the fragment buffer never flushes — you’ll see calls with no user turns.
Barge-in isn’t handled by this adapter — build it yourself with a local VAD or a provider event like Deepgram’s SpeechStarted.

Speechmatics

SpeechmaticsAdapter registers on ADD_TRANSCRIPT and END_OF_UTTERANCE. Speechmatics-rt stacks event handlers rather than replacing them, so the adapter coexists safely with any handlers you register yourself.

Custom providers

For providers other than Deepgram and Speechmatics, extend BaseSTTAdapter from tuner_stt_observer — its docstring documents the full contract (_record_user_turn(), _record_stt_usage(), timestamp conversion) with a worked example.

What gets captured

SignalDeepgramSpeechmatics
Complete user utterance text✓ (fragments joined on UtteranceEnd)✓ (fragments joined on END_OF_UTTERANCE)
Turn start timestamp
Turn duration
STT latency✓ (last fragment’s audio end → Transcript arrival)✓ (END_OF_UTTERANCE → flush)
STT audio usage

Troubleshooting

  • Your LiveOptions must set utterance_end_ms (e.g. "1000") and vad_events=True — without them Deepgram never emits UtteranceEnd and the utterance buffer never flushes.
  • Fragments are joined per utterance — if you’re seeing one turn per fragment, the utterance-end event is never firing. On Deepgram, check utterance_end_ms; on Speechmatics, confirm your session emits END_OF_UTTERANCE.

What’s Next?

Quickstart

The session lifecycle, credentials, and every observer wired together.

Text-to-Speech

Capture the agent side — synthesis latency and word-accurate interruption.

LangChain / LangGraph

Node transitions, tool calls, and LLM latency in your call timeline.

Create Call API

The underlying API every observer feeds into at flush time.