Guides

Broadcast

Table of Contents

  1. Overview
  2. End-to-End Flow Diagram
  3. Host-Side Flow
  4. Viewer-Side Flow
  5. Password Protection
  6. Capacity Management and Queuing
  7. Broadcast Status and Lifecycle
  8. Standby Phase in Detail
  9. Announcements
  10. Error Handling
  11. Related Reference Documents

Overview

The VAS broadcast feature provides one-to-many real-time subtitle broadcasting. The host sends audio over WebSocket for speech recognition and translation, while viewers receive multilingual subtitles in real time over SSE.

Key Features

  • Real-time subtitles: The host's speech is instantly converted into multilingual subtitles
  • One-to-many architecture: One host, multiple viewers receiving simultaneously
  • Multilingual translation: Supports multiple translation languages; viewers can choose their preferred language
  • TTS audio: Viewers can receive translated speech playback
  • Standby phase: The host can warm up and test first, confirming the equipment works before going live
  • Password protection: Supports public or password-protected broadcasts
  • Capacity management: Viewer limits and queuing
  • Speaker identification: Supports multi-speaker diarization (Speaker Diarization)

API Types Involved

API TypeRolePurpose
REST APIHostCreate, query, update, and revoke broadcasts
REST APIViewerQuery broadcast information, verify password
WebSocketHostSend audio, control the broadcast, manage viewers
SSEViewerReceive live subtitles, translations, and TTS
Broadcast REST APIViewerQuery the live broadcast status

Authentication

  • Host side: The REST API uses an API Key, and WebSocket uses Ticket authentication. See Authentication for details.
  • Viewer side: Authenticated via the broadcast Token; no API Key is required. Password-protected broadcasts additionally require a viewer_access_token.

End-to-End Flow Diagram

Host Side                                    Viewer Side
=========                                    ===========

[1] POST /api/v1/broadcasts
    Create the broadcast, get token & share_url
         |
[2] Share share_url with viewers ──────────> Receive the share link
         |                                         |
[3] POST /api/v1/auth/ticket                 [A] GET /api/v1/viewer/broadcasts/{token}
    Get the WebSocket Ticket                      Query public broadcast info
         |                                         |
[4] WebSocket connection                      [B] (if password protected)
    wss://vas-poc.vurbo.ai/ws                        POST /viewer/broadcasts/{token}/verify
         |                                         Get viewer_access_token
[5] Send start action                              |
    type: "broadcast"                         [C] EventSource connection
    broadcast_token: "xxx"                        GET /broadcast/{token}/text
    broadcast_phase: "standby"                     |
         |                                         |
    ===== Standby Phase =====                       |
         |                                    Receive connected event
[6] STT/translation results visible           Receive standby event
    to host only                              Show "Preparing, please wait..."
    Host tests the equipment                       |
         |                                         |
    ===== Switch to live phase =====                |
         |                                         |
[7] broadcast_go_live ─────────────────────> Receive phase_changed event
         |                                    phase: "live"
    ===== Live =====                                |
         |                                         |
[8] Send audio (audio action)                [D] Receive live subtitles
    Receive recognition results                   origin event (source text)
    Receive translation results                   translation event (translation)
         |                                         tts_ready event (TTS audio)
         |                                         |
[9] Pause (pause) ─────────────────────────> Receive paused event
         |                                         |
[10] Resume (resume) ──────────────────────> Receive resumed event
         |                                         |
[11] Send announcement ────────────────────> Receive announcement event
         |                                         |
[12] Stop (stop) ──────────────────────────> Receive ended event
                                                   Close the SSE connection

Host-Side Flow

Step 1: Create a Broadcast

Create a broadcast channel via the REST API and obtain the share Token and link.

curl -X POST "https://vas-poc.vurbo.ai/api/v1/broadcasts" \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "transcription_language": "zh-TW",
    "translation_languages": ["en-US", "ja-JP"],
    "name": "Tech Seminar Live Subtitles",
    "access_type": "public",
    "max_viewers": 100,
    "speaker_diarization": false,
    "tts_config": {
      "en-US": {"voice": "en-US-JennyNeural", "speaking_rate": 1.0},
      "ja-JP": {"voice": "ja-JP-NanamiNeural", "speaking_rate": 1.0}
    },
    "summary_template": "meeting",
    "summary_language": "zh-TW"
  }'

Key request parameters:

ParameterRequiredDescription
transcription_languageYesTranscription language (the language the host speaks)
translation_languagesNoArray of translation languages
nameNoChannel name (max 100 characters)
access_typeNopublic (default) or password
pass_codeConditionalPassword (required when type is password, 4-12 characters)
max_viewersNoMaximum number of viewers (defaults to the plan limit)
speaker_diarizationNoWhether to enable speaker identification (default false)
tts_configNoDefault TTS settings
summary_templateNoSummary template slug (e.g., meeting, lecture)
summary_languageNoSummary output language (uses transcription_language if not specified)
callback_urlNoWebhook callback URL (notified when recording processing completes/fails)

Key fields in a successful response:

FieldDescription
idBroadcast ID (used for subsequent REST API operations)
tokenShare Token (4-character short code, a-z0-9, used for viewer connections)
share_urlShare link (the full URL to give directly to viewers)
statusInitial status is pending

For the full parameter list, see REST API - Broadcasts.

Webhook notifications: After adding the callback_url parameter, you receive a recording.completed event notification when the broadcast recording finishes processing. See the Webhook Callback Guide for details.

Share the share_url from the response with viewers. Viewers can use this link to enter the broadcast page.

https://vas-poc.vurbo.ai/broadcast/a3f9

Step 3: WebSocket Connection

The host needs to establish a WebSocket connection to send audio.

3.1 Get a Ticket:

curl -X POST "https://vas-poc.vurbo.ai/api/v1/auth/ticket" \
  -H "X-API-Key: YOUR_API_KEY"

3.2 Establish the WebSocket connection:

const ws = new WebSocket('wss://vas-poc.vurbo.ai/ws', [`ticket.${ticket}`]);

3.3 Send the start action:

{
  "type": "voice-translation",
  "data": {
    "action": "start",
    "type": "broadcast",
    "broadcast_token": "a3f9",
    "audio_format": "pcm",
    "broadcast_phase": "standby",
    "standby_message": "The talk is about to begin, please wait..."
  }
}

Key parameters for start in broadcast mode:

ParameterRequiredDescription
typeYesMust be "broadcast"
broadcast_tokenYesThe Token obtained when creating the broadcast
audio_formatYespcm or webm
broadcast_phaseNostandby or live (default)
standby_messageNoThe message viewers see during the standby phase
tts_configNoMultilingual TTS settings (can override the settings from creation time)
summary_templateNoSummary template slug (can override the settings from creation time; uses the broadcast channel default if not specified)

Note: In broadcast mode, the language settings are automatically taken from the broadcast channel settings, so you do not need to send transcription_languages and translation_languages in start. summary_template and summary_language are also taken from the broadcast channel settings; pass them only when you need to override.

Successful response:

{
  "type": "voice-translation",
  "data": {
    "action": "session_started",
    "session_id": "550e8400-e29b-41d4-a716-446655440000",
    "recording_id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
    "recording_type": "broadcast",
    "recognition_mode": "multi_speaker",
    "phase": "standby",
    "viewer_count": 0,
    "queue_count": 0,
    "peak_viewers": 0,
    "total_viewers": 0,
    "message": "Speech recognition started"
  }
}

Step 4: Standby Phase (standby)

The standby phase lets the host test equipment and warm up STT/translation before going live.

Standby phase characteristics:

  • STT/translation results are visible to the host only; viewers cannot see them
  • Viewers see the waiting message set in standby_message
  • The host can confirm that the microphone, recognition accuracy, and so on are working correctly
  • The standby message can be updated dynamically at any time

Update the standby message dynamically:

{
  "type": "voice-translation",
  "data": {
    "action": "set_standby_message",
    "message": "The presenter is getting ready, expected to start in about 5 minutes..."
  }
}

Viewers immediately receive the updated standby event, and the message is automatically translated into all translation languages.

For details, see Standby Phase in Detail.

Step 5: Going Live (go_live)

Once you confirm the equipment is working, switch to the live phase:

{
  "type": "voice-translation",
  "data": {
    "action": "broadcast_go_live"
  }
}

Successful response:

{
  "type": "voice-translation",
  "data": {
    "action": "broadcast_phase_changed",
    "phase": "live",
    "message": "Broadcast has started"
  }
}

After switching:

  • STT/translation results begin broadcasting to viewers
  • Results begin being written to the transcript
  • TTS begins being sent to viewers
  • Viewers receive the phase_changed event

Note: If you set broadcast_phase: "live" (the default) at start, the standby phase is skipped and the broadcast goes live directly.

Step 6: Operations During the Broadcast

While live, the host can perform the following operations:

Send audio:

{
  "type": "voice-translation",
  "data": {
    "action": "audio",
    "payload": "Base64-encoded audio data"
  }
}

Pause the broadcast:

{
  "type": "voice-translation",
  "data": {
    "action": "pause"
  }
}

Viewers receive the paused event and see "Broadcast paused."

Resume the broadcast:

{
  "type": "voice-translation",
  "data": {
    "action": "resume"
  }
}

Viewers receive the resumed event.

Step 7: Update Settings Dynamically

While the broadcast is running, you can adjust settings in real time via the REST API:

curl -X PATCH "https://vas-poc.vurbo.ai/api/v1/broadcasts/{id}" \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "translation_languages": ["en-US", "ja-JP", "ko-KR"],
    "max_viewers": 200
  }'

Settings that can be updated dynamically:

SettingDescription
access_typeSwitch between public/password protected
pass_codeUpdate the password
max_viewersAdjust the viewer limit
transcription_languageChange the transcription language
translation_languagesAdd or remove translation languages
speaker_diarizationEnable/disable speaker identification
tts_configUpdate TTS settings
summary_templateSummary template (empty string clears it)
summary_languageSummary output language (empty string clears it)

Only broadcasts in pending, active, or paused status can be updated.

Step 8: Viewer Management

The host can monitor the viewer count during the broadcast. The system checks every 3 seconds and pushes a viewer_count event whenever there is a change:

{
  "type": "voice-translation",
  "data": {
    "action": "viewer_count",
    "viewer_count": 45,
    "queue_count": 8,
    "peak_viewers": 50,
    "total_viewers": 123
  }
}
FieldDescription
viewer_countCurrent online viewer count
queue_countNumber of viewers waiting in the queue
peak_viewersPeak viewer count for this broadcast
total_viewersTotal number of viewers that have ever connected

Step 9: Stop the Broadcast

{
  "type": "voice-translation",
  "data": {
    "action": "stop"
  }
}

After stopping:

  • All viewers receive the ended event
  • The system automatically uploads the audio file and transcript
  • The broadcast status changes to ended
  • The host receives a task_complete event (including a task_id that can be used for subsequent queries)

Viewer-Side Flow

Step 1: Retrieve Broadcast Information

After a viewer opens the share link, they first query the broadcast information.

Method A: via the Viewer API

curl -X GET "https://vas-poc.vurbo.ai/api/v1/viewer/broadcasts/{token}"

The response includes the channel name, access type, available languages, the TTS voice list, and other information. The frontend can use this to display the broadcast information page.

Key fields in the Viewer API response:

FieldDescription
nameChannel name
access_typepublic or password
requires_passwordWhether password verification is required
is_liveWhether the broadcast is currently live
translation_languagesAvailable translation languages
tts_languagesLanguages that support TTS
tts_voicesThe list of available TTS voices for each language

Step 2: Password Verification (if required)

If the broadcast is set to password protected (requires_password: true), the viewer must verify the password first:

curl -X POST "https://vas-poc.vurbo.ai/api/v1/viewer/broadcasts/{token}/verify" \
  -H "Content-Type: application/json" \
  -d '{"password": "mySecret123"}'

Successful response:

{
  "data": {
    "viewer_access_token": "aB3dE5fG7hI9jK1lM3nO5pQ7rS9tU1vWaB3dE5fG7hI9jK1lM3nO5pQ7rS9tU1vW",
    "expires_at": "2026-01-04T10:00:00.000Z"
  }
}

The viewer_access_token you obtain must be included in the subsequent SSE connection. The token is valid for 24 hours.

Step 3: SSE Connection to Receive Subtitles

Viewers receive the subtitle stream in real time over an SSE connection.

Basic connection (public broadcast):

const eventSource = new EventSource(
  'https://vas-poc.vurbo.ai/broadcast/{token}/text'
);

Filter to a specific translation language:

const eventSource = new EventSource(
  'https://vas-poc.vurbo.ai/broadcast/{token}/text?lang=en-US'
);

Enable TTS:

const eventSource = new EventSource(
  'https://vas-poc.vurbo.ai/broadcast/{token}/text?lang=en-US&tts=true'
);

Password-protected broadcast:

const eventSource = new EventSource(
  'https://vas-poc.vurbo.ai/broadcast/{token}/text?lang=en-US&viewer_access_token=aB3dE5fG7hI9jK1l...'
);

SSE connection parameters:

ParameterRequiredDescription
tokenYesBroadcast share Token (path parameter)
langNoFilter to a specific translation language (e.g., en-US)
ttsNoWhether to enable TTS (true / false)
viewer_access_tokenConditionalRequired for password-protected broadcasts

Step 4: Receive Live Content

After connecting successfully, the viewer receives the following events in order:

4.1 connected (connection confirmation)

{
  "session_id": "abc123",
  "source_lang": "zh-TW",
  "subscribed_lang": "en-US",
  "available_langs": ["en-US", "ja-JP"],
  "tts_languages": ["en-US"],
  "phase": "live",
  "recognition_mode": "single",
  "client_id": "client_xyz"
}

4.2 origin (source text)

{
  "sid": 1,
  "text": "Hello everyone, welcome to today's technical seminar",
  "speaker_id": "0",
  "start_time": "00:05",
  "is_final": true
}

4.3 translation

{
  "sid": 1,
  "language": "en-US",
  "text": "Hello everyone, welcome to today's technical seminar",
  "speaker_id": "Royx",
  "is_final": true
}

4.4 tts_ready (TTS audio, requires tts=true)

{
  "sid": 1,
  "language": "en-US",
  "transcript": "Hello everyone, welcome to today's technical seminar",
  "text": "Hello everyone, welcome to today's technical seminar",
  "audio": "Base64EncodedMP3...",
  "format": "mp3",
  "duration_ms": 3200,
  "boundaries": [...]
}

Step 5: Select Language and TTS

Viewers can select their preferred translation language and TTS settings through the SSE connection parameters.

Switching languages: You need to close the existing SSE connection and reconnect with a new lang parameter.

// Switch to Japanese
eventSource.close();
const newEventSource = new EventSource(
  `https://vas-poc.vurbo.ai/broadcast/${token}/text?lang=ja-JP&tts=true`
);

Complete viewer-side example:

function connectBroadcast(token, lang, enableTts, viewerToken) {
  let url = `https://vas-poc.vurbo.ai/broadcast/${token}/text`;
  const params = new URLSearchParams();
  if (lang) params.set('lang', lang);
  if (enableTts) params.set('tts', 'true');
  if (viewerToken) params.set('viewer_access_token', viewerToken);

  if (params.toString()) url += `?${params.toString()}`;

  const eventSource = new EventSource(url);

  // Connection confirmation
  eventSource.addEventListener('connected', (e) => {
    const data = JSON.parse(e.data);
    console.log(`Connected, available languages: ${data.available_langs.join(', ')}`);
  });

  // Standby phase
  eventSource.addEventListener('standby', (e) => {
    const data = JSON.parse(e.data);
    const msg = data.translations?.[lang] || data.message;
    showWaitingScreen(msg);
  });

  // Phase change
  eventSource.addEventListener('phase_changed', (e) => {
    const data = JSON.parse(e.data);
    if (data.phase === 'live') {
      hideWaitingScreen();
    }
  });

  // Source text
  eventSource.addEventListener('origin', (e) => {
    const data = JSON.parse(e.data);
    displayOriginText(data.sid, data.text, data.speaker_id, data.start_time);
  });

  // Translation
  eventSource.addEventListener('translation', (e) => {
    const data = JSON.parse(e.data);
    displayTranslation(data.sid, data.language, data.text);
  });

  // TTS
  eventSource.addEventListener('tts_ready', (e) => {
    const data = JSON.parse(e.data);
    playTtsAudio(data.audio, data.boundaries, data.text);
  });

  // Pause/resume
  eventSource.addEventListener('paused', (e) => {
    showPausedOverlay();
  });
  eventSource.addEventListener('resumed', (e) => {
    hidePausedOverlay();
  });

  // Announcement
  eventSource.addEventListener('announcement', (e) => {
    const data = JSON.parse(e.data);
    const msg = data.translations?.[lang] || data.message;
    showAnnouncement(msg);
  });

  // End
  eventSource.addEventListener('ended', (e) => {
    const data = JSON.parse(e.data);
    showEndedScreen(data.reason);
    eventSource.close();
  });

  // Kicked
  eventSource.addEventListener('kicked', (e) => {
    showKickedMessage();
    eventSource.close();
  });

  // Queue
  eventSource.addEventListener('queued', (e) => {
    const data = JSON.parse(e.data);
    showQueuePosition(data.position, data.estimated_wait);
  });
  eventSource.addEventListener('admitted', (e) => {
    hideQueueScreen();
  });

  // Error
  eventSource.addEventListener('error', (e) => {
    if (e.data) {
      const error = JSON.parse(e.data);
      handleError(error.error_code, error.message);
    }
    eventSource.close();
  });

  return eventSource;
}

Password Protection

A broadcast can be set to password protected, requiring viewers to enter the correct password before entering.

Create a Password-Protected Broadcast

curl -X POST "https://vas-poc.vurbo.ai/api/v1/broadcasts" \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "transcription_language": "zh-TW",
    "translation_languages": ["en-US"],
    "access_type": "password",
    "pass_code": "mySecret123"
  }'

Viewer-Side Verification Flow

[1] GET /api/v1/viewer/broadcasts/{token}
    ↓ Confirm requires_password: true
[2] Show the password entry screen
    ↓ Viewer enters the password
[3] POST /api/v1/viewer/broadcasts/{token}/verify
    ↓ Get viewer_access_token
[4] SSE connection includes viewer_access_token
    GET /broadcast/{token}/text?viewer_access_token=xxx

Switch Access Type Dynamically

While the broadcast is running, you can change a public broadcast to password protected, or vice versa:

# Change to password protected
curl -X PATCH "https://vas-poc.vurbo.ai/api/v1/broadcasts/{id}" \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "access_type": "password",
    "pass_code": "newPassword"
  }'

# Change back to public
curl -X PATCH "https://vas-poc.vurbo.ai/api/v1/broadcasts/{id}" \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "access_type": "public"
  }'

Capacity Management and Queuing

Viewer Limit

Each broadcast can set a maximum number of viewers (max_viewers). Viewers beyond the limit enter the queue.

Queue Flow

When the viewer count reaches the limit:

  1. After a new viewer connects via SSE, they receive a queued event
  2. The system informs them of their queue position and estimated wait time
  3. As viewers leave, viewers in the queue are admitted in order
  4. When a viewer enters the broadcast, they receive an admitted event

queued event:

{
  "position": 3,
  "estimated_wait": "About 2 minutes"
}

admitted event:

{
  "message": "You have entered the broadcast"
}

Queue Timeout

Viewers who wait in the queue too long receive an ended event with the reason capacity_exceeded:

{
  "reason": "capacity_exceeded",
  "duration_ms": 0
}

Adjust the Limit Dynamically

The host can adjust the viewer limit dynamically during the broadcast:

curl -X PATCH "https://vas-poc.vurbo.ai/api/v1/broadcasts/{id}" \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"max_viewers": 200}'

After raising the limit, viewers in the queue are admitted automatically.


Broadcast Status and Lifecycle

Status Transitions

pending  ──(WebSocket start)──>  active  ──(pause)──>  paused
                                   |                      |
                                   |    <──(resume)───────
                                   |
                                   ├──(stop)──>  ended
                                   |
pending  ──(DELETE)──>  revoked

Status Descriptions

StatusDescriptionAllowed Operations
pendingCreated, waiting for the host to startUpdate settings, revoke
activeLivePause, stop, update settings, send audio
pausedPausedResume, stop, update settings
endedEndedNone (read-only)
revokedRevoked (only pending broadcasts can be revoked)None (read-only)

is_live Field

is_live is a convenience field that is true when the status is active or paused, indicating that the broadcast is in progress.

End Reasons

When a broadcast ends, the ended event that viewers receive includes the end reason:

reasonDescription
session_stoppedThe host ended it normally
token_revokedThe Token was revoked
host_timeoutThe host disconnected and timed out
capacity_exceededQueue timeout

Standby Phase in Detail

The standby phase is the warm-up period before the broadcast officially starts, letting the host test equipment and confirm recognition quality before going live.

Enable the Standby Phase

Set broadcast_phase: "standby" in the WebSocket start action:

{
  "type": "voice-translation",
  "data": {
    "action": "start",
    "type": "broadcast",
    "broadcast_token": "YOUR_TOKEN",
    "audio_format": "pcm",
    "broadcast_phase": "standby",
    "standby_message": "The talk is about to begin, please wait..."
  }
}

Standby Phase Behavior

ItemBehavior
STT recognitionOperates normally; results are sent to the host only
TranslationOperates normally; results are sent to the host only
Viewer subtitlesNot sent; viewers see standby_message
TTSNot sent to viewers
TranscriptNot written

Update the Standby Message Dynamically

After entering the standby phase, you can update the message shown to viewers at any time:

{
  "type": "voice-translation",
  "data": {
    "action": "set_standby_message",
    "message": "Adjusting the equipment, expected to start in 3 minutes"
  }
}

After the update, all viewers immediately receive a new standby event:

event: standby
data: {"message":"Adjusting the equipment, expected to start in 3 minutes","translations":{"en-US":"Adjusting equipment, expected to start in 3 minutes","ja-JP":"機器の調整中、約3分後に開始予定"}}

Note: set_standby_message can only be used during the standby phase. It returns an error once the broadcast is already live.

The Viewer Experience During the Standby Phase

  1. After connecting, the viewer receives a connected event (phase: "standby")
  2. Immediately afterward, they receive a standby event containing the waiting message and its multilingual translations
  3. When the host switches to the live phase, the viewer receives a phase_changed event (phase: "live")
  4. They then begin receiving subtitles and translations
eventSource.addEventListener('standby', (e) => {
  const data = JSON.parse(e.data);
  // Display the corresponding translation based on the viewer's selected language
  const displayLang = 'en-US';
  const msg = data.translations?.[displayLang] || data.message;
  showWaitingScreen(msg);
});

eventSource.addEventListener('phase_changed', (e) => {
  const data = JSON.parse(e.data);
  if (data.phase === 'live') {
    hideWaitingScreen();
    // Start displaying the subtitle area
  }
});

Announcements

The host can send announcement messages to all viewers during the broadcast.

Send an Announcement

{
  "type": "voice-translation",
  "data": {
    "action": "broadcast_announcement",
    "message": "The meeting will end in 5 minutes"
  }
}

Viewer-Side Reception

Viewers receive an announcement event over SSE, containing the source text and its multilingual translations:

{
  "message": "The meeting will end in 5 minutes",
  "translations": {
    "en-US": "The meeting will end in 5 minutes",
    "ja-JP": "会議は5分後に終了します"
  }
}

The frontend can display the corresponding translation based on the viewer's selected language:

eventSource.addEventListener('announcement', (e) => {
  const data = JSON.parse(e.data);
  const displayLang = 'en-US';
  const msg = data.translations?.[displayLang] || data.message;
  showAnnouncementPopup(msg);
});

Error Handling

Common Host-Side Errors

Error CodeDescriptionSuggested Action
broadcast_token_requiredBroadcast mode requires a TokenConfirm that broadcast_token is provided
broadcast_token_invalidInvalid TokenConfirm the Token is correct and not expired
broadcast_not_readyBroadcast service not yet startedRetry later
broadcast_not_enabledNot in broadcast modeConfirm type: "broadcast"
broadcast_not_in_standbyNot in the standby phaseCan only be used during the standby phase
broadcast_cannot_updateCannot update settingsCheck the current broadcast status
broadcast_cannot_revokeCannot revokeOnly pending broadcasts can be revoked

Common Viewer-Side Errors

Error CodeDescriptionSuggested Action
broadcast_not_foundBroadcast not foundConfirm the Token is correct
broadcast_session_endedBroadcast has endedInform the viewer that the broadcast has ended
broadcast_capacity_fullViewer limit reachedJoin the queue
broadcast_token_invalidInvalid TokenConfirm the Token is correct
broadcast_token_revokedToken revokedThe broadcast has been revoked
broadcast_password_incorrectIncorrect passwordRe-enter the password

Disconnection Handling

Host disconnection:

  • Viewers receive a paused event (reason: "host_disconnected")
  • If the host fails to reconnect before timing out, viewers receive an ended event (reason: "host_timeout")

Viewer disconnection:

  • After the SSE connection drops, the browser reconnects automatically (the built-in EventSource mechanism)
  • After reconnecting, the viewer receives a new connected event
  • SSE uses a 15-second heartbeat interval to keep the connection alive


Version: V1.5.7 Last Updated: 2026-05-20

Copyright © 2026