# Mux Webhooks

## When to Use This Skill

* How do I receive Mux webhooks?
* How do I verify the Mux webhook `mux-signature` header?
* How do I know when a Mux asset is ready for playback (`video.asset.ready`)?
* How do I handle Mux direct upload or live stream webhook events?
* Why is my Mux webhook signature verification failing?

## Verification (core)

Every Mux webhook carries a `mux-signature` header of the form `t=<unix seconds>,v1=<hex>`. The `v1` value is **HMAC-SHA256** (hex) of `"<t>.<raw body>"`, keyed with the endpoint's signing secret. Reject timestamps older than **5 minutes** (the SDK default). Always use the **raw** request body.

```javascript
const crypto = require('crypto');

function verifyMuxSignature(rawBody, header, secret, toleranceSec = 300) {
  const parts = Object.fromEntries((header || '').split(',').map((p) => p.trim().split('=', 2)));
  const timestamp = Number(parts.t);
  if (!Number.isInteger(timestamp) || !parts.v1) return false;
  if (Math.abs(Date.now() / 1000 - timestamp) > toleranceSec) return false;

  const expected = crypto.createHmac('sha256', secret)
    .update(`${parts.t}.${rawBody}`)          // "<timestamp>.<raw body>"
    .digest('hex');
  const a = Buffer.from(expected);
  const b = Buffer.from(parts.v1);
  return a.length === b.length && crypto.timingSafeEqual(a, b);
}

```

With the official Node SDK ([`@mux/ts`](https://www.npmjs.com/package/@mux/ts), formerly `@mux/mux-node`) the same check plus JSON parsing is one call:

```javascript
const event = await mux.webhooks.unwrap(rawBody, req.headers, process.env.MUX_WEBHOOK_SECRET);
// throws on a missing/invalid signature or a timestamp older than 5 minutes

```

> **For complete handlers with tests**, see [examples/express/](https://github.com/hookdeck/webhook-skills/tree/main/skills/mux-webhooks/examples/express/), [examples/nextjs/](https://github.com/hookdeck/webhook-skills/tree/main/skills/mux-webhooks/examples/nextjs/), [examples/fastapi/](https://github.com/hookdeck/webhook-skills/tree/main/skills/mux-webhooks/examples/fastapi/). Express and Next.js use the SDK; FastAPI verifies manually (the Mux Python SDK has no webhook helper).

## Common Event Types

| Event | Triggered When |
| --- | --- |
| `video.asset.created` | An asset has been created |
| `video.asset.ready` | Asset is ready for playback via its `playback_id` |
| `video.asset.errored` | Asset failed (bad input URL, invalid video file, …) |
| `video.asset.deleted` | Asset has been deleted and is no longer playable |
| `video.asset.live_stream_completed` | A live stream ended and its recorded asset is complete |
| `video.upload.asset_created` | A direct upload finished and created an asset |
| `video.live_stream.active` | A live stream is active and can be played |
| `video.live_stream.idle` | A live stream's reconnect window elapsed; status is now `idle` |

The event type is in the payload's `type` field; the resource is in `data`, and `object.id` / `object.type` identify it.

> **For the full event list** (assets, static renditions, tracks, uploads, live streams, simulcast targets), see [references/overview.md](https://github.com/hookdeck/webhook-skills/blob/main/skills/mux-webhooks/references/overview.md) and [Mux's webhook docs](https://www.mux.com/docs/core/listen-for-webhooks#types-of-events).

## Environment Variables

```bash
# Signing secret for THIS webhook endpoint (Dashboard > Settings > Webhooks)
MUX_WEBHOOK_SECRET=your_mux_webhook_signing_secret

```

Each webhook endpoint has its own signing secret. `MUX_WEBHOOK_SECRET` is also the variable the `@mux/ts` client reads by default.

## Local Development

```bash
# Start tunnel (no account needed)
npx hookdeck-cli listen 3000 mux --path /webhooks/mux

```

## Reference Materials

* [references/overview.md](https://github.com/hookdeck/webhook-skills/blob/main/skills/mux-webhooks/references/overview.md) - Mux webhook concepts, full event list, payload shape
* [references/setup.md](https://github.com/hookdeck/webhook-skills/blob/main/skills/mux-webhooks/references/setup.md) - Dashboard and API configuration, signing secret
* [references/verification.md](https://github.com/hookdeck/webhook-skills/blob/main/skills/mux-webhooks/references/verification.md) - Signature verification details and gotchas