Webhooks
Subscribing to streaming.video.{ready,errored} events.
When Mux completes (or fails) transcoding a submitted asset, PlatformXe receives a webhook from Mux, applies the terminal state to the row, and relays a normalised event to every webhook subscriber registered for that caller service. This is the same outbound webhook infrastructure used for every other PlatformXe event (deliveries logged, HMAC-signed with each subscriber's per-app secret, retried with exponential backoff).
Event types
| Event | When | Payload status |
|---|---|---|
streaming.video.ready | Mux finished transcoding successfully | status: 'ready', muxPlaybackId populated, durationSeconds populated |
streaming.video.errored | Mux rejected the source or failed mid-transcode | status: 'errored', errorMessage populated |
Non-terminal Mux events (asset.preparing, asset.created, etc.) are tracked on the asset row but not relayed — subscribers only see terminal transitions.
Payload shape
interface StreamingVideoEventPayload {
version: 1;
event: 'streaming.video.ready' | 'streaming.video.errored';
assetId: string; // PlatformXe streaming_assets.id
callerService: string;
module: string; // e.g. 'properties'
entityId: string; // e.g. property id
callerRef: string | null; // Whatever you passed at submit time
muxAssetId: string | null;
muxPlaybackId: string | null;
durationSeconds: number | null;
status: 'pending' | 'ready' | 'errored';
errorMessage: string | null;
}
The outbound webhook envelope wraps this as { event, event_id, timestamp, data: <payload> } — see the Webhooks service for the standard envelope and HMAC headers.
Subscribing
Each caller service registers ONE webhook URL that subscribes to both events (or streaming.video.* for the whole group). For Lettings this is bootstrapped via:
npx tsx --env-file=.env scripts/seed-lettings-streaming-webhook.ts -- --env=prod
The seed script prints a per-subscription HMAC signing secret exactly once — copy it into the caller service's env as PLATFORMX_STREAMING_WEBHOOK_SECRET (or your service's equivalent).
Idempotency
Webhook deliveries can land more than once (PlatformXe retries on non-2xx). Consumers should make their handler safe to re-apply — typically a row UPDATE keyed on assetId or callerRef.
Missed webhooks
If a delivery fails after all retries (10 attempts over ~50 minutes by default), the asset's terminal state still lives in PlatformXe. Callers can fall back to polling GET /assets/[id] — the live-sync behaviour will refresh from Mux on demand.