<iframe src="https://acme.xform.media/_embed/intro">Point xform at a video in your source (S3, R2, etc.) or upload directly to xform via a presigned URL if you don't need the source file in your own storage.
xform automatically transcodes your video into multiple HLS quality levels (1080p, 720p, 480p) plus an MP4 download, thumbnail, and optional captions.
Serve adaptive bitrate HLS from the edge. Embed the player with a single line of code or use the raw HLS manifest directly in your own player.
Built-in analytics track views, engagement heatmaps, caption searches, UTM campaigns, quality distribution, and referrers - no third-party scripts needed.
import { XformClient } from '@xformmedia/sdk'
const client = new XformClient({ ... })
// Returns an iframe HTML string
const html = client.embed('intro', {
autoplay: false,
quality: 'auto',
captions: true,
color: '6366f1'
})<!-- Embed player via iframe -->
<iframe
src="https://acme.xform.media/_embed/intro?captions=1"
width="100%"
height="100%"
frameborder="0"
allowfullscreen
></iframe>
<!-- Or use HLS directly -->
<!-- https://acme.xform.media/_v/intro.m3u8 -->| Quality | Bitrate | Notes |
|---|---|---|
1080p | 4 Mbps | Only if source is 1080p or higher |
720p | 2 Mbps | Only if source is 720p or higher |
480p | 800 kbps | Always included (minimum) |
Adaptive bitrate M3U8 manifests for seamless quality switching.
Progressive download with faststart for instant playback.
Auto-extracted poster image at 1280px wide.
VTT extraction from source or manual upload via SDK.
Renditions are automatically filtered - xform never upscales. A 720p source produces 720p and 480p, not 1080p.
| Method | Description |
|---|---|
client.createUploadUrl() | Get a presigned URL to upload directly to xform (not your source) |
client.ingest({ key }) | Trigger transcoding for an uploaded video |
client.events() | Real-time SSE stream of video status changes |
client.embed(videoKey) | Generate an iframe embed code |
client.videos.list() | List all videos with pagination |
client.videos.get(key) | Get video metadata, status, and renditions |
client.videos.analytics() | Query views, heatmaps, UTM campaigns, searches, and quality metrics |
client.videos.uploadCaptions() | Upload or replace WebVTT captions |
client.videos.delete(id) | Delete video and all transcoded assets |
npm install @xformmedia/sdkconst client = new XformClient({
sourceId: 'src_...',
organizationId: 'org_...',
apiKey: 'xfm_...',
baseUrl: 'https://admin.xform.media',
streamBaseUrl: 'https://acme.xform.media'
})
const { key } = await client.createUploadUrl({
filename: 'demo.mp4',
contentType: 'video/mp4'
})
const { videoKey } = await client.ingest({ key })video.readyTranscoding completed - includes stream URL, duration, dimensions, and thumbnail.
video.failedTranscoding failed after 3 retry attempts - includes error message.
video.renamedVideo display name was changed.
Total views, unique sessions, and daily trends.
See which parts of your video are most watched, rewatched, or skipped.
Track campaign performance with UTM parameters on your embed URLs.
See what viewers search for in your captions and whether they find it.
Top referring domains, quality distribution, and switching patterns.
Analytics are collected automatically by the embed player - no extra scripts or configuration needed.
Your videos live in S3, R2, or any supported storage. xform reads from your source and stores transcoded files on our infrastructure.
Serve video from your own subdomain. Custom domains work for both images and video.
Source-scoped API keys give you fine-grained control. Credentials are encrypted at rest.