Signed webhooks are live today: stream started, stream ended, a destination failing mid-broadcast, a recording finishing. A public REST API is planned but isn’t built yet — we’d rather say that plainly than list endpoints that don’t exist.
An enhancement beyond the streaming platform we're built on parity with — theirs has no webhook system at all. HMAC-signed, retried on failure, with a full delivery log.
Settings → Webhooks → Add endpoint. Give it an https:// URL, an optional label, and check the events you want.
CastFork shows the whsec_… signing secret exactly once on save. Rotate the endpoint to mint a new one if you lose it.
Every delivery carries castfork-signature (t=…,v1=…) — HMAC-SHA256 of the timestamp and raw body, keyed with your secret.
Anything else, or a timeout past 10 seconds, counts as a failure and gets retried on a backoff schedule.
| Type | Fires when | data |
|---|---|---|
| stream.started | An ingest goes live and fan-out begins | session, destinations[] |
| stream.ended | A live session closes | session (startedAt, endedAt) |
| destination.failed | A destination errors mid-broadcast | session, destination (errorCode) |
| recording.ready | A cloud recording finishes processing | session, recording (id, key, bytes, durationS) |
Payloads never carry secrets — no RTMP URL, no stream key. Per-plan endpoint caps: Free 1, Standard 3, Professional 5, Business 10, Enterprise 20.
const crypto = require("node:crypto");
function verifyCastforkWebhook(rawBody, header, secret, toleranceSec = 300) {
// header: "t=1752345791,v1=abc123…"
const parts = Object.fromEntries(
header.split(",").map((kv) => kv.split("=").map((s) => s.trim())),
);
const t = Number(parts.t);
if (!Number.isFinite(t)) return false;
if (Math.abs(Date.now() / 1000 - t) > toleranceSec) return false; // stale
const expected = crypto
.createHmac("sha256", secret)
.update(`${t}.${rawBody}`)
.digest("hex");
const a = Buffer.from(expected);
const b = Buffer.from(parts.v1 ?? "");
return a.length === b.length && crypto.timingSafeEqual(a, b);
}We’re planning a public API covering channels, stream cards, and events — mirroring the same shapes the CastFork app itself uses internally. Until it ships, webhooks are the supported way to react to what’s happening on your account from your own code.
Webhooks
API roadmap
Free covers two destinations at once, no time limit, no card required.