A reference for LLMs and AI agents writing code against the Mux API.
This guide is written for LLMs and AI coding agents. It contains everything you need to write working code against the Mux API on the first try.
The Mux CLI (@mux/cli) lets you manage Mux resources directly from the terminal. It is useful for quick operations, scripting, automation, and CI/CD pipelines.
Install:
npm install -g @mux/cli # global install
# or run directly without installing:
npx @mux/cli
# or install via Homebrew:
brew install muxinc/tap/muxAfter installing, authenticate with mux login or set MUX_TOKEN_ID and MUX_TOKEN_SECRET environment variables. Always pass --agent to optimize output for AI agents (includes JSON output).
Common commands:
| Command | What it does |
|---|---|
mux assets create --input-url URL | Create an asset from a URL |
mux assets create --file video.mp4 | Upload a local file |
mux assets list | List assets |
mux assets get ${ASSET_ID} | Get asset details |
mux assets delete ${ASSET_ID} | Delete an asset |
mux live-streams create | Create a live stream |
mux uploads create | Create a direct upload URL |
mux sign ${PLAYBACK_ID} | Generate a signed playback URL |
Use --wait to block until an asset is ready:
mux assets create --input-url "https://example.com/video.mp4" --wait --agentFor the full list of commands, see the CLI documentation.
video.asset.readyBefore you can make API calls, your user needs to set up a Mux account and provide you with API credentials.
Store the credentials as environment variables:
MUX_TOKEN_ID=your-token-id
MUX_TOKEN_SECRET=your-token-secretFor details on how authentication works, see the make API requests guide.
Never expose API credentials in client-side code. All Mux API calls must be made from a server.
This is for when you have a small, constrained number of videos — a hero video or background video on your homepage, a demo reel, or a few dozen videos across your site. The key characteristic is that the set of videos doesn't change often and is manageable enough to hardcode.
In this case, you can hardcode playback IDs directly in your code or extract them into a JSON config file with metadata:
{
"videos": [
{ "title": "Hero Video", "playbackId": "TXjw00EgPBPS6acv7gBUEJ14PEr5XNWOe" },
{ "title": "Product Demo", "playbackId": "a4nOgR00sKz6cMWLeM5skT8ePBn7U6gC5" }
]
}Then use Mux Player to embed each video:
import MuxPlayer from '@mux/mux-player-react';
<MuxPlayer playbackId="TXjw00EgPBPS6acv7gBUEJ14PEr5XNWOe" />To create your assets and get playback IDs, use the CLI (mux assets create --input-url URL --wait --json) or the stream video files guide.
This is for when videos are uploaded dynamically as part of your application. Common scenarios include:
For these use cases, you will need to:
video.asset.ready), when it errors, or when it's deletedOfficial server-side SDKs:
Unless the user specifies otherwise, use these values:
| Parameter | Default to use | Notes |
|---|---|---|
playback_policy | ["public"] | Use "signed" only if the user needs secure/private playback |
video_quality | "basic" | No encoding costs and great for most use cases. Use "plus" if the user needs higher quality encoding |
static_renditions | Do not set | Only set if the user explicitly needs downloadable MP4/M4A files. See the static renditions guide |
max_resolution_tier | Do not set | Defaults to 1080p. Set to "2160p" only if the user requests 4K |
playback_policy: "public" allows open access. Use "signed" for secure video playback with signed JWTs.video_quality: See pricing for the difference between "basic" and "plus".static_renditions: Replaces the deprecated mp4_support parameter. Use [{ "resolution": "highest" }] for an MP4 download or [{ "resolution": "audio-only" }] for an M4A file. See the static renditions guide for all options.After creating an asset, save the relevant data into your database or persistence layer. At minimum, store the asset ID and playback ID. You will also want to save metadata as it becomes available: status, duration, aspect_ratio, resolution_tier, and any static_renditions information.
For simple integrations with a fixed set of videos — hero videos, background videos, demo reels on a marketing site — you can hardcode playback IDs in a JSON file or config object. These rarely change and don't need a database.
For production applications where users upload videos, videos are created programmatically, or the video catalog changes over time, always persist asset data in a database. Use webhooks to keep your database in sync — listen for video.asset.ready to update status, and video.asset.deleted to clean up records.
| ID type | What it's for |
|---|---|
| Asset ID | Managing the asset (get, update, delete) via api.mux.com |
| Playback ID | Streaming the video via stream.mux.com |
| Upload ID | Tracking direct upload status |
| Stream Key | Broadcasting to a live stream (keep secret) |
| Live Stream ID | Managing the live stream via api.mux.com |
Do NOT confuse Asset IDs with Playback IDs. Asset IDs are for API operations (api.mux.com). Playback IDs are for streaming (stream.mux.com). They are different strings.
Do NOT use the playback URL before the asset is ready. Always check status === "ready" first. A playback URL for a preparing asset will not work.
Do NOT construct playback URLs with the Asset ID. The correct URL is https://stream.mux.com/{PLAYBACK_ID}.m3u8, not https://stream.mux.com/{ASSET_ID}.m3u8.
Do NOT expose API keys in client-side code. API credentials (Token ID and Token Secret) must never be included in frontend JavaScript, mobile apps, or any code that runs on the user's device. All Mux API requests must be made from a trusted server.
Do NOT expose stream keys in client-side code. Stream keys allow anyone to broadcast to your live stream. Keep them server-side only.
Do NOT hardcode playback URLs. Always construct them from the playback ID returned by the API.
Do NOT poll more than once per second. The API has rate limits. Poll every 2 seconds for asset status.
Do NOT use POST endpoints at high volume without backoff. POST requests are rate limited to ~1 request per second sustained. GET requests allow ~5 per second.