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/baxcloud

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

server.js
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 minutes

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