UK Dynamo Creative Technical Specifications

For production agencies delivering dynamic HTML campaigns to Bauer Media Outdoor UK Adshel Liveand Billboard Live panels.

1. Overview

UK Adshel Live and Billboard Live panels use the Dynamo distribution system. This operates differently to the standard BroadSign HTML Package delivery model used in other markets.

A Dynamo campaign is split into two components:

Component Delivery Description
Core bundle Delivered directly to Bauer Media Outdoor HTML, CSS, JavaScript, and all static assets. Uploaded to the CMS and pushed to panels.
FTP data files Hosted on a client-side FTP server Dynamic data: feeds, copy variations, trigger logic. Synced from client FTP to an internal Bauer Media Outdoor FTP, then served as a localhost endpoint on each panel.

The core bundle and data files are linked at runtime on the panel. The JavaScript in the core bundle fetches data files from the local endpoint exposed by the Dynamo system.

Important: Dynamo is the distribution infrastructure only. The BroadSign Player remains the playback engine on every panel — it renders the HTML creative, injects BroadSignObject, calls BroadSignPlay(), and handles Proof of Play via WebSocket. All standard BroadSign creative requirements therefore still apply. Dynamo affects only how assets are delivered to the panel, not how they run.

Note: This guide is specific to UK Dynamo deployments. For all other markets and standard BroadSign deliveries, see the HTML Creative Technical Specifications doc for more info.


2. Delivery Architecture

[Client FTP] ──sync──► [BMO internal FTP] ──deliver──► localhost:8080 on each panel
                                                              ↑
[Core bundle] ──CMS───► [Panel CMS] ──push──► Panel filesystem │
                                                              ↓
                                              [BroadSign Player] ───┘
                                              renders index.html,
                                              calls BroadSignPlay(),
                                              handles PoP

Data files are available on each panel at:

http://localhost:8080/livedata/{campaignName}/

{campaignName} is agreed between Bauer Media Outdoor and the agency before the campaign build begins.


3. Core Bundle

3.1 File Structure

The core bundle is a self-contained ZIP of all files that remain constant for the duration of the campaign.

For full package structure requirements — including the index.html at root rule, valid directory layout, and prohibited system files — see the HTML Creative Technical Specifications doc for more info.

The core bundle should contain only static campaign assets. Dynamic data is delivered separately via FTP — see §4 FTP Data Files.

3.2 Fallback Image

index.html must include a hardcoded fallback image that is displayed if index.js fails to load — for example, if there is a network error, a JavaScript exception, or a missing asset.

The fallback image should be:

  • A static JPEG encoded as a base64 data URI to avoid an additional network request
  • Positioned at full-screen dimensions (1080 × 1920 px for portrait panels)
  • Initially hidden (opacity: 0), shown only when the fallback condition is triggered
<head>
  <script>
    var indexJsLoaded = false;
    function displayFallback() {
      document.getElementById("fallback").style.opacity = "1";
    }
    setTimeout(function () {
      if (!indexJsLoaded) {
        displayFallback();
      }
    }, 1000);
  </script>
  <script src="./index.js"></script>
</head>
<body>
  <img id="fallback"
       src="data:image/jpeg;base64,/9j/4AAQSkZJRgAB..."
       style="opacity:0; position:absolute; top:0; left:0; width:1080px; height:1920px;">
</body>

In index.js, set indexJsLoaded = true inside the window.onload handler. This prevents the fallback from appearing on a successful load. The displayFallback() function can also be called explicitly from within index.js whenever a critical error condition is detected (e.g. a required asset fails to load).

3.3 HTML Base Styling

The Chromium browser on Dynamo panels initialises with a white background. To prevent a white flash before the creative renders, add the following as the first element inside <head>:

<head>
  <div style="background-color: #000; position: absolute; top: 0; left: 0; width: 1080px; height: 1920px;"></div>
  <!-- other head elements follow -->
</head>

3.4 Accessing Bundle Assets

All assets within the core bundle must use relative paths. Absolute paths will not resolve in the panel environment. See the HTML Creative Technical Specifications doc for the full requirement.

Note: FTP-hosted data files are the exception — those must use absolute paths (e.g. http://localhost:8080/livedata/...). See §4.1.

3.5 Minimising Load Time

On DOOH panels, any time spent loading is display time lost. Keep the core bundle lean:

  • Inline CSS into <head> in index.html where practical.
  • Bundle all JavaScript into a single index.js where possible — minimise separate file requests.
  • Avoid loading frameworks (jQuery, React, Vue.js, etc.) unless strictly necessary. Use native ES6 DOM APIs instead.

4. FTP Data Files

4.1 Accessing FTP Files

Files delivered via the client FTP are served from the panel at:

http://localhost:8080/livedata/{campaignName}/{fileName}

Use absolute paths when referencing FTP assets from within the core bundle:

const dataFile = "http://localhost:8080/livedata/my_campaign/data.json";

4.2 Cache Busting

Files on the FTP that are expected to change during a campaign must include a cache-buster query parameter to force the player to re-fetch rather than serve a stale cached version:

const dataFile = "http://localhost:8080/livedata/my_campaign/data.json?cb=" + Date.now();

Important: Only add cache-busters to files that will actually change (e.g. data feeds, configuration JSON). Do not add cache-busters to static assets such as images or videos — this will cause unnecessary re-downloads and increase data consumption.

4.3 Naming Conventions

  • Filenames must not contain spaces or special characters.
  • Use hyphens or underscores as word separators.
Correct Incorrect
data-feed.json data feed.json
panel_list.json panel list (v2).json
location-weather.json location & weather.json

4.4 Aggregating Data Files

Minimise the number of AJAX calls from the core bundle. If a campaign uses multiple data triggers, aggregate all data into a single file rather than making separate requests per trigger type.

Instead of two separate files:

// location-data.json
{ "locationData": { "123456789": "London" } }
// weather-data.json
{ "weatherData": { "123456789": "Sunny" } }

Combine into one:

{
  "data": {
    "123456789": ["London", "Sunny"]
  }
}

4.5 Panel List as FTP Data

The list of panels booked for the campaign should be stored in a data file on the FTP — not hardcoded in the core bundle. This means panels can be added or removed mid-campaign without requiring a core bundle re-test and re-delivery.


5. Panel Targeting

5.1 BroadSign Frame ID

Each physical panel has a unique BroadSign Frame ID. This is accessible in the creative via BroadSignObject:

const frame_id = BroadSignObject["frame_id"];

This ID is used to look up panel-specific content from a data file.

5.2 Master Site List

Bauer Media Outdoor will provide a Master Site List containing details for every available panel:

  • BroadSign Frame ID
  • Panel address
  • Location name
  • Postcode
  • Latitude / Longitude
  • Additional operational metadata

Cross-reference the Master Site List against the list of booked panels to build a data file containing panel-specific content.

Example data file structure:

{
  "data": {
    "123456789": "London",
    "987654321": "Manchester",
    "555123456": "Birmingham"
  }
}

Example usage in the core bundle:

const url = "http://localhost:8080/livedata/my_campaign/data.json?cb=" + Date.now();
fetch(url)
  .then(res => res.json())
  .then(data => {
    const city = data.data[BroadSignObject["frame_id"]] || "your city";
    renderCreative(city);
  });

6. Animations and Pre-buffering

All animations and video must be paused at start. Playback must only begin when BroadSignPlay() is called by the BroadSign Player. This is a BroadSign Player mechanism — Dynamo is not involved in playback triggering.

See the HTML Creative Technical Specifications doc for full implementation details, including the BroadSignPlay() function structure. See also BroadSign: HTML5 Ad Copies for the official platform reference.

function BroadSignPlay() {
  // All playback and animation logic starts here
  document.getElementById("video").play();
}

7. Custom Proof of Play (UK Dynamo)

UK Dynamo campaigns have specific requirements for the Custom PoP payload that differ from the general specification. Refer to BroadSign: Custom PoP Action for the platform-level setup documentation.

Note: Custom PoP is a BroadSign Player feature. The WebSocket endpoint at ws://localhost:2326 is exposed by the BroadSign Player on the panel — Dynamo has no involvement in PoP recording. The UK-specific requirements in this section relate to the payload structure expected by Bauer Media Outdoor's reporting systems.

7.1 Implementation

The PoP message must be sent from inside BroadSignPlay() so it fires when the creative is showing on screen, not during pre-load.

Note: The implementation below is UK Dynamo-specific. The payload omits external_value_1 / external_value_2 and populates custom_field with the standardized creative reference keys defined by the UK OOH Standards Committee — see §7.2 Creative Reference Field Standard. For the general payload reference, see the HTML Creative Technical Specifications doc for more info.

let thirdPartyCreativeRef;
let creativeTriggerEvent;

function whatToPlay() {
  // Determine what to display based on dynamic data
  thirdPartyCreativeRef = "img1_sunny";
  creativeTriggerEvent = "london_sunny";

  // Revert to fallback if an error condition is detected
  if (err) {
    thirdPartyCreativeRef = "fallback.jpg";
    creativeTriggerEvent = "fallback";
  }
}

function BroadSignPlay() {
  whatToPlay();

  // Start playback
  document.getElementById("video").play();

  // Send Custom PoP
  const ws = new WebSocket("ws://localhost:2326");
  ws.onopen = function (event) {
    ws.send(JSON.stringify({
      rc: {
        version: "1",
        id: "1",
        action: "custom_pop",
        frame_id: BroadSignObject["frame_id"],
        content_id: BroadSignObject["ad_copy_id"],
        custom_field: JSON.stringify({
          thirdpartycreativeref: thirdPartyCreativeRef,
          creativetriggerevent: creativeTriggerEvent
        }),
        name: "dynamic trigger"
      }
    }));
  };
  ws.onmessage = function (event) {
    // PoP confirmed by the player
  };
  ws.onerror = function (error) {
    // PoP connection failed — log for debugging
  };
}

7.2 Creative Reference Field Standard (UK OOH Standards Committee)

The UK OOH Standards Committee (Technical Sub-Committee) has standardized four creative reference fields used across Dynamic Playout reporting. This replaces the previous BMO-specific guidance that reporting was limited to creative / trigger keys only — that restriction no longer applies.

Field Populated by Max length Description
creativeid Playout 64 chars Media owner-defined creative identifier
creativename Playout 128 chars Creative title used for reporting — usually a filename
thirdpartycreativeref Creative JSON payload 128 chars Description of the creative served, as defined by the third party (agency/DCO platform) — replaces the previous creative key
creativetriggerevent Creative JSON payload 64 chars The trigger event that prompted the given creative to be used — replaces the previous trigger key

All four fields are plain text. creativeid and creativename are populated on the media owner/Playout side — the creative's own JSON payload does not need to set them. Dynamic content providers should include thirdpartycreativeref and creativetriggerevent in the custom_field (or setCustomPopData() payload once rolled out — see §7.5) JSON; Playout maps these into its corresponding fields.

Correction: Bauer Media Outdoor has confirmed that the full extra_data object submitted in a PoP is always captured — no keys are silently discarded. Standard reporting extracts the fields above, but BMO retains access to the complete object for any additional fields a creative includes.

Correct:

custom_field: JSON.stringify({ thirdpartycreativeref: thirdPartyCreativeRef, creativetriggerevent: creativeTriggerEvent })

Rollout status: Target implementation date is 1 April — year to be confirmed by Bauer Media Outdoor. A transition period is expected for in-flight campaigns using the previous creative / trigger mapping; confirm with Bauer Media Outdoor whether a given campaign's Playout configuration still requires the legacy keys during this period.

7.3 creativetriggerevent and thirdpartycreativeref Values

creativetriggerevent should describe the conditions that started the build chain. thirdpartycreativeref should describe the end product of the build chain. Together they allow a direct correlation between input conditions and displayed output.

Example: A campaign with 2 image options, 2 weather states, and 3 locations:

Conditions creativetriggerevent value thirdpartycreativeref value
London, Sunny london_sunny img1_sunny
London, Rainy london_rainy img2_rain
Manchester, Sunny manchester_sunny img1_sunny
Manchester, Rainy manchester_rainy img2_rain
Birmingham, Sunny birmingham_sunny img1_sunny
Birmingham, Rainy birmingham_rainy img2_rain
Any location, error state {location}_error fallback.jpg

This mapping must be submitted to Bauer Media Outdoor as a PoP reporting matrix (see §8.2 PoP Reporting Matrix).

7.4 Timing Requirements

PoP timing is a hard requirement — see the HTML Creative Technical Specifications doc for the thresholds and consequences. These apply equally to UK Dynamo campaigns.

Before submitting a creative with Custom PoP, complete the validation checklist — see the HTML Creative Technical Specifications doc for more info.

7.5 setCustomPopData() Method (UK Dynamo)

BroadSign Player (BSP) 15.13.8 introduced BroadSignObject.setCustomPopData() as an alternative to the WebSocket method above — see the HTML Creative Technical Specifications doc for the general implementation. The same thirdpartycreativeref / creativetriggerevent field standard (§7.2) applies to the JSON payload passed to setCustomPopData(), since Bauer Media Outdoor's reporting captures the full extra_data object regardless of which method delivered it.

Rollout status: BSP 15.13.8 has not yet been rolled out across Bauer Media Outdoor's inventory — see the rollout note in the HTML Creative Technical Specifications doc for more info. Continue using the WebSocket method (§7.1) until Bauer Media Outdoor confirms this method is available for a given business unit.

setTimeout(() => {
  if (typeof BroadSignObject !== "undefined") {
    var result = BroadSignObject.setCustomPopData(JSON.stringify({
      thirdpartycreativeref: thirdPartyCreativeRef,
      creativetriggerevent: creativeTriggerEvent,
    }));
    if (result) {
      console.log("Sending PoP success");
    } else {
      console.log("Sending PoP failed");
    }
  }
}, 2000); // add 2s delay to make sure BroadSignObject should be ready when called.

If a creative ever calls both methods for the same ad copy, data set via setCustomPopData() always takes precedence over the WebSocket method and cannot be overwritten by it — see the HTML Creative Technical Specifications doc for more info.


8. Testing

8.1 Test Parameters

All dynamic variations must be testable via URL query parameters. This allows Bauer Media Outdoor to force any combination during review without requiring live data.

const params = new URLSearchParams(window.location.search);
const forceLocation = params.get('location'); // e.g. ?location=london
const forceWeather = params.get('weather');   // e.g. ?weather=sunny

Consider all possible combinations of parameters and verify that the correct creativetriggerevent and thirdpartycreativeref values are produced in each case.

8.2 PoP Reporting Matrix

A PoP reporting matrix must be submitted to Bauer Media Outdoor alongside every UK Dynamo DCO campaign. Unlike the creative variation matrix submitted for delivery documentation (see the HTML Creative Technical Specifications doc for more info), this matrix maps trigger conditions to the specific creativetriggerevent and thirdpartycreativeref values that will appear in the PoP log.

This enables Bauer Media Outdoor to:

  • Verify that the correct creative variation plays under each set of conditions
  • Confirm that PoP logs accurately reflect what was displayed on screen
  • Identify errors in live playout by comparing PoP data against expected outcomes

Example content matrix:

Trigger conditions Expected creativetriggerevent Expected thirdpartycreativeref
Location: London, Weather: Sunny london_sunny img1_text2_loc1
Location: London, Weather: Rainy london_rainy img2_text1_loc1
Location: Manchester, Weather: Sunny manchester_sunny img1_text2_loc3
Location: Manchester, Weather: Rainy manchester_rainy img2_text1_loc3
Any location, asset load error {location}_error fallback.jpg

The content matrix must account for all error and fallback states, not just happy-path variations.

8.3 Forcing Triggers for Testing

Any dynamic change in the campaign must be controllable from the data feed. The client must be able to push specific values through the Bauer Media Outdoor test panel so that all content combinations can be verified before go-live.

8.4 Time-Triggered Creatives

For creatives that change based on the panel's local time of day, testing can be facilitated by temporarily adjusting the panel clock to simulate different time windows. This must be arranged with Bauer Media Outdoor prior to the test session.


9. Browser Compatibility

The BroadSign Player on Dynamo-distributed panels runs on an older, fixed-version embedded Chromium browser — not an evergreen, auto-updating browser. All HTML, CSS, and JavaScript in the core bundle must be compatible with this engine. The exact build is not published here; contact your Bauer Media Outdoor account or technical contact for the specific version if you need it for build tooling.

Note: Some Dynamo-distributed panels run older hardware with an even earlier Chromium build. Treat the feature-support tables referenced below as binding regardless of hardware generation — if in doubt, confirm with your Bauer Media Outdoor contact.

For full CSS compatibility detail — including hard fails such as @layer and known compatible libraries — see the HTML Creative Technical Specifications doc for more info.

Third-party libraries and CMP SDKs: If the creative includes GSAP, CreateJS, BannerFlow, Flashtalking, or any other third-party library or SDK, see the HTML Creative Technical Specifications doc for compatibility notes and UAT requirements. These apply equally to Dynamo deliveries.


Further Reading

  • HTML Creative Technical Specifications (see the other doc for more info) — companion document covering all standard BroadSign delivery requirements
  • BroadSign: HTML5 Ad Copies
  • BroadSign: Custom PoP Action
  • BroadSign: Content Variables

‍

‍

‍

‍

No items found.