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
| Provider | Adapter | Status |
|---|---|---|
| Deepgram | DeepgramAdapter | ✅ Supported |
| Speechmatics | SpeechmaticsAdapter | ✅ Supported |
| AssemblyAI | — | SOON |
BaseSTTAdapter — see Custom providers below.
Install
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:
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, extendBaseSTTAdapter 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
| Signal | Deepgram | Speechmatics |
|---|---|---|
| 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
Calls have no user turns (Deepgram)
Calls have no user turns (Deepgram)
- Your
LiveOptionsmust setutterance_end_ms(e.g."1000") andvad_events=True— without them Deepgram never emitsUtteranceEndand the utterance buffer never flushes.
User turns arrive as fragments
User turns arrive as fragments
- 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 emitsEND_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.