Webhooks
Receive real-time event notifications from BaxCloud
Overview
Webhooks allow your application to receive real-time notifications when events happen in BaxCloud. Instead of polling for changes, BaxCloud will send HTTP POST requests to your configured endpoint whenever an event occurs.
Real-time Events
Get notified instantly when events occur
Signature Verification
Verify webhook authenticity with HMAC signatures
Automatic Retries
Failed deliveries are automatically retried
Event Types
47 webhook events across BaxMedia, BaxVerify, BaxMail, BaxLinks, and BaxStream
Room
room.createdOccurs when a new room is created and becomes active.room.endedOccurs when a room session ends and all participants have left.Participant
participant.joinedOccurs when a participant successfully joins a room.participant.leftOccurs when a participant leaves a room or is disconnected.Track
track.publishedOccurs when a participant publishes a track (audio or video) to the room.track.unpublishedOccurs when a participant unpublishes a track or stops sharing media.Recording
recording.startedOccurs when recording of a room session begins.recording.updatedOccurs when recording status is updated (e.g., progress, duration changes).recording.completedOccurs when recording finishes and the file is ready for download.recording.failedOccurs when a recording fails due to an error (e.g., storage issue, encoding failure).Stream Out (Egress)
stream.startedOccurs when an outgoing RTMP stream to an external platform (YouTube, Twitch, etc.) begins.stream.updatedOccurs when an outgoing stream status is updated (e.g., bitrate change, destination added).stream.completedOccurs when an outgoing stream ends successfully.stream.failedOccurs when an outgoing stream fails (e.g., destination unreachable, encoding error).Stream In (Ingress)
live.startedOccurs when an RTMP or WHIP ingress stream starts broadcasting into a room (e.g., from OBS, FFmpeg).live.updatedOccurs when an ingress stream status is updated (e.g., quality change, reconnection).live.endedOccurs when an ingress stream stops or the broadcaster disconnects.live.failedOccurs when an ingress stream fails (e.g., authentication error, invalid stream key).PK Battle
pk.startedOccurs when a PK battle begins after countdown. Contains battle ID, hosts, duration, and scores.pk.score_updateOccurs when a host's score changes during an active PK battle. Contains updated scores for all hosts.pk.endedOccurs when a PK battle finishes. Contains final scores, winner identity, and battle duration.pk.cancelledOccurs when a PK battle is cancelled or declined before it starts.Subscribe to specific events in Dashboard → Project → Webhooks, or select all events for a catch-all endpoint.
Setup Webhooks
Configure webhook endpoints in your project
Step 1: Create Webhook Endpoint
Navigate to your project settings and add a webhook endpoint URL:
1https://your-app.com/webhooks/baxcloudStep 2: Select Events
Choose which events you want to receive notifications for. You can select specific events or subscribe to all events.
Step 3: Get Signing Secret
After creating the webhook, you'll receive a signing secret. Store this securely - you'll need it to verify webhook authenticity.
1whsec_abc123xyz789...Webhook Payload
Structure of incoming webhook requests
BaxCloud sends webhooks as HTTP POST requests with a JSON payload:
1{
2 "event": "room.created",
3 "timestamp": "2026-01-18T10:00:00.000Z",
4 "projectId": "cl_proj_abc123",
5 "room": {
6 "sid": "RM_abc123xyz",
7 "name": "my-room",
8 "numParticipants": 0,
9 "numPublishers": 0,
10 "activeRecording": false,
11 "creationTime": "1705576800",
12 "metadata": { "projectId": "cl_proj_abc123" }
13 }
14}Example: participant.joined
1{
2 "event": "participant.joined",
3 "timestamp": "2026-01-18T10:01:00.000Z",
4 "projectId": "cl_proj_abc123",
5 "room": {
6 "sid": "RM_abc123xyz",
7 "name": "my-room",
8 "numParticipants": 2
9 },
10 "participant": {
11 "sid": "PA_xyz789abc",
12 "identity": "user-123",
13 "name": "John Doe",
14 "state": "ACTIVE",
15 "joinedAt": "1705576860",
16 "trackCount": 2
17 }
18}BaxStream product webhooks add eventId, metadata, and a data object — see BaxStream webhooks.
Signature Verification
Verify webhook authenticity to prevent spoofing
BaxCloud signs all webhook requests with HMAC-SHA256. Verify the signature to ensure the webhook came from BaxCloud and wasn't tampered with.
1import express from 'express';
2import { webhookMiddleware } from '@baxcloud/baxcloud-server-sdk';
3
4const app = express();
5
6app.post(
7 '/webhooks/baxcloud',
8 express.json({
9 verify: (req: any, _res, buf) => {
10 req.rawBody = buf.toString('utf8');
11 },
12 }),
13 webhookMiddleware(process.env.BAXCLOUD_WEBHOOK_SECRET!),
14 (req, res) => {
15 const event = req.baxcloudEvent;
16
17 switch (event.event) {
18 case 'room.created':
19 console.log('Room created:', event.room?.name);
20 break;
21 case 'participant.joined':
22 console.log('Participant joined:', event.participant?.identity);
23 break;
24 }
25
26 res.status(200).json({ received: true });
27 },
28);Full reference: Server SDK (Node.js)
Always verify signatures
Verifying webhook signatures is critical for security. Never process unverified webhooks.
Best Practices
Return 200 OK quickly
Process webhooks asynchronously and return 200 OK immediately
Handle duplicate events
BaxStream webhooks include eventId for deduplication; for other products, dedupe on event + stable fields (e.g. room SID + timestamp)
Verify signatures first
Always verify the webhook signature before processing the payload
Use HTTPS endpoints
Webhook URLs must use HTTPS for security
Monitor webhook health
Check the webhook logs in your dashboard for delivery failures
Retry Logic
If your endpoint returns a non-200 status code or times out, BaxCloud will automatically retry the webhook delivery with exponential backoff:
11st retry: after 5 seconds
22nd retry: after 30 seconds
33rd retry: after 2 minutes
44th retry: after 10 minutes
55th retry: after 30 minutesAfter 5 failed attempts, the webhook delivery is marked as failed and you'll be notified via email. You can manually retry failed webhooks from the dashboard.