Webhooks
Receive real-time notifications when events happen on the Velora platform.
Building a desktop app or stream tool?
The Events API provides real-time event streaming via WebSocket or SSE—no server required. Perfect for Streamer.bot, OBS plugins, and desktop applications.
Learn about the Events API →Overview
Webhooks allow your application to receive real-time HTTP notifications when events occur. Instead of polling for changes, you can subscribe to specific events and we'll send them to your endpoint.
- ✓Real-time event delivery
- ✓Secure signature verification
- ✓Automatic retries on failure
- ✓Delivery history and debugging
Creating a Webhook
You can create webhooks in the Developer Dashboard or via the API:
Via Dashboard
- Go to your application in the Developer Dashboard
- Navigate to the "Webhooks" tab
- Click "Add Webhook"
- Enter your endpoint URL and select events
- Save and copy your webhook secret
Via API
curl -X POST https://api.velora.tv/api/developer/apps/{clientId}/webhooks \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"url": "https://yourapp.com/webhooks/velora",
"events": ["stream.online", "stream.offline", "channel.follow"]
}'Available Events
Stream Events
| Event | Description |
|---|---|
stream.online | A stream goes live |
stream.offline | A stream ends |
stream.update | Stream title or category changes |
Channel Events
| Event | Description |
|---|---|
channel.follow | Someone follows a channel |
channel.subscribe | New or renewed subscription |
channel.update | Channel information updated |
User Events
| Event | Description |
|---|---|
user.authorization.grant | User authorizes your app |
user.authorization.revoke | User revokes authorization |
Webhook Payload
Each webhook delivery sends a POST request with a JSON payload:
{
"id": "evt_abc123",
"type": "stream.online",
"timestamp": "2026-01-18T15:30:00Z",
"data": {
"streamId": "stream_xyz",
"userId": "user_123",
"username": "coolstreamer",
"title": "Playing Velora Games!",
"startedAt": "2026-01-18T15:30:00Z"
}
}Verifying Signatures
Every webhook request includes a signature header for verification. Always verify the signature to ensure the request came from Velora.
Security: Never process webhook payloads without verifying the signature first.
Headers
| Header | Description |
|---|---|
X-Velora-Signature | HMAC-SHA256 signature |
X-Velora-Timestamp | Unix timestamp of the request |
X-Velora-Event | Event type (e.g., stream.online) |
Verification Example (Node.js)
const crypto = require('crypto');
function verifyWebhookSignature(payload, timestamp, signature, secret) {
// The signature is prefixed with "sha256=" - strip it
const sig = signature.replace('sha256=', '');
// The signature is computed over: timestamp.payload
const expected = crypto
.createHmac('sha256', secret)
.update(`${timestamp}.${payload}`)
.digest('hex');
return crypto.timingSafeEqual(
Buffer.from(sig),
Buffer.from(expected)
);
}
// Express middleware example
app.post('/webhooks/velora', express.raw({ type: 'application/json' }), (req, res) => {
const signature = req.headers['x-velora-signature'];
const timestamp = req.headers['x-velora-timestamp'];
const payload = req.body.toString();
// Verify the signature using timestamp + payload
if (!verifyWebhookSignature(payload, timestamp, signature, WEBHOOK_SECRET)) {
return res.status(401).send('Invalid signature');
}
// Optional: Reject old timestamps to prevent replay attacks
const now = Math.floor(Date.now() / 1000);
if (Math.abs(now - parseInt(timestamp)) > 300) { // 5 minute tolerance
return res.status(401).send('Timestamp too old');
}
// Process the webhook
const event = JSON.parse(payload);
console.log('Received event:', event.type);
res.status(200).send('OK');
});Retry Policy
If your endpoint doesn't respond with a 2xx status code within 10 seconds, we'll retry the delivery:
- 1.Immediate retry after failure
- 2.Retry after 1 minute
- 3.Retry after 5 minutes
- 4.Retry after 30 minutes
- 5.Final retry after 2 hours
After 5 failed attempts, the webhook will be disabled automatically. You can re-enable it from the dashboard.
Best Practices
- ✓Respond quickly
Return a 200 response immediately, then process asynchronously
- ✓Handle duplicates
Use the event ID for idempotency - we may send the same event twice
- ✓Verify signatures
Always verify the X-Velora-Signature header
- ✓Use HTTPS
Webhook endpoints must use HTTPS