Webhooks
Get an HTTP POST the moment something happens in your account: a video finishes processing, fails, is deleted, or a member joins or leaves.
Setting Up Webhooks
- Open Dashboard → Global Settings → Webhooks.
- Paste your endpoint URL (https recommended) and tick the events you want — none ticked means all of them.
- Copy the signing secret into your server's configuration.
- Click Send test event. The result appears under Recent deliveries.
Delivery: a JSON
POST. Answer with any 2xx within 10 seconds. A timeout, a network error, 408, 429 or any 5xx is retried twice (after 1 s and 3 s). Redirects are not followed. Endpoints on private or local addresses are refused.Events
Events
| Parameter | Type | Required | Description |
|---|---|---|---|
| videoPublished | event | Optional | A published video finished processing and is ready to play |
| videoProcessed | event | Optional | Any video finished processing, published or not (also after a Replace or a re-encode) |
| videoFailed | event | Optional | Processing a video failed; video.Error says why |
| videoDeleted | event | Optional | A video was deleted — from the dashboard, the API or an auto-delete rule |
| memberCreated | event | Optional | A member was added in the dashboard or signed up on a gated video |
| memberDeleted | event | Optional | A member was removed |
| test | event | Optional | Sent by the Send test event button, whatever events are ticked |
Headers and signature
Request headers
| Parameter | Type | Required | Description |
|---|---|---|---|
| X-StreamVault-Event | string | Required | The event name, same as the body's event field |
| X-StreamVault-Delivery | uuid | Required | Unique per delivery; the same on its retries — use it to ignore duplicates |
| X-StreamVault-Timestamp | integer | Required | Unix seconds when this attempt was sent |
| X-StreamVault-Signature | string | Required | t=<timestamp>,v1=<hex HMAC-SHA256 of `${t}.${rawBody}` with your signing secret> |
Verify the signature over the raw request body (before JSON parsing), and reject timestamps older than five minutes so a captured request cannot be replayed later.
javascript
const crypto = require("crypto");
const express = require("express");
const app = express();
const SECRET = process.env.STREAMVAULT_WEBHOOK_SECRET; // whsec_…
app.post("/webhooks/streamvault", express.raw({ type: "application/json" }), (req, res) => {
const header = req.get("X-StreamVault-Signature") || "";
const parts = Object.fromEntries(header.split(",").map((p) => p.trim().split("=")));
const t = Number(parts.t);
const expected = crypto.createHmac("sha256", SECRET).update(`${t}.${req.body}`).digest("hex");
const fresh = Math.abs(Date.now() / 1000 - t) < 300;
const valid = parts.v1 && parts.v1.length === expected.length &&
crypto.timingSafeEqual(Buffer.from(parts.v1), Buffer.from(expected));
if (!fresh || !valid) return res.status(401).end();
const event = JSON.parse(req.body);
switch (event.event) {
case "videoPublished":
console.log("Ready:", event.video.Title, event.video.IframeLink);
break;
case "videoDeleted":
console.log("Deleted:", event.video.Id);
break;
case "memberCreated":
console.log("New member:", event.member.Email);
break;
}
res.status(200).json({ received: true });
});
app.listen(3000);Video events
videoPublished and videoProcessed carry the full video object; videoFailed sends Id, Title and Error; videoDeleted sends Id, Title and ProjectId.
video
| Parameter | Type | Required | Description |
|---|---|---|---|
| Id | string | Required | Video id |
| Title | string | Required | Video title |
| Description | string | Optional | Video description |
| Duration | string | Required | hh:mm:ss.0000000 |
| Status | integer | Required | 3 = ready |
| Key | string | Required | Short key used in the private link |
| ChannelKey | string | Optional | Channel key |
| ProjectId | string | Optional | Project id |
| IframeLink | string | Required | Embeddable player URL |
| HLSLink | string | Required | HLS URL. Videos with viewer restrictions need a signed URL: GET /v1/videos/{id}/playback |
| PrivateLink | string | Required | Share page URL |
| Image | object | Required | Poster URLs (xsUrl, smUrl, mdUrl, lgUrl) |
| Tags | string[] | Required | Tags |
| Formats | object | Required | HLS / MP4 availability and resolutions |
| Created | datetime | Required | ISO 8601 creation time |
json
{
"event": "videoPublished",
"video": {
"Id": "5c1f6a2e-7a41-4f0e-9d0b-2b6f4f1f9c21",
"Title": "Product Demo",
"Description": "A walkthrough of our product features",
"Duration": "00:02:30.0000000",
"Status": 3,
"Key": "f8RMr2q4h6y",
"ChannelKey": "c99097f8129b4f788983",
"ProjectId": "0b6c7d1e-4a5f-4c3b-8e2d-1f0a9b8c7d6e",
"IframeLink": "https://streamvault.one/embed/5c1f6a2e-7a41-4f0e-9d0b-2b6f4f1f9c21",
"HLSLink": "https://api.streamvault.one/v1/play/5c1f6a2e-7a41-4f0e-9d0b-2b6f4f1f9c21/master.m3u8",
"PrivateLink": "https://streamvault.one/v/f8RMr2q4h6y",
"Image": {
"xsUrl": "https://api.streamvault.one/v1/play/5c1f6a2e-7a41-4f0e-9d0b-2b6f4f1f9c21/poster.jpg",
"smUrl": "https://api.streamvault.one/v1/play/5c1f6a2e-7a41-4f0e-9d0b-2b6f4f1f9c21/poster.jpg",
"mdUrl": "https://api.streamvault.one/v1/play/5c1f6a2e-7a41-4f0e-9d0b-2b6f4f1f9c21/poster.jpg",
"lgUrl": "https://api.streamvault.one/v1/play/5c1f6a2e-7a41-4f0e-9d0b-2b6f4f1f9c21/poster.jpg"
},
"Captions": [],
"Tags": ["demo", "product"],
"Formats": { "HLS": true, "MP4": false, "resolutions": "360p,720p,1080p" },
"Created": "2026-09-26T10:30:00Z"
},
"firedAt": "2026-09-26T10:34:12.482Z"
}Member events
json
{
"event": "memberCreated",
"member": {
"Id": "8f7e6d5c-4b3a-2918-7766-554433221100",
"Email": "student@example.com",
"FirstName": "Sam",
"LastName": "Lee",
"Status": "active",
"PlanId": "1a2b3c4d-5e6f-7081-92a3-b4c5d6e7f809"
},
"firedAt": "2026-09-26T10:35:00.000Z"
}Connect anything via Zapier
Point your webhook at a Zapier Catch Hook and route events to 6,000+ apps (Mailchimp, HubSpot, Slack, Google Sheets, …).
- In Zapier create a Zap with the trigger Webhooks by Zapier → Catch Hook and copy the hook URL.
- Paste it as your endpoint URL in Global Settings → Webhooks and pick events.
- Click Send test event — it becomes the Zap's sample — then map fields to any action app.
Every delivery (status code, time, target URL) is listed under Global Settings → Webhooks → Recent deliveries.