Skip to main content

SDK Architecture Overview

The Percus rendering layer is composed of two decoupled packages that work together to embed personalized video experiences into any web page.

┌─────────────────────────────────────────────────────────┐
│ Host Page (customer website) │
│ │
│ ┌──────────────────────────────────────────────────┐ │
│ │ percus-embed-sdk (SmartEmbed) │ │
│ │ - Creates <iframe> │ │
│ │ - Sends INIT / PLAY / PAUSE / SEEK via postMsg │ │
│ │ - Receives READY / PROGRESS / ERROR callbacks │ │
│ └────────────────────┬─────────────────────────────┘ │
└────────────────────────│────────────────────────────────┘
postMessage (cross-origin)
┌───────────────────────────────────────────────────────── ┐
│ <iframe> (Percus Player origin) │
│ │
│ ┌──────────────────────────────────────────────────┐ │
│ │ percus-player (Player Runtime) │ │
│ │ - Loads template (Lottie JSON) │ │
│ │ - Loads manifest & personalization data │ │
│ │ - Applies bindings via BindingEngine │ │
│ │ - Renders animation via Renderer (lottie-web) │ │
│ └──────────────────────────────────────────────────┘ │
└──────────────────────────────────────────────────────────┘

What these components do

Before diving into technical details, here is a plain-language summary of everything these two components enable.

Percus Player — what it delivers

  • Plays personalized video animations — renders Lottie-based animations that have been customized with each customer's own data (name, account balance, plan details, etc.).
  • Loads content on demand — fetches the animation template and any required assets only when a viewer opens the experience, so there is nothing to pre-generate or store.
  • Applies data bindings automatically — takes the customer's data and replaces the right placeholders inside the animation without any manual work per viewer.
  • Responds to playback controls — can be played, paused, and jumped to any point in time, just like a regular video player.
  • Reports real-time progress — continuously informs the host page about how far along the animation is, enabling custom progress bars, chapter markers, or analytics.
  • Communicates errors clearly — if something goes wrong during loading or playback, it sends a structured error back to the host page so the experience can fail gracefully.
  • Runs in an isolated sandbox — operates inside an iframe on its own domain, keeping customer data and rendering logic separate from the host page.
  • Supports custom modules — every internal piece (template loader, data provider, binding engine, renderer) can be swapped out, making the player adaptable to different template formats or data sources.
  • (planned) Fires in-video events — notifies the host page when a CTA button, chapter marker, or custom interaction point is reached during playback.
  • (planned) Handles autoplay gracefully — detects when the browser blocks autoplay and reports it as a specific event so the host page can show a manual play prompt.
  • (planned) Supports closed captions and transcripts — renders subtitle tracks synchronized to the animation for accessibility and regulatory compliance.
  • (planned) Emits completion signals — distinguishes between a viewer who watched the full animation and one who left before the end, enabling engagement scoring.

Percus SmartEmbed SDK — what it delivers

  • One-line embedding — a single function call (PercusEmbed.init) is all that is needed to place the player inside any <div> on a web page.
  • Works with any web stack — ships as a plain <script> tag for static pages and as an ES module for React, Vue, Angular, or any modern bundler.
  • Handles the iframe automatically — creates, configures, and injects the iframe so developers never have to write boilerplate HTML or worry about sizing.
  • Sends personalization data securely — forwards customer data directly to the player at initialization time; the data is never stored or exposed outside the iframe.
  • Exposes simple playback controlsplay(), pause(), seek(), and destroy() give full control over the viewing experience with no knowledge of the underlying protocol required.
  • Delivers lifecycle callbacksonReady, onProgress, and onError hooks let the surrounding page react to player events (show a spinner, update a progress bar, display an error message).
  • Fully typed for TypeScript projects — ships complete type declarations so editors can autocomplete parameters and catch mistakes at compile time.
  • Cleans up after itselfdestroy() removes the iframe and all event listeners, preventing memory leaks in single-page applications.
  • (planned) Built-in analytics tracking — records player events (plays, completions, CTA clicks, chapter views) and can forward them to an analytics backend or Google Analytics without any extra code on the host page.
  • (planned) Consent management — respects privacy regulations by gating all tracking behind explicit user consent, with callbacks for accepted and declined states.
  • (planned) Call-to-action callbacks — surfaces CTA interactions from inside the animation so the host page can open a form, redirect to a product page, or trigger any business action.
  • (planned) Modal / lightbox mode — can open the player as a full-screen overlay with an optional auto-open delay, useful for promotional or onboarding experiences.
  • (planned) Aspect ratio and responsive sizing — accepts a single aspect ratio parameter ("16x9", "1x1", etc.) and handles all the CSS needed to make the iframe fully responsive.
  • (planned) Multiple player instances — provides a registry to manage and control several independent players on the same page.
  • (planned) Mute, loop, and autoplay options — standard playback settings configurable at init time with proper browser-policy fallback handling.

Packages

PackageNPM / BuildRole
percus-playerIIFE served from CDNRuns inside the iframe – loads, binds, and renders animations
percus-embed-sdkESM + IIFERuns on the host page – creates the iframe and exposes a control API

Message Contract

Both packages share a versioned postMessage protocol (PERCUS_MESSAGE_VERSION = 1). All messages follow the same envelope:

{
version: 1;
type: PercusMessageType;
payload: TPayload;
}

Message flow

DirectionMessage typePurpose
Host → PlayerPERCUS/INITSend template, manifest, and personalization data
Host → PlayerPERCUS/PLAYStart / resume playback
Host → PlayerPERCUS/PAUSEPause playback
Host → PlayerPERCUS/SEEKJump to a time position
Player → HostPERCUS/READYPlayer has loaded and is ready
Player → HostPERCUS/PROGRESSPeriodic playback heartbeat (≈500 ms)
Player → HostPERCUS/ERRORAn error occurred

Security model

  • The Player Runtime accepts messages only from origins in a configurable allowlist.
  • The SmartEmbed SDK validates that incoming messages originate from the injected iframe (event.source === iframe.contentWindow).
  • Personalization data (PII) is held in memory only during binding and is never logged, persisted, or forwarded.
  • postMessage calls should be pinned to the real target origin in production (avoid "*").
  • The host page is responsible for setting restrictive sandbox attributes on the iframe.

Feature roadmap

The table below covers the full scope of both components — core functionality and enhancements. Items are grouped by category and ordered by implementation priority within each group.

Core functionality (not yet implemented)

PriorityFeatureComponent(s)Notes
HighTemplate loadingPlayerFetch Lottie JSON template from a URL on PERCUS/INIT
HighManifest loadingPlayerFetch and validate the binding manifest from a URL
HighPersonalization data loadingPlayerAccept inline data or fetch from dataUrl
HighData binding enginePlayerApply manifest bindings to the template JSON, replacing placeholders with customer data
HighAnimation renderingPlayerRender the bound Lottie animation via lottie-web
HighPlay / Pause / Seek controlsPlayer + SDKHandle PERCUS/PLAY, PERCUS/PAUSE, PERCUS/SEEK commands; expose play(), pause(), seek() on the controller
HighProgress heartbeatPlayer + SDKEmit PERCUS/PROGRESS every ~500 ms; surface via onProgress callback
HighError reportingPlayer + SDKEmit PERCUS/ERROR on any failure; surface via onError callback
HighIframe injectionSDKCreate, configure, and append the <iframe> to the target element
HighPERCUS/INIT dispatchSDKSend template, manifest, and data URLs to the player after iframe load
HighOrigin allowlist enforcementPlayerReject postMessage commands from origins not in the configured allowlist
HighPluggable module architecturePlayerAllow TemplateLoader, ManifestLoader, DataProvider, BindingEngine, and Renderer to be swapped via constructor options

Enhancements (identified from competitive analysis)

PriorityFeatureComponent(s)Notes
HighAnalytics / Smart TrackingSDK + PlayerPer-session tracking key, event capture, analytics backend integration
HighConsent managementSDKGate all tracking behind user consent; onConsentAccepted / onConsentDeclined callbacks
HighCTA eventsSDK + PlayerSurface in-animation call-to-action triggers to the host page
HighonPlayComplete / onPlayIncompleteSDK + PlayerDistinguish full watches from drop-offs for engagement scoring
MediumAutoplay + mute fallbackSDK + PlayerDetect browser autoplay blocks; onAutoplayFailure event + mute-on-start option
MediumClosed captions / transcriptPlayerSubtitle track rendering for accessibility and regulatory compliance
MediumModal / lightbox modeSDKOpen player as overlay; optional auto-open-time delay
MediumAspect ratio & responsive sizingSDKSingle config param drives all responsive CSS
LowChapter navigation eventsSDK + PlayeronChapterEnter / onChapterExit for longer-form content
LowMultiple player instancesSDKRegistry API to manage several players on the same page
LowTheming / color schemesSDKPer-client branding without a new build

See Percus Player and SmartEmbed SDK for full API references.