# MeetStream Guide: Live Transcription (Streaming) via Webhook This guide explains how to enable **live (real‑time) transcription** for a MeetStream bot using: - `deepgram_streaming` - `assemblyai_streaming` You will receive streaming transcription updates on your webhook URL while the bot is in the meeting. --- ## 1) What you need To use live transcription you must provide: 1) A webhook endpoint that can receive POST requests (public URL). 2) `live_transcription_required.webhook_url` in your create bot payload. 3) A streaming provider config under `recording_config.transcript.provider`. > Tip: For local testing, use **ngrok** or **cloudflared** to expose your local webhook to the internet. --- ## 2) Add `live_transcription_required` to your bot payload In your Create Bot / Create Agent request body: ```json "live_transcription_required": { "webhook_url": "{{webhook_url}}/webhook" } ``` This is the endpoint where MeetStream will POST live transcription events. --- ## 3) Choose a streaming provider (payload examples) ### A) AssemblyAI Streaming (`assemblyai_streaming`) ```json "live_transcription_required": { "webhook_url": "{{webhook_url}}/webhook" }, "recording_config": { "transcript": { "provider": { "assemblyai_streaming": { "transcription_mode": "raw", "sample_rate": 48000, "speech_model": "universal-streaming-english", "format_turns": false, "encoding": "pcm_s16le", "vad_threshold": "0.4", "end_of_turn_confidence_threshold": "0.4", "inactivity_timeout": 300, "min_end_of_turn_silence_when_confident": "400", "max_turn_silence": "1280" } } } } ``` --- ### B) Deepgram Streaming (`deepgram_streaming`) ```json "live_transcription_required": { "webhook_url": "{{webhook_url}}/webhook" }, "recording_config": { "transcript": { "provider": { "deepgram_streaming": { "transcription_mode": "sentence", "model": "nova-2", "language": "en", "punctuate": true, "smart_format": true, "endpointing": 300, "vad_events": true, "utterance_end_ms": 1000, "encoding": "linear16", "channels": 1 } } } } ``` > Use **exactly one** provider in `recording_config.transcript.provider`. --- ## 4) What your webhook will receive (example payload) MeetStream will POST live transcription updates to: `{{webhook_url}}/webhook` Example payload: ```json { "bot_id": "8ceabf49-d392-4c04-8e91-bd9601a0df6e", "speakerName": "Madan Raj", "timestamp": "2026-01-24T17:00:30.354452", "new_text": "hear", "transcript": "hear", "utterance": "", "words": [ { "word": "hear", "start": 2, "end": 2.08, "confidence": 0.999955, "speaker": "Madan Raj", "punctuated_word": "hear", "speech_confidence": 0.999955, "word_is_final": false } ], "end_of_turn": false, "turn_is_formatted": false, "transcription_mode": "word_level", "custom_attributes": { "tag": "Maddy", "sample": "testing" } } ``` ### Field notes (practical) - `bot_id` — use this to map to your session/meeting. - `speakerName` / `speaker` — speaker label (if available). - `new_text` — incremental update (useful for streaming UI). - `transcript` — current transcript buffer (can be partial). - `words[]` — word-level timings + confidence. - `word_is_final` — if `false`, treat as interim (may change). - `end_of_turn` — can be used to “commit” a phrase/segment. - `custom_attributes` — echoed from your Create Bot payload (useful for correlation). --- ## 5) Recommended implementation pattern ### A) Always ACK fast Your webhook should respond **2xx quickly** (e.g., 200 OK) to avoid timeouts. ### B) Store and stream Common approaches: - **Live UI captions:** append `new_text` when `word_is_final=true`, or only commit when `end_of_turn=true`. - **Analytics / downstream triggers:** run actions when `end_of_turn=true` (less noisy). - **Persist to DB:** store word chunks with timestamps, or store turn-level segments. ### C) De-dup / idempotency Webhooks can occasionally arrive close together. Consider de-duping with: - `{bot_id, timestamp, new_text}` or - a rolling hash of the payload body. --- ## 6) Troubleshooting - No live transcription arriving? - Confirm `live_transcription_required.webhook_url` is reachable publicly (try `curl`). - Ensure your webhook endpoint path is correct (`/webhook`). - Confirm your webhook server accepts **POST** and returns **2xx**. - Getting payloads but UI looks “jumpy”? - Treat `word_is_final=false` as interim. - Only commit text when `end_of_turn=true` or `word_is_final=true`. --- If you tell me your stack (Node / Bun / Python), I’ll add a copy‑paste webhook handler that: - validates requests, - logs payloads safely, - and streams updates to your frontend via WebSocket/SSE.