WAVE sends webhook events for stream lifecycle changes, viewer activity, and billing events. All payloads follow these TypeScript interfaces.
interface WebhookEvent<T = unknown> {
id: string;
type: string;
created_at: string; // ISO 8601
organization_id: string;
data: T;
}
stream.startedFired when a stream begins broadcasting.
interface StreamStartedPayload {
stream_id: string;
title: string;
protocol: "webrtc" | "srt" | "rtmp" | "ndi";
quality: {
width: number;
height: number;
fps: number;
bitrate_kbps: number;
};
started_at: string;
}
stream.endedFired when a stream stops broadcasting.
interface StreamEndedPayload {
stream_id: string;
duration_seconds: number;
peak_viewers: number;
total_views: number;
ended_at: string;
reason: "manual" | "error" | "timeout" | "scheduled";
}
stream.viewer.joinedFired when a viewer connects to a stream.
interface ViewerJoinedPayload {
stream_id: string;
viewer_id: string;
viewer_count: number;
joined_at: string;
geo: {
country: string;
region: string;
};
}
subscription.createdinterface SubscriptionCreatedPayload {
subscription_id: string;
customer_id: string;
plan: "starter" | "pro" | "enterprise";
billing_cycle: "monthly" | "annual";
amount_cents: number;
currency: string;
started_at: string;
}
All webhooks include a X-Wave-Signature header for verification:
import { createHmac } from "crypto";
function verifyWebhook(payload: string, signature: string, secret: string): boolean {
const expected = createHmac("sha256", secret)
.update(payload)
.digest("hex");
return `sha256=${expected}` === signature;
}