Applies to: Video, Moderation Audience: All developers integrating Stream Video with Moderation
Quick Answer
WebSocket events are delivered in real time to clients with an active WebSocket connection. Use them for live UI updates (e.g., showing a ringing indicator, updating participant counts).
Webhook events are HTTP POST requests sent to your server endpoint. Use them for server-side processing (e.g., logging calls, triggering moderation workflows, analytics).
Most video events are delivered via both channels. A few are exclusive to one:
connection.ok and connection.error are WebSocket only — they signal connection state to the client.
Several moderation events (moderation_check.completed, appeal.*, moderation_rule.triggered, etc.) are webhook only — they are meant for server-side processing.
If you are not receiving an expected event, first confirm whether it is delivered via the channel you are listening on (WebSocket vs webhook).
Webhooks vs WebSockets — What's the Difference?
WebSocket
Webhook
Direction
Server → connected client
Server → your HTTP endpoint
Transport
Persistent WebSocket connection
HTTP POST request
Latency
Real time (milliseconds)
Near real time (depends on network + retries)
Audience
Client-side (mobile, web, desktop apps)
Server-side (your backend)
Requires connection?
Yes — client must be connected
No — delivered to your endpoint regardless of client state
Retries
No — if the client is disconnected, the event is missed (catch up on reconnect)
Yes — up to 5 retry attempts on failure (408, 429, 5xx)
Authentication
Established during WS handshake (JWT token)
Verified via X-Signature header (HMAC-SHA256 with your API secret)
Deduplication
Built into the WS protocol
Use the X-Webhook-Id header to deduplicate retried deliveries
Use case
Live UI: ringing screens, participant lists, recording indicators
The table below lists all video (call.*) events and their delivery channels.
Call Lifecycle
Event Type
Description
WebSocket
Webhook
call.created
The call was created
Yes
Yes
call.updated
The call was updated (settings, custom data, etc.)
Yes
Yes
call.ended
The call was ended
Yes
Yes
call.deleted
The call was deleted
Yes
Yes
call.live_started
The call left backstage mode and is now live
Yes
Yes
Ringing & Notifications
Event Type
Description
WebSocket
Webhook
call.ring
A user is calling all call members (ring flow)
Yes
Yes
call.notification
A user is notifying all call members (notify flow)
Yes
Yes
call.accepted
A user accepted the notification to join a call
Yes
Yes
call.rejected
A user declined to join the call
Yes
Yes
call.missed
The call was missed (no one answered)
Yes
Yes
Members & Permissions
Event Type
Description
WebSocket
Webhook
call.member_added
One or more members were added to the call
Yes
Yes
call.member_removed
One or more members were removed from the call
Yes
Yes
call.member_updated
One or more members were updated
Yes
Yes
call.member_updated_permission
One or more members' role was updated
Yes
Yes
call.permission_request
A user is requesting permissions (e.g., to share screen)
Yes
Yes
call.permissions_updated
A member's permissions were updated
Yes
Yes
Session & Participants
Event Type
Description
WebSocket
Webhook
call.session_started
A call session started (the first participant joined)
Yes
Yes
call.session_ended
A call session ended (all participants have left)
Yes
Yes
call.session_participant_joined
A participant joined the call session
Yes
Yes
call.session_participant_left
A participant left the call session
Yes
Yes
call.session_participant_count_updated
The participant count has been updated
Yes
Yes
Recording
Event Type
Description
WebSocket
Webhook
call.recording_started
A recording has been started
Yes
Yes
call.recording_stopped
The recording was stopped
Yes
Yes
call.recording_ready
The recording is ready for download
Yes
Yes
call.recording_failed
The recording failed
Yes
Yes
call.frame_recording_started
The call started capturing frames
Yes
Yes
call.frame_recording_stopped
The call stopped capturing frames
Yes
Yes
call.frame_recording_ready
A captured frame is ready
Yes
Yes
call.frame_recording_failed
Frame capture failed
Yes
Yes
call.stats_report_ready
Call stats report is ready for download
Yes
Yes
Broadcasting
Event Type
Description
WebSocket
Webhook
call.hls_broadcasting_started
HLS broadcasting started
Yes
Yes
call.hls_broadcasting_stopped
HLS broadcasting stopped
Yes
Yes
call.hls_broadcasting_failed
HLS broadcasting failed
Yes
Yes
call.rtmp_broadcast_started
RTMP broadcasting started
Yes
Yes
call.rtmp_broadcast_stopped
RTMP broadcasting stopped
Yes
Yes
call.rtmp_broadcast_failed
RTMP broadcasting failed
Yes
Yes
Transcription & Closed Captions
Event Type
Description
WebSocket
Webhook
call.transcription_started
A transcription has been started
Yes
Yes
call.transcription_stopped
The transcription was stopped
Yes
Yes
call.transcription_ready
The transcription is ready for download
Yes
Yes
call.transcription_failed
The transcription failed
Yes
Yes
call.closed_captions_started
Closed captions started
Yes
Yes
call.closed_captions_stopped
Closed captions stopped
Yes
Yes
call.closed_captions_failed
Closed captions failed
Yes
Yes
call.closed_caption
A closed caption text segment was sent
Yes
Yes
User Actions
Event Type
Description
WebSocket
Webhook
call.user_muted
A user was muted
Yes
Yes
call.blocked_user
A user is blocked from the call
Yes
Yes
call.unblocked_user
A user is unblocked from the call
Yes
Yes
call.kicked_user
A user is kicked from the call
Yes
Yes
call.reaction_new
A new reaction was sent during the call
Yes
Yes
call.user_feedback_submitted
A user submitted feedback about the call
Yes
Yes
custom
A custom event sent by your application
Yes
Yes
Video Moderation
Event Type
Description
WebSocket
Webhook
call.moderation_warning
A moderation action was taken on a call participant (e.g., warning issued)
Yes
Yes
call.moderation_blur
A moderation blur was applied to a participant's video stream
Yes
Yes
Moderation Events Reference
If you use Stream Moderation alongside Video, the following moderation-specific events may also be relevant. Note that many moderation events are webhook only because they are designed for server-side moderation workflows.
Moderation - Both WebSocket & Webhook
Event Type
Description
WebSocket
Webhook
moderation.flagged
An item (message, user, or media) was flagged by the moderation system
Yes
Yes
moderation.mark_reviewed
A review queue item was marked as reviewed by a moderator
Yes
Yes
moderation.custom_action
A custom moderation action was performed on a review queue item
Yes
Yes
Moderation - Webhook Only
Event Type
Description
WebSocket
Webhook
moderation_check.completed
A moderation check has completed (AI or rule-based analysis finished)
No
Yes
moderation_rule.triggered
A rule builder rule was triggered by content matching its conditions
No
Yes
appeal.created
A user created an appeal against a moderation action
No
Yes
appeal.accepted
A moderation appeal was accepted (action reversed)
No
Yes
appeal.rejected
A moderation appeal was rejected (action upheld)
No
Yes
user.flagged
A user was flagged for moderation review
No
Yes
message.flagged
A message was flagged for moderation review
No
Yes
flag.updated
A flag has been updated or reviewed by a moderator
These events are never sent via webhooks. They are connection-state events relevant only to the connected client.
Event Type
Description
WebSocket
Webhook
connection.ok
WebSocket connection is established and authentication succeeded. Includes the current user object and connection ID.
Yes
No
connection.error
WebSocket connection failed due to authentication errors. Includes error details.
Yes
No
Why are these WebSocket only? They represent the state of a specific client connection. Your server does not have a “connection” to Stream in the same way — these events are meaningless outside the context of a live WebSocket session.
Webhook-Only Events
These events are never sent via WebSocket. They represent server-side moderation processing results that are not relevant to the end-user client in real time.
moderation_check.completed — Indicates that an AI or rule-based moderation check has finished. Listen for this to take automated action on flagged content.
moderation_rule.triggered — Fired when a rule builder rule matches. Use this to build custom moderation pipelines.
appeal.created / appeal.accepted / appeal.rejected — Appeal lifecycle events. Use these to notify moderators or update your moderation dashboard.
user.flagged / message.flagged / flag.updated — Flag lifecycle events for content and users.
1. “I'm not receiving moderation events on the client”
Most moderation events (moderation_check.completed, appeal.*, moderation_rule.triggered, etc.) are webhook only. They will never arrive over a WebSocket connection. Set up a webhook endpoint to receive them.
2. “I'm receiving duplicate events”
If you listen on both WebSocket and webhook for the same event type, you will receive it twice — once on each channel. This is by design. Either:
Deduplicate using the event's created_at timestamp and type, or
Use WebSocket for client-side logic and webhooks for server-side logic — don't mix responsibilities.
3. “I missed events while my client was disconnected”
WebSocket events are only delivered to connected clients. If a client disconnects and reconnects, it may miss events. Webhooks are more reliable for events you cannot afford to miss, since they include retry logic.
4. Confusing call.moderation_warning with moderation.flagged
call.moderation_warning is a video event sent to call participants when a moderation action is taken during a live call (e.g., a warning overlay). It is delivered via both WebSocket and webhook.
moderation.flagged is a moderation platform event fired when any item is flagged across the system. It is also delivered via both channels but carries different payload structure.
Best Practices
Use WebSocket for real-time UI. Show ringing indicators, participant joins/leaves, recording status, and moderation warnings to end users via WebSocket events.
Use webhooks for server-side logic. Log calls, process moderation results, trigger notifications, and build analytics pipelines using webhook events.
Always configure a webhook endpoint if you use moderation. Many moderation events are webhook-only, so without a webhook endpoint you will miss them entirely.
Verify webhook signatures. Always validate the X-Signature header using your API secret to ensure events are genuinely from Stream.
Deduplicate webhook deliveries. Use the X-Webhook-Id header to detect retried deliveries and avoid processing the same event twice.
Return 200 quickly from your webhook handler. Process events asynchronously. If your endpoint is slow to respond (over 6 seconds), Stream will retry, potentially causing duplicates.
Handle reconnection gracefully on WebSocket. When a client reconnects, query the current call state to catch up on any events missed during disconnection.
Diagnostics Checklist
If you are not receiving expected events, walk through this checklist:
Check the delivery channel. Is the event you expect delivered via WebSocket, webhook, or both? Refer to the tables above.
Verify your webhook is configured. Go to your Stream Dashboard → App Settings → Webhooks. Confirm the URL is correct and active.
Check webhook logs in the Dashboard. The Stream Dashboard shows recent webhook deliveries, including failures and response codes.
Verify the WebSocket connection. Confirm you receive connection.ok after connecting. If you get connection.error, fix your authentication first.
Check event subscriptions. Some events may be filtered by your app configuration. Verify the event type is enabled for webhook delivery in your Dashboard.
Check your webhook response time. If your endpoint takes longer than 6 seconds to respond, the delivery is considered failed and will be retried.
Look for signature validation errors. If your webhook handler rejects events, check that you are using the correct API secret for HMAC-SHA256 verification.
Comments
0 comments
Please sign in to leave a comment.