PlatformXeDocs
Get API Key

Streaming / Video Overview

Provider-backed video transcoding and HLS playback for property tours and other long-form video.

The Streaming Service transcodes uploaded videos into adaptive-bitrate HLS plus downloadable MP4 renditions, then notifies caller services via webhook when the asset is ready to play. Today it's backed by Mux; the dispatcher is built so a second provider (Cloudflare Stream, Bunny.net, etc.) can be added without changing the caller-facing API.

What it does

  • Transcoding — phone-camera videos arrive in wildly different codecs (iPhone HEVC in .mov, Android VP9 in .webm, WhatsApp's .mp4). The streaming service hands the file to Mux which normalises everything to h.264 + AAC HLS with multiple bitrate variants.
  • Adaptive bitrate playback — the player picks 480p on mobile, 1080p on desktop, automatically.
  • Thumbnails — Mux auto-generates a still-frame thumbnail and an animated GIF preview.
  • Faststart MP4 — for share-by-link or fallback when HLS isn't available.

What it does not do

  • AI upscaling / denoise / "enhancement" — Mux is a transcoder, not an enhancer. If you need to repair a low-quality source, that's a different vendor (Topaz Video AI, Adobe Firefly).
  • Live streaming — the current configuration is on-demand only.
  • Signed / private playback — assets use playback_policy: ['public'] for now. Signed playback can be added when paywalled content lands.

Auto-orchestration with Storage

If a caller service uses the Storage service to upload a video (via POST /api/v1/storage/media/upload or the sign-upload + register direct path), the storage dispatcher automatically submits the video to streaming. Callers don't need to call the streaming API explicitly — the storage upload response includes streamingAssetId for follow-up lookups.

For callers that own their own upload path (e.g. Lettings uploading directly to its own Supabase bucket without going through PlatformXe storage), call POST /api/v1/streaming/video/submit with the public URL.

Scopes

ScopeRequired for
streaming:submitPOST /api/v1/streaming/video/submit
streaming:readGET /api/v1/streaming/video/assets/[id]

Both are granted by default to lettings and concierge (see Scope Catalog).

Pipeline at a glance

Caller          PlatformXe              Mux
  │                  │                   │
  │ POST submit      │                   │
  ├─────────────────►│                   │
  │  { sourceUrl }   │ HEAD sourceUrl    │
  │                  │ pre-check         │
  │                  │ ─ ─ ─ ─ ─ ─ ─ ►   │
  │                  │ POST /video/v1/   │
  │                  │ assets {input}    │
  │                  ├──────────────────►│
  │                  │ { id }            │
  │                  │◄──────────────────┤
  │ 201 { asset,    │                   │
  │   status:pending}│                   │
  │◄─────────────────┤                   │
  │                                      │
  │  ── Mux transcodes asynchronously ── │
  │                                      │
  │                  POST webhooks/mux   │
  │                  ◄───────────────────┤
  │                                      │
  │  ── PlatformXe relays via            │
  │     WebhookAPI to subscribers ──     │
  │                                      │
  │ POST /api/webhooks/<your-app>/streaming
  │ ◄─── { event: 'streaming.video.ready',
  │       muxPlaybackId, durationSeconds, … }

Webhook events

EventWhenPayload
streaming.video.readyMux finished transcoding successfullyFull StreamingVideoEventPayload with muxPlaybackId populated
streaming.video.erroredMux rejected the source (bad codec, truncated file, content-moderation)Same shape with errorMessage populated

See Submit a video for the request schema and Playback URLs for the URLs you can build from a muxPlaybackId.

Failure modes

  • Mux credentials missing on PlatformXesubmit succeeds but the row is created with status: 'errored' and an error message. No call to Mux is attempted.
  • Source URL unfetchablesubmit returns 400 with SOURCE_UNREACHABLE (or related probe codes) before the Mux call when the soft probe has positive evidence. Call POST /api/v1/media/probe in strict mode earlier in your flow for partner-facing errors.
  • Webhook missed — the next GET /assets/[id] poll detects status: 'pending' and refreshes from Mux's authoritative state, recovering automatically.
  • Provider outage mid-transcode — Mux retries internally; if it gives up, fires streaming.video.errored which PlatformXe relays. Caller decides whether to resubmit.