
The dashboard's Player Session settings cover the basics: a handful of colors, thumbnail height, track height. If you're managing one video on one site, that's plenty. If you're building a platform where hundreds of customers each need their own branded player, or you just want theme changes to happen from code instead of a settings page, AIOZ Stream has a separate Player Theme API that goes considerably further than the dashboard UI lets on.
TL;DR:
api.aiozstream.network/api/players, independent of the dashboard's Player Session screenAIOZ Stream ships two separate paths to a themed player. The one covered in the embedding guide is the dashboard's Player Session screen: log in, name a session, pick colors from a form, save, apply it to a video from a dropdown. It's built for doing this once or twice by hand.
The second path is the Player Theme API, a REST resource under /api/players with create, read, update, delete, list, and two logo-specific endpoints on top. It's built for the opposite case: an app that creates a theme automatically when a customer signs up, or a pipeline that pushes theme updates the same way it pushes any other config change.
Worth knowing before you start: the two don't expose identical fields. The dashboard groups colors under labels like Main Color and Track Color. The API's theme object is named differently and split more finely, with separate fields for the control bar, the menu, and the progress bar. Both style the same player, but if you've configured a theme in the dashboard and go looking for a field called main_color in the API to match it, expect to map some of it by eye rather than by name.
A theme is created with a POST to the players endpoint. Colors go in as rgba strings, dimensions as pixel values:
curl -X POST https://api.aiozstream.network/api/players \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "acme-brand-theme",
"theme": {
"main_color": "rgba(255, 87, 34, 1)",
"control_bar_background_color": "rgba(0, 0, 0, 0.7)",
"control_bar_height": "48px",
"progress_bar_height": "4px",
"progress_bar_circle_size": "12px",
"menu_background_color": "rgba(20, 20, 20, 0.95)",
"menu_item_background_hover": "rgba(255, 87, 34, 0.2)",
"text_color": "rgba(255, 255, 255, 1)",
"text_track_color": "rgba(255, 255, 255, 1)",
"text_track_background": "rgba(0, 0, 0, 0.6)"
},
"is_default": false
}'The response returns the new theme's ID, which is what you'll use for every other call: uploading a logo, applying it to a video, or updating it later. Set is_default to true if this theme should apply automatically to videos that don't have one explicitly assigned; leave it false for a theme you plan to attach on purpose.
Colors alone don't remove AIOZ Stream's own branding from the player. That's a separate step: uploading a logo to the theme through its own endpoint.
curl -X POST https://api.aiozstream.network/api/players/PLAYER_THEME_ID/logo \
-H "Authorization: Bearer YOUR_API_KEY" \
-F "logo=@./acme-logo.png" \
-F "logo_link=https://acme.example.com"The constraints are specific and easy to trip on if you're reusing a logo built for something else: image/jpeg or image/png only, a hard cap of 100 KiB, and a maximum size of 200x100px. That's a small, wide logo, closer to a wordmark than a square icon. Resize and compress before uploading rather than after a rejected request tells you why. The optional logo_link makes the logo clickable, useful if you want viewers who tap your brand mark to land on your own site instead of AIOZ's. Removing a logo later is a plain DELETE to the same /logo path, no payload needed.
Alongside colors, a theme carries a separate set of controls fields that change how the player behaves, not just how it looks. These aren't in the dashboard at all:
curl -X PATCH https://api.aiozstream.network/api/players/PLAYER_THEME_ID \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"controls": {
"force_autoplay": true,
"force_loop": false,
"hide_title": true,
"enable_controls": true,
"enable_api": true
}
}'hide_title is the one that matters most for white-labeling specifically, since it's what strips the video's title text off the player chrome rather than just recoloring it. force_autoplay and force_loop do what they say, useful for background-video or kiosk-style placements where you don't want a viewer to hunt for a play button. enable_api turns on a JavaScript control interface for the embedded player itself, separate from the server-side Developer API covered in the API and SDKs guide, and only worth enabling if your frontend actually needs to drive playback programmatically (pause on scroll, sync with another element on the page, that kind of thing).
Creating a theme doesn't attach it to anything by itself. That's a separate call that pairs a video ID with a theme ID:
curl -X POST https://api.aiozstream.network/api/players/add-player \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"video_id": "VIDEO_ID",
"player_theme_id": "PLAYER_THEME_ID"
}'The same pairing in reverse, /players/remove-player, detaches a theme from a video without deleting the theme itself, which matters if you're reusing one theme across many videos for the same customer and just need to unassign it from one. Because the pairing lives on the video, not on the embed URL, the iframe code from the embedding guide stays exactly the same before and after you apply a theme. Nothing about the src URL changes.
Once you're managing more than a handful of themes, usually one per customer in a multi-tenant setup, the list endpoint is what you'll reach for most. It supports the pagination and sorting you'd expect from a real resource collection:
curl "https://api.aiozstream.network/api/players?limit=25&offset=0&sort=created_at&order_by=desc" \
-H "Authorization: Bearer YOUR_API_KEY"Two operational details are worth planning around rather than discovering during an incident. First, updates to a theme don't take effect instantly. AIOZ's own documentation states plainly that "it may take up to 10 min before the new player configuration is available from our CDN", so a theme change made right before a launch or a demo needs that buffer built in, not tested five seconds after the PATCH request returns 200. Second, deletion is guarded: a theme still assigned to at least one video will not be deleted, full stop. Detach it from every video with /remove-player first, then delete it.
Putting the pieces in order, here's what standing up a fully white-labeled player for one customer actually looks like end to end:
API_KEY="your_api_key"
BASE="https://api.aiozstream.network/api/players"
# 1. Create the theme
THEME_ID=$(curl -s -X POST "$BASE" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{"name":"acme-brand-theme","theme":{"main_color":"rgba(255,87,34,1)"}}' \
| jq -r '.id')
# 2. Upload the customer's logo
curl -s -X POST "$BASE/$THEME_ID/logo" \
-H "Authorization: Bearer $API_KEY" \
-F "logo=@./acme-logo.png" \
-F "logo_link=https://acme.example.com"
# 3. Hide the default title and force autoplay
curl -s -X PATCH "$BASE/$THEME_ID" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{"controls":{"hide_title":true,"force_autoplay":true}}'
# 4. Attach it to the customer's video
curl -s -X POST "$BASE/add-player" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d "{\"video_id\":\"$VIDEO_ID\",\"player_theme_id\":\"$THEME_ID\"}"Run that whole sequence in your own onboarding flow (say, right after a new customer connects their account) and every video they upload from then on plays back inside a player that carries their brand, not AIOZ's, with no dashboard clicking involved. For the SDK equivalent of these same calls in Node.js or Go instead of raw curl, see the Node.js SDK guide.
Single-site embedding rarely needs any of this. The dashboard's Player Session screen exists because most people configure a theme once and move on. The API earns its complexity in a narrower set of cases: a SaaS product reselling video hosting under its own brand, an agency managing themes for a dozen clients from one internal tool, or any workflow where clicking through a settings form doesn't scale to the number of themes you actually need. If that's not your situation, the dashboard is still the right tool, not a workaround.
Do I need to use the Player Theme API, or is the dashboard enough?
For a single site or a handful of videos, the dashboard's Player Session screen is enough and simpler. Reach for the API when you're creating themes programmatically, per customer, or as part of an automated pipeline.
Can I fully remove all AIOZ Stream branding from the player?
The documented controls get you most of the way: hide_title removes the title text, and a custom logo replaces AIOZ's mark. Whether every last trace of AIOZ branding disappears from the player chrome isn't explicitly documented, so verify against a real preview before promising a client a fully unbranded player.
Why does my logo upload get rejected?
Almost always size or format. The limit is a strict 100 KiB and 200x100px, JPEG or PNG only. A logo built for a website header is usually too large in both file size and pixel dimensions and needs resizing first.
How long after I update a theme does the change show up for viewers?
Up to 10 minutes, per AIOZ's own documentation. Build that delay into any launch or demo timing rather than assuming an update is live the moment the API call succeeds.
Why won't a theme delete?
Because it's still attached to at least one video. Detach it from every video with the remove-player endpoint first, then delete it.
Do the dashboard's color fields and the API's theme fields map one to one?
Not by name. The dashboard groups colors under simpler labels (Main Color, Track Color, and so on), while the API's theme object splits the same visual areas into more specific fields for the control bar, menu, and progress bar. Match them visually rather than assuming a direct field-name correspondence.
For background on the color format used throughout the theme object, MDN has a full reference on the rgb() and rgba() color functions, and on the image formats accepted for the logo upload.

How AIOZ Stream wallet billing actually works: token deposits, conversion rates, why the network matters, and the volatility risk fiat billing never has.

Glass-to-glass latency is camera-to-screen delay, the only number that matches what viewers feel. Here is what causes it, and how to measure it yourself.

A complete guide to how AIOZ Stream pricing actually works: the three cost components, hourly wallet billing, and where decentralized delivery beats AWS.

Low-Latency HLS cuts glass-to-glass delay from 30 seconds to about 2 to 5 seconds. Here is how LL-HLS actually works, what it costs, and when to use it.

A complete guide to the AIOZ Stream video player: what it does out of the box, two different paths to customizing it, and what still requires the API.

How to white-label the AIOZ Stream video player via the Player Theme API: creating a theme, uploading a logo, and every controllable field it supports.