Broadsign Integration
An open-source HTML5 package for Broadsign Control that connects your DOOH screens to Adlocaite programmatic demand. Built for publishers who run Broadsign as their playout system.
Open Source
This integration is MIT-licensed and open source. Contributions are welcome. View the source on GitHub or read the Contributing Guide.
Overview
The Adlocaite Broadsign Integration is an HTML5 package (.x-html-package) that runs inside the Broadsign Control Player. When Broadsign schedules an ad slot for this package, it automatically requests a programmatic advertisement from the Adlocaite API, plays the creative (video or image), fires VAST tracking events, and confirms the playout.
The package is designed as a self-contained unit: no external build tools, no server-side components, no dependencies beyond what ships in the package. You configure it with your API key, build the package with a single command, and upload it to Broadsign Control.
Key features
- VAST 2.0/3.0/4.0 support -- Industry-standard ad serving protocol for video and image creatives
- Automatic playout confirmation -- Reports successful playouts back to the Adlocaite API
- VAST tracking -- Fires impression, quartile, and completion tracking events
- Graceful error handling -- API errors are handled without crashing the Broadsign Player, with automatic retry and exponential backoff
- Debug mode -- Visual debug panel and detailed console logging for troubleshooting
- Browser-based test interface -- Test the full lifecycle without a Broadsign Player
- Zero dependencies -- Pure vanilla JavaScript, no external libraries or build tools
- Open source (MIT) -- Fully inspectable and modifiable
Current status
- Name
Version- Type
- string
- Description
1.0.0
- Name
License- Type
- string
- Description
MIT
- Name
Status- Type
- string
- Description
Stable (V1) -- V2 in development
- Name
Requirements- Type
- string
- Description
Broadsign Control 15.4+ (Chromium 87+)
- Name
Repository- Type
- string
- Description
How it works
The integration follows a linear lifecycle within a single Broadsign ad slot:
Playback lifecycle (V1)
- Page Load -- Broadsign loads the HTML5 package and runs initialization (configuration, module setup).
- BroadSignPlay() -- Broadsign calls
BroadSignPlay()when the ad slot is displayed on screen. Only at this point isBroadSignObject.frame_idavailable to identify the screen. - Content loading -- The package requests an offer from the Adlocaite API, parses the VAST response, and loads the media asset (video or image). This happens while the slot is already visible, which can cause a brief loading delay (see Known Limitations).
- Playback -- The media plays while VAST tracking events are fired at impression, start, quartiles (25%, 50%, 75%), and completion.
- Playout confirmation -- After playback completes, the package confirms the playout via the Adlocaite API with duration and completion data.
Architecture
The package consists of four core modules:
- Name
AdlocaiteApp- Type
- Orchestrator
- Description
Main application class in
index.html. Manages initialization and playback lifecycle. Coordinates all other modules.
- Name
BroadsignAdapter- Type
- broadsign-adapter.js
- Description
Handles Broadsign Control Player integration:
BroadSignPlay()lifecycle, screen ID extraction fromBroadSignObject, playback state management, and skip signaling via document title.
- Name
AdlocaiteAPIClient- Type
- adlocaite-api.js
- Description
HTTP client for the Adlocaite API. Handles offer requests (by screen ID or external ID), offer acceptance/rejection, and playout confirmation. Includes retry logic with exponential backoff.
- Name
VASTParser- Type
- vast-parser.js
- Description
Parses VAST XML responses. Extracts media files, tracking URLs, deal IDs from custom extensions, and creative metadata. Supports VAST 2.0, 3.0, and 4.0.
- Name
AdlocaitePlayer- Type
- player.js
- Description
Media playback engine. Loads video and image assets at playout time. Handles HTML5 video playback with muted autoplay (Chromium 87+ requirement), image display with timed duration, and VAST tracking pixel firing.
Integration comparison
Adlocaite offers multiple integration paths for publishers. Choose the one that fits your infrastructure:
Integration | Setup Effort | Maintenance | Customizability | Best For |
|---|---|---|---|---|
| Core API (Direct) | High | Self-managed | Full | Custom CMS / full control |
| Grassfish CMS | Low | Managed by Grassfish | Limited | Grassfish CMS users |
| Broadsign | Medium | Self-managed (open source) | High (fork & modify) | Broadsign Control users |
| OpenRTB 2.6 | Medium | Managed by Adlocaite | Limited (protocol constraints) | SSP / legacy RTB systems |
Getting started
Prerequisites
Before you begin, make sure you have:
- Adlocaite Publisher API key -- Obtain one through the Publisher Onboarding process
- Screens registered in Adlocaite -- Each screen needs an
external_idmatching the Broadsignframe_id(see Screen Registration) - Git installed on your machine
- Broadsign Control 15.4+ (Chromium 87+) for production deployment
Step 1: Clone the repository
Clone
git clone https://github.com/Adlocaite/adlocaite-broadsign.git
cd adlocaite-broadsign
Step 2: Configure your API key
cp package/js/config.example.js package/js/config.js
Open package/js/config.js and set your API key and environment:
const ADLOCAITE_CONFIG = {
// Your publisher API key (required)
apiKey: 'pub_your_actual_api_key_here',
// Use production URL for live screens
apiBaseUrl: 'https://api.adlocaite.com/functions/v1/api',
// Minimum bid price in cents (100 = 1.00 EUR)
minBidCents: 100,
// Disable debug mode for production
debugMode: false,
// Keep other defaults unless you have specific requirements
// ...
};
See the full Configuration Reference below for all available options.
Step 3: Build the package
Build
./build.sh
This creates adlocaite-broadsign.x-html-package in the project root. The build script validates your config, injects the version number, and packages everything into a zip file with the .x-html-package extension.
Step 4: Deploy to Broadsign Control
- Open Broadsign Control Administrator
- Navigate to Library > Ad Copies
- Click Upload and select the
.x-html-packagefile - Assign the ad copy to your campaign
Step 5: Configure a fallback campaign
Fallback campaign required
You must configure a separate fallback campaign in Broadsign Control. When Adlocaite has no ad to serve, the integration signals Broadsign to skip, but Broadsign needs fallback content to display instead. Without this, empty slots will show a black screen. See Known Limitations for details.
Deployment checklist
- API key configured in
config.js(not the placeholderpub_xxxx) - API base URL set to production (
https://api.adlocaite.com/functions/v1/api) - Debug mode disabled for production deployment
- Package built with
./build.sh(check for warnings) - Screens registered in Adlocaite with matching
external_id - Fallback campaign configured in Broadsign Control
- Tested on staging before rolling out to production
Configuration reference
Configuration lives in package/js/config.js. This file is loaded as a global JavaScript object and must not be committed to version control (it contains your API key).
The config file exports a global ADLOCAITE_CONFIG object:
const ADLOCAITE_CONFIG = {
apiKey: 'pub_your_api_key_here',
apiBaseUrl: 'https://api.adlocaite.com/functions/v1/api',
minBidCents: 100,
vastMode: true,
debugMode: false,
requestTimeout: 10000,
assetTimeout: 20000,
maxLifecycleDuration: 60000,
maxRetries: 3,
retryDelay: 1000,
};
if (typeof window !== 'undefined') {
window.ADLOCAITE_CONFIG = ADLOCAITE_CONFIG;
}
Never commit config.js
The file package/js/config.js contains your API key and is listed in .gitignore. Only config.example.js should be committed. Git hooks in the repository will prevent accidental commits of sensitive data.
Required parameters
- Name
apiKey- Type
- string
- Description
Publisher API key for authenticating with the Adlocaite API. Obtain this from your onboarding team or the Adlocaite Dashboard. Must start with
pub_.
- Name
apiBaseUrl- Type
- string
- Description
Base URL for the Adlocaite API. Determines whether you connect to staging or production.
- Production:
https://api.adlocaite.com/functions/v1/api - Staging:
https://staging.api.adlocaite.com/functions/v1/api
- Production:
Offer configuration
- Name
minBidCents- Type
- number
- Description
Minimum bid price in cents. Only offers with bids at or above this value will be accepted. For example,
100means a minimum bid of 1.00 EUR. Default:100
- Name
vastMode- Type
- boolean
- Description
When
true, API requests includevast=trueto receive VAST XML responses. VAST provides standardized tracking and better compatibility with industry tools. Disable only if you need raw JSON offer responses. Default:true
Timeout configuration
- Name
requestTimeout- Type
- number
- Description
Maximum time to wait for API responses, in milliseconds. If an API call takes longer, it is aborted and retried (if retries are available). Default:
10000(10 seconds)
- Name
assetTimeout- Type
- number
- Description
Maximum time to wait for media assets (video/image) to load, in milliseconds. Default:
20000(20 seconds)
- Name
maxLifecycleDuration- Type
- number
- Description
Maximum total time allowed for the complete lifecycle (offer request, acceptance, and playout), in milliseconds. Default:
60000(60 seconds)
Retry configuration
- Name
maxRetries- Type
- number
- Description
Number of times to retry failed API requests. Applies to server errors (5xx) and network failures. Client errors (4xx) are not retried. Default:
3
- Name
retryDelay- Type
- number
- Description
Initial delay before the first retry, in milliseconds. Each subsequent retry doubles the delay (exponential backoff). For example, with
retryDelay: 1000andmaxRetries: 3, retries happen at 1s, 2s, and 4s. Default:1000
Debug configuration
- Name
debugMode- Type
- boolean
- Description
Enable detailed logging and the visual debug panel. When
true, all modules log timestamped messages to the browser console, and a debug overlay is shown on screen. Disable for production. Default:false
Caching configuration (V2)
Asset pre-caching is not yet functional in V1. These parameters exist in the config template but have no effect. They will be activated in V2.
- Name
enableCaching- Type
- boolean
- Description
Enable background asset pre-caching. Not functional in V1. Default:
true
- Name
cachingInterval- Type
- number
- Description
How often to refresh the asset cache, in milliseconds. Not functional in V1. Default:
300000(5 minutes)
Environment setup
Staging -- Use for testing and development. Staging uses separate API keys and campaign data from production.
{
apiKey: 'pub_your_staging_key',
apiBaseUrl: 'https://staging.api.adlocaite.com/functions/v1/api',
debugMode: true,
minBidCents: 1, // Low threshold for testing
}
Production -- Use for live screens serving real ad campaigns.
{
apiKey: 'pub_your_production_key',
apiBaseUrl: 'https://api.adlocaite.com/functions/v1/api',
debugMode: false, // Always disable in production
minBidCents: 100, // Set your actual minimum
}
Test on staging first
Always test your configuration on the staging environment before deploying to production screens. Staging and production use separate API keys -- a staging key will not work on production and vice versa.
Screen registration
Each Broadsign screen must be registered in the Adlocaite platform with a matching identifier. The integration uses the Broadsign frame_id as the screen identifier.
How screen matching works
- Broadsign provides
BroadSignObject.frame_idto the HTML5 package at runtime - The integration sends this
frame_idto the Adlocaite API as anexternal_id - The API looks up the screen by its
external_idand returns matching offers
Fallback identification methods (in order): URL parameter ?screen_id=, localStorage value adlocaite_screen_id.
Finding your frame_id
Check your Broadsign Player debug logs to find the frame_id value. The frame_id is assigned by Broadsign when you configure a frame (display area) in Broadsign Control.
Alternatively, in the test interface, the frame_id field shows what value would be used.
Registering in Adlocaite
In the Adlocaite Dashboard, set the screen's external_id to match the Broadsign frame_id. For detailed instructions, see External Screen IDs.
Verifying the mapping
Enable debugMode: true and check the console logs for:
[Broadsign Adapter] Screen ID (frame_id) from BroadSignObject: 842292831
Then verify the API responds with offers (not 404) for this screen ID.
Testing
The built-in test interface (/test/) simulates the Broadsign Control Player in your browser.
Starting the test server
npm run test:serve
# Open http://127.0.0.1:8000/test/
Test interface features
- Configuration panel -- Set
frame_id, API key, environment, resolution, and options - BroadSignObject simulation -- Mocks the
BroadSignObjectthat Broadsign injects - Manual lifecycle control -- "Load Package" initializes the integration, "Trigger Play" calls
BroadSignPlay() - Real-time log output -- All console output from the package is displayed
- Title monitoring -- Watches the document title changes (
wait/ready/skip) - Persistent config -- Settings are saved to localStorage and can be passed via URL parameters
Quick test via URL parameters
http://127.0.0.1:8000/test/?api_key=pub_xxx&frame_id=842292831&env=staging&debug=true
Test scenarios
- Happy path -- Configure a valid
frame_idand API key, load package, trigger play. Expected: ad plays successfully. - No offers -- Use a
frame_idthat has no active campaigns. Expected: title changes toskip:no offers available. - Invalid screen -- Use a non-existent
frame_id. Expected: 404 handled gracefully, title changes toskip. - Invalid API key -- Use
pub_invalid. Expected: 401 error in logs, title changes toskip.
Strengths & limitations
Strengths
- Name
Zero-dependency package- Description
The integration is pure vanilla JavaScript with no external dependencies, build tools, or bundlers. This makes it lightweight, easy to audit, and compatible with any Broadsign Control version that supports HTML5 (Chromium 87+).
- Name
VAST standard compliance- Description
Full support for VAST 2.0, 3.0, and 4.0. This means the integration works with industry-standard ad serving infrastructure and fires all expected tracking events (impression, start, quartiles, complete).
- Name
Graceful error handling- Description
API errors (404, 5xx) are handled without throwing exceptions that could crash the Broadsign Player. The integration returns structured error objects and signals Broadsign to skip to fallback content instead.
- Name
Retry with exponential backoff- Description
Failed API requests are automatically retried with configurable retry count and exponential backoff delay. Server errors (5xx) and network failures trigger retries; client errors (4xx) do not.
- Name
Built-in test interface- Description
A browser-based test UI simulates the Broadsign Player environment, including
BroadSignObjectinjection,BroadSignPlay()triggering, and real-time log output. No Broadsign hardware required for development.
- Name
Open source (MIT)- Description
Fully open source under the MIT license. You can inspect, modify, and redistribute the code. Contributions are welcome via the GitHub repository.
Known limitations
Skip signal timing (V1) -- Broadsign checks the document <title> within the first 1-2 seconds after page load to decide whether to skip the ad copy. However, BroadSignPlay() fires after this check window, which means the skip signal set by the integration arrives too late for Broadsign to act on it automatically. Workaround: Configure a separate fallback campaign in Broadsign Control. (Issue #4)
Loading delay (V1) -- Since the screen ID is only available after BroadSignPlay() fires, content must be fetched while the slot is already visible. This can cause a brief black screen or loading delay. Workaround: Ensure reliable network connectivity to the API and asset CDN. (Issue #3)
Fallback campaign required -- Because the skip signal timing issue prevents automatic waterfall fallback, publishers must configure a separate fallback campaign in Broadsign Control. Without it, empty ad slots will show a black screen.
No asset pre-caching -- The integration does not currently pre-cache ad assets. Each ad slot fetches its content live from the API, which means playback depends on network availability and speed at playout time. Asset pre-caching is planned for V2.
No automated test suite -- The integration currently relies on manual testing via the browser-based test interface. Automated end-to-end tests are planned but not yet implemented.
Muted video playback -- Due to Chromium 87+ autoplay policies, all video playback is muted (muted=true). This is a browser-level restriction -- unmuted autoplay is blocked by the Chromium engine used in Broadsign Control.
Comparison with direct API
If you can build a custom integration using the Core API directly, here is what you gain and lose compared to using the Broadsign package:
Aspect | Broadsign Package | Direct Core API |
|---|---|---|
| Setup time | Minutes (clone, configure, build) | Days to weeks (custom development) |
| Playout system | Broadsign Control only | Any system |
| Offer workflow | Automated (request + accept + play) | Full control (request, review, accept/reject) |
| VAST tracking | Built-in | Must implement yourself |
| Asset caching | Not available (planned for V2) | Custom implementation possible |
| Customizability | Config + source modification | Unlimited |
| Fallback handling | Requires Broadsign fallback campaign | Fully custom |
V2 roadmap
Version 2 is in active development and will address the major V1 limitations:
Content pre-loading during off-screen buffering
V2 will load offers and media assets during Broadsign's off-screen pre-buffering phase (before BroadSignPlay() fires), enabling instant playback with no visible delay. The content will be fully buffered before the ad slot becomes visible.
Asset pre-caching
V2 will introduce a background cache manager that periodically fetches upcoming ad assets and stores them in the browser cache. This reduces load times and provides resilience against temporary network issues during playout.
Skip signal before check window
V2 will set the document title to skip before Broadsign's title check window (within the first 1-2 seconds of page load). This enables automatic waterfall fallback without requiring a dedicated fallback campaign in Broadsign Control.
Screen ID fallback chain
V2 will implement a fallback chain for screen identification:
frame_id(primary, current behavior)display_unit_id(fallback ifframe_idis not configured)player_id(last resort)
This makes the integration more resilient to varying Broadsign configurations.
How to follow progress
- Track V2 development on GitHub Issues
- Contributions to V2 features are welcome -- see the Contributing Guide
Troubleshooting
No screen ID available
The package cannot determine which screen to request offers for.
- In Broadsign Player: Verify that
frame_idis configured in your Broadsign setup - In the test interface: Enter a
frame_idin the configuration panel - Check Broadsign Player debug logs for
BroadSignObjectvalues
404 -- No offers available
The API cannot find matching offers for this screen.
- Verify the screen is registered in Adlocaite with the correct
external_id - Check that there are active campaigns targeting this screen
- Ensure the screen's resolution matches available ad creatives
401 -- Invalid API key
Authentication failed.
- Verify your API key in
config.jsstarts withpub_ - Check that the key is for the correct environment (staging vs. production)
- Ensure there are no trailing spaces or newlines in the key
CORS errors
Asset loading fails with cross-origin errors.
- Ad asset servers must include
Access-Control-Allow-Origin: *header - This is configured on the Adlocaite side -- contact support if you encounter this
Black screen / no ad playing
The ad slot is visible but nothing appears.
- Ensure a fallback campaign is configured in Broadsign Control
- Enable
debugMode: truein config and check console output - Verify the API is reachable from the player network
Build fails
The build.sh script reports errors.
- Ensure
package/js/config.jsexists (copy fromconfig.example.js) - Check that
zipis installed (brew install zipon macOS,apt install zipon Ubuntu) - Verify the API key line is not still set to the placeholder
pub_xxxx