Payload Plugins
Pluginspayload-mux

Endpoints & webhooks

Finish long-encoding videos, sync Mux-dashboard deletes, and ingest video in code — the endpoints and webhook that keep Payload and Mux in step.

For AI / LLMs: View Markdown

The plugin mounts three HTTP endpoints and expects one Mux webhook. Together they finish slow-encoding videos, mirror Mux-dashboard deletes back into Payload, and let you create a video entirely in code.

Endpoints

The plugin registers three endpoints under Payload's API route. The upload pair is gated by the options.access.upload option.

EndpointWhat it does
POST /api/mux/uploadMint a Mux direct-upload. The admin uploader posts files to it.
GET /api/mux/upload?id=…Read a direct-upload, to pick up its asset_id.
POST /api/mux/webhookVerify and apply Mux events: set metadata on ready/updated, delete on deleted, log on errored, and (with autoCreateOnWebhook) backfill assets uploaded in Mux.

Webhook

On upload, the beforeChange hook polls the new asset for ~6 seconds. If Mux finishes encoding in that window, the hook fills in the playback metadata inline. Anything slower is saved with just its assetId and left for the webhook.

Point a Mux webhook at /api/mux/webhook (or <your routes.api>/mux/webhook if you've customized Payload's API route). Set MUX_WEBHOOK_SECRET so the plugin can verify each event's signature.

The webhook needs a publicly reachable URL. Mux pushes events to your endpoint, so its servers must be able to POST to it. The SDK only verifies the signature on receipt — it can't make Mux reach localhost. In production, set MUX_WEBHOOK_SECRET and point the dashboard at https://your-site/api/mux/webhook. For local dev, expose localhost with a tunnel (cloudflared tunnel --url http://localhost:3000 or ngrok) and set that URL as the webhook.

Not every flow depends on the webhook. Use the split below to know what breaks without it.

  • Metadata for videos that take longer than ~6s to encode, without anyone touching the doc. The common case. The upload's poll gives up at ~6s and the webhook is what fills playbackOptions in on its own. Without it the video stays preparing until someone saves the doc, which refetches from Mux — so a missed event is recoverable, but only by hand. See Troubleshooting.
  • Mux → Payload delete sync. Deleting an asset in the Mux dashboard removes the Payload doc only via the video.asset.deleted event.
  • autoCreateOnWebhook backfill. Importing assets you uploaded directly in Mux.
  • The upload itself, and metadata for short videos (set synchronously by the 6s poll).
  • Recovering a video stuck on preparing. Saving the doc refetches the asset from Mux, so a webhook you never received doesn't strand the video.
  • Payload → Mux delete. Handled by the collection's afterDelete hook, not the webhook.
  • Server-side ingest / seeding. The 6s limit doesn't apply; ingest waits for ready and writes full metadata into the doc, so these play straight away whatever their length.
  • Playback of already-populated videos: the URLs compute on read from the stored playback id.

Server-side ingest

Besides the browser uploader, a mux-video can be created server-side from a local file or URL. This is handy for imports, migrations, and seeding. Pass a source; the beforeValidate hook uploads it to Mux, waits for the asset to be ready, fills in the metadata, and discards source.

import { ingestMuxVideo } from '@pro-laico/payload-mux'

await ingestMuxVideo(payload, { source: '/path/to/intro.mp4', title: 'Intro' })
// or a URL: ingestMuxVideo(payload, { source: 'https://example.com/intro.mp4', title: 'Intro' })
// playback policy comes from the plugin's `options.playbackPolicy`; pass { playbackPolicy: 'signed' } to override one video
// posterTimestamp: 12.5 picks the poster frame; defaults to the middle of the video
// collection: 'media' — only if you renamed the collection AND `payload` was built without the plugin; otherwise the marker's slug is used

Local paths stream from disk, so ingesting a large file doesn't load it all into memory. Ingest is also what powers declarative seeding — see How it works.

Next

  • Use a video — relate, play back, and sign playback URLs.
  • How it works — the asset lifecycle, revalidation, and seeding.
  • Troubleshooting — videos stuck on "preparing" and other fixes.

On this page