Real-time event notifications for your streaming infrastructure
Push-based event delivery for real-time integrations
Webhooks allow your application to receive real-time HTTP POST notifications when events occur in your WAVE account. Instead of polling our API for changes, your server receives events immediately—typically within 100ms—when streams start, recordings complete, or billing thresholds are reached.
Real-time
P95 delivery under 100ms
Secure
HMAC-SHA256 signatures
Reliable
6 retries with backoff
25+ event types across 5 categories
stream.createdA new stream resource was created and is ready for ingest
Use case: Initialize your database record, prepare analytics dashboard
stream.connectedEncoder connected and stream is receiving data
Use case: Log connection time, track encoder health
stream.startedStream went live and is receiving video frames
Use case: Notify followers, update live status, start viewer tracking
stream.endedStream stopped receiving video and went offline
Use case: Send analytics summary, generate clips, notify team
stream.deletedStream resource was permanently deleted
Use case: Clean up related data, remove from dashboards
Register, verify, and handle webhooks
// Register a webhook endpoint
const response = await fetch('https://api.wave.online/v1/webhooks', {
method: 'POST',
headers: {
'Authorization': 'Bearer YOUR_API_KEY',
'Content-Type': 'application/json'
},
body: JSON.stringify({
url: 'https://your-server.com/webhooks/wave',
events: [
'stream.started',
'stream.ended',
'recording.completed',
'stream.error'
],
// Auto-generated if not provided, but recommended to set your own
secret: 'whsec_your_webhook_secret_here',
description: 'Production webhook endpoint',
// Optional: Filter by specific streams
filters: {
stream_ids: ['stream_abc123', 'stream_def456'],
// Or filter by owner
owner_ids: ['user_xyz789']
},
// Optional: Set custom headers for your endpoint
custom_headers: {
'X-Custom-Auth': 'your-internal-token'
}
})
});
const webhook = await response.json();
console.log('Webhook created:', webhook);
// {
// id: 'wh_abc123',
// url: 'https://your-server.com/webhooks/wave',
// events: ['stream.started', 'stream.ended', ...],
// status: 'active',
// secret: 'whsec_...',
// created_at: '2024-01-15T10:00:00Z'
// }Headers included with every webhook request
X-Wave-SignatureHMAC-SHA256 signature: sha256={hex_digest}
sha256=abc123...X-Wave-TimestampUnix timestamp (milliseconds) when event was sent
1705312345678X-Wave-Event-TypeThe event type for routing
stream.startedX-Wave-Webhook-IdYour webhook configuration ID
wh_abc123X-Wave-Event-IdUnique event ID for idempotency
evt_xyz789X-Wave-Delivery-IdUnique ID for this delivery attempt
del_123456Automatic retries with exponential backoff
If your endpoint fails to respond with a 2xx status code within the timeout window, we automatically retry with exponential backoff:
| Attempt | Delay | Timeout | Cumulative |
|---|---|---|---|
1 | Immediate | 30s | 0s |
2 | 1 minute | 30s | 1m |
3 | 5 minutes | 30s | 6m |
4 | 30 minutes | 30s | 36m |
5 | 2 hours | 30s | 2h 36m |
6 | 8 hours | 30s | 10h 36m |
Critical patterns for reliable webhook handling
Never process webhooks without verifying the HMAC-SHA256 signature. This prevents spoofed events from attackers.
if (!verifySignature(payload, signature)) {
return res.status(401).json({ error: 'Invalid' });
}Return a 200 response immediately, then process asynchronously. Slow responses trigger retries and may disable your webhook.
res.status(200).json({ received: true });
// Then process in background
processEvent(event).catch(console.error);Events may be delivered multiple times due to retries. Use the event ID to deduplicate and avoid double-processing.
if (await isDuplicate(eventId)) {
return { duplicate: true };
}
await processAndMark(eventId, event);Store raw event payloads before processing. They are invaluable for debugging, compliance, and replaying failed events.
await eventLog.insert({
id: event.id,
payload: rawBody,
received_at: new Date()
});Reject events with timestamps older than 5 minutes to prevent replay attacks from captured requests.
const age = Date.now() - parseInt(timestamp);
if (age > 300000) { // 5 minutes
return res.status(400).json({ error: 'Too old' });
}Push events to a message queue (Redis, SQS, etc.) for reliable processing with automatic retries and dead-letter handling.
await eventQueue.push({
event,
retries: 0,
deadLetterAfter: 5
});Common issues and solutions
How teams build with WAVE webhooks
Analytics Platform
Needed real-time stream events to power live analytics dashboards for 10,000+ concurrent streamers.
Implemented WAVE webhooks with Redis queue for event processing, achieving sub-second dashboard updates.
“WAVE webhooks are the backbone of our real-time analytics. The signature verification and retry logic give us confidence in every event.”
Push Notifications
Building a notification service that alerts followers within seconds of a stream going live.
Direct webhook integration with stream.started events, triggering push notifications to mobile and web.
“The webhook documentation was so clear we had notifications working in a single afternoon. Our creators love the instant alerts.”
Video Processing
Automatically generate highlight clips when streams end, processing thousands of recordings daily.
recording.completed webhooks trigger ML-powered clip generation pipeline with auto-upload to social media.
“Every recording completion triggers our AI pipeline automatically. We went from manual clip creation to fully automated in weeks.”
Continue building your integration
Complete webhook API documentation
Access real-time metrics via PULSE API
Automate VOD processing with webhooks
Use tools like ngrok or localtunnel to expose your local server, or use the “Test Locally” code examples above to simulate events.