Embedding a video

Every published embed uses a ten-character workspace public ID and video public ID. You can find both in the video’s share details. The current edge URL includes both IDs.

The video must be Public or Unlisted to play outside Playflow. A private video shows “This video is private” in the embed. See Visibility & sharing.

Script embed

The one we recommend. Drop the loader once per page, then a div wherever you want a video. It sizes itself, lazy-loads, and you can put as many on a page as you like.

HTML
<script src="https://v.getplayflow.co/embed.js" data-playflow-workspace="WORKSPACE_PUBLIC_ID" async></script>

<div data-playflow-video="VIDEO_PUBLIC_ID"></div>

The script scans for [data-playflow-video] when it loads. Place the video divs in the page before the loader runs, including when using a site builder.

Iframe embed

Background video

In Share & Embed, choose Background video. Use the script snippet first: it makes the iframe non-focusable and passes clicks through to the page. If your plan requires the Playflow watermark, the loader places one clickable watermark over the video and removes the internal copy. Paid plans without the watermark do not show it.

Same video, two independent players
<div id="hero-video" data-playflow-video="VIDEO_PUBLIC_ID" data-playflow-mode="background"></div>
<div id="watch-video" data-playflow-video="VIDEO_PUBLIC_ID" data-playflow-mode="standard"></div>
<script src="https://v.getplayflow.co/embed.js" data-playflow-workspace="WORKSPACE_PUBLIC_ID" defer></script>

Background mode forces muted autoplay, looping and inline playback. It hides controls, play and replay buttons, the unmute indicator, title, tenant branding and captions. It uses fill-and-crop sizing, starts adaptive playback at a 720p preference, and shows only the poster if autoplay is blocked or the viewer prefers reduced motion. There is no silent fallback play button.

An explicit data-playflow-mode="background" or data-playflow-mode="standard" overrides the video's setting in either direction. Without it, the video setting wins, then the workspace default. A share link uses the saved default; Background share links are full-bleed. Standard players keep fit sizing and their normal controls.

Plain iframe alternative
<iframe src="https://v.getplayflow.co/WORKSPACE_PUBLIC_ID/e/VIDEO_PUBLIC_ID?mode=background"
  tabindex="-1" allow="autoplay" style="width:100%;height:100%;border:0;pointer-events:none"></iframe>

A plain iframe cannot pass clicks through by itself. The host CSS pointer-events: none above also makes its required internal watermark unclickable. Use the script embed for a clickable watermark. Set a height on the host container when filling a background area. The Player API addresses each instance independently by its element or element ID.

Starting quality: Auto, Start at 360p, Start at 480p, Start at 720p, Start at 1080p, Start at 1440p, or Start at 4K (2160p). Starts here, then adjusts to the viewer's connection like Auto. Use data-start-quality on the script-embed div or start_quality in an iframe/watch URL, with auto, 360, 480, 720, 1080, 1440, or 2160. Unset inherits video, then workspace settings. Invalid values warn and are ignored. Only available source renditions are used, without upscaling. This does not fix in-play quality; see Starting quality and preload.

Use this when you can’t add a script. Some CMS and email-adjacent tools only allow iframes.

Keep screen-wake-lock in the iframe allow attribute. Standard playback requests a screen wake lock while playing and releases it on pause, end, or when the tab is hidden. Returning to a visible tab requests it again if playback continues. Background mode never takes a wake lock. Unsupported browsers, battery-saving restrictions, and denied permissions do not interrupt playback.

HTML
<iframe
  src="https://v.getplayflow.co/WORKSPACE_PUBLIC_ID/e/VIDEO_PUBLIC_ID"
  style="aspect-ratio:16/9;width:100%;border:0"
  allow="autoplay; fullscreen; picture-in-picture; screen-wake-lock"
  referrerpolicy="no-referrer"
  title="Onboarding tour"></iframe>
Set aspect-ratio yourself on an iframe. Unlike the script embed, an iframe can’t know the video’s shape before it loads, so without it you get a 150px-tall box.

Sizing and aspect ratio

Share & embed defaults to Fit: no sizing attributes are required on the video div. It centers the video within the parent width and explicit height or max-height. Fixed size chooses a contained width and height; Fill and crop explicitly crops to fill. Crop can hide picture content; use it only when intentional.

By default both video and poster use contain, with letterboxing in the player canvas color. Controls and overlays remain inside the fitted player box. The script uses real video metadata for its ratio, including square and vertical video, without a ratio attribute.

For a height-constrained parent, use default Fit and set an explicit limit such as max-height:320px on the parent. The script measures that limit without treating its own automatic height as a constraint. A cross-origin iframe cannot inspect your parent: use the generated Fit snippet and its inherited maximum height, or set the frame height explicitly. overflow:hidden alone is not a sizing instruction.

<div style="width:100%;max-height:320px;overflow:hidden">
  <div data-playflow-video="VIDEO_PUBLIC_ID"></div>
</div>

The script embed reads the video’s real dimensions and applies the matching aspect-ratio, so a 9:16 phone video doesn’t get letterboxed into a widescreen frame. It fills the width of its container; to constrain it, constrain the parent.

HTML
<!-- 720px max, centered -->
<div style="max-width:720px;margin:0 auto">
  <div data-playflow-video="VIDEO_PUBLIC_ID"></div>
</div>
AttributeDefaultWhat it does
data-playflow-videorequiredThe video code.

See embed.js options for the supported embed behavior and analytics privacy controls.

Autoplay and muting

Set playback for one script embed with data-autoplay, data-loop, data-remember-sound, data-center-play, and data-center-replay. Direct iframe and watch URLs accept autoplay, loop, remember_sound, center_play, and center_replay. Each center button accepts auto, show, or hide; Auto hides it when a visible overlay intersects its moved rectangle. Leave a value unset to inherit. See embed.js playback precedence for workspace-wide sound memory, mobile behavior, and browser fallback.

All plans support independent positions: data-center-play-position="30,50" and data-center-replay-position="70,50" on script embeds, or center_play_position=30,50 and center_replay_position=70,50 in iframe/watch URLs. Values are 0–100 percentages of the video picture. Omit either position to inherit video/workspace settings, ultimately 50,50. Positions track contain, crop and fullscreen; rendering clamps the circle inside the visible picture without changing saved coordinates.

All plans also support independent circle diameters from 8 to 40% of the shorter video-picture edge: data-center-play-size="18" and data-center-replay-size="18" on script embeds, or center_play_size=18 and center_replay_size=18 in iframe/watch URLs. Unset sizes inherit the video and workspace settings; a null saved size keeps the responsive default. The circle is capped to fit and is hidden if the shortest player edge is under 44px. Video click to play still works.

Entitled Buttons, Hotspots and timed Play and Replay placements are served with the same player in script and iframe embeds, including fullscreen and phones. See Interactivity. The existing embed and CSP requirements do not change.

Timed Play and Replay placements

On Marina and Fleet, set Play and Replay placements for chosen portions of a video in its Interactive tab. For example, move Replay to the left of a Give button for the final three seconds, or hide it during a scene. Up to 10 placements are independent of the 20 interactive overlays. Each placement targets Play, Replay or Both and sets picture-relative position, optional 8–40% size, and show/hide; leave size unset to keep the size otherwise in effect. Placements for the same circle cannot overlap. The published placement follows the video picture in script and iframe embeds, including crop and fullscreen; there is no separate embed attribute or Player API method to author the timeline.

At a given time the order for each field is a host page’s setAppearance override, the active timed placement, the per-video setting, workspace default, then player default. Before first play the time is 0; paused uses the pause time; ended Replay also uses a placement whose end equals the video duration. Outside a placement the saved video/workspace settings return. Auto checks overlap using the resolved position and size. Visible changes animate for 150ms, or instantly under reduced motion; playback is not restarted. See Player API appearance.

If the video carries a voiceover, don’t autoplay it. A muted autoplay of a talking head reads as broken.

Content Security Policy

On the page hosting a Playflow embed, add https://v.getplayflow.co to your existing script-src and frame-src allowlists. Keep the other sources, nonces, and hashes your site needs. For example:

Example parent-page CSP directives
Content-Security-Policy:
  script-src 'self' https://v.getplayflow.co;
  frame-src 'self' https://v.getplayflow.co;

embed.js loads the iframe from the player origin. The player fetches its media and analytics inside that cross-origin iframe, whose CSP is managed separately. You do not need to add playback CDN media or image sources to the parent page solely for this embed.

Custom domains are available on Fleet and are set up with our team on request. Talk to sales to plan setup. You can also use the Playflow-hosted embed address and the Content Security Policy origins shown above.

Troubleshooting

What you seeUsually means
Nothing renders at allThe loader didn’t run. Check the network tab for embed.js, and that the div isn’t inside a template that never mounted.
“This video is private”Visibility is Private. Switch it to Unlisted.
“Still processing”Encoding hasn’t finished. Check again later, and publish once the status is ready.
A 150px-tall sliverAn iframe with no aspect-ratio.
Plays on desktop, not on phonesThe browser has blocked autoplay. Let the visitor start playback.

Still stuck? Send us the page URL and we’ll look at it.