MeetStream Guide: Live Transcription (Streaming) via Webhook

View as MarkdownOpen in Claude

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:

1"live_transcription_required": {
2 "webhook_url": "{{webhook_url}}/webhook"
3}

This is the endpoint where MeetStream will POST live transcription events.


3) Choose a streaming provider (payload examples)

A) AssemblyAI Streaming (assemblyai_streaming)

1"live_transcription_required": {
2 "webhook_url": "{{webhook_url}}/webhook"
3},
4"recording_config": {
5 "transcript": {
6 "provider": {
7 "assemblyai_streaming": {
8 "transcription_mode": "raw",
9 "sample_rate": 48000,
10 "speech_model": "universal-streaming-english",
11 "format_turns": false,
12 "encoding": "pcm_s16le",
13 "vad_threshold": "0.4",
14 "end_of_turn_confidence_threshold": "0.4",
15 "inactivity_timeout": 300,
16 "min_end_of_turn_silence_when_confident": "400",
17 "max_turn_silence": "1280"
18 }
19 }
20 }
21}

B) Deepgram Streaming (deepgram_streaming)

1"live_transcription_required": {
2 "webhook_url": "{{webhook_url}}/webhook"
3},
4"recording_config": {
5 "transcript": {
6 "provider": {
7 "deepgram_streaming": {
8 "transcription_mode": "sentence",
9 "model": "nova-2",
10 "language": "en",
11 "punctuate": true,
12 "smart_format": true,
13 "endpointing": 300,
14 "vad_events": true,
15 "utterance_end_ms": 1000,
16 "encoding": "linear16",
17 "channels": 1
18 }
19 }
20 }
21}

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:

1{
2 "bot_id": "8ceabf49-d392-4c04-8e91-bd9601a0df6e",
3 "speakerName": "Madan Raj",
4 "timestamp": "2026-01-24T17:00:30.354452",
5 "new_text": "hear",
6 "transcript": "hear",
7 "utterance": "",
8 "words": [
9 {
10 "word": "hear",
11 "start": 2,
12 "end": 2.08,
13 "confidence": 0.999955,
14 "speaker": "Madan Raj",
15 "punctuated_word": "hear",
16 "speech_confidence": 0.999955,
17 "word_is_final": false
18 }
19 ],
20 "end_of_turn": false,
21 "turn_is_formatted": false,
22 "transcription_mode": "word_level",
23 "custom_attributes": {
24 "tag": "Maddy",
25 "sample": "testing"
26 }
27}

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).

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.