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 controls —
play(),pause(),seek(), anddestroy()give full control over the viewing experience with no knowledge of the underlying protocol required. - Delivers lifecycle callbacks —
onReady,onProgress, andonErrorhooks 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 itself —
destroy()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
| Package | NPM / Build | Role |
|---|---|---|
percus-player | IIFE served from CDN | Runs inside the iframe – loads, binds, and renders animations |
percus-embed-sdk | ESM + IIFE | Runs 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
| Direction | Message type | Purpose |
|---|---|---|
| Host → Player | PERCUS/INIT | Send template, manifest, and personalization data |
| Host → Player | PERCUS/PLAY | Start / resume playback |
| Host → Player | PERCUS/PAUSE | Pause playback |
| Host → Player | PERCUS/SEEK | Jump to a time position |
| Player → Host | PERCUS/READY | Player has loaded and is ready |
| Player → Host | PERCUS/PROGRESS | Periodic playback heartbeat (≈500 ms) |
| Player → Host | PERCUS/ERROR | An 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.
postMessagecalls should be pinned to the real target origin in production (avoid"*").- The host page is responsible for setting restrictive
sandboxattributes 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)
| Priority | Feature | Component(s) | Notes |
|---|---|---|---|
| High | Template loading | Player | Fetch Lottie JSON template from a URL on PERCUS/INIT |
| High | Manifest loading | Player | Fetch and validate the binding manifest from a URL |
| High | Personalization data loading | Player | Accept inline data or fetch from dataUrl |
| High | Data binding engine | Player | Apply manifest bindings to the template JSON, replacing placeholders with customer data |
| High | Animation rendering | Player | Render the bound Lottie animation via lottie-web |
| High | Play / Pause / Seek controls | Player + SDK | Handle PERCUS/PLAY, PERCUS/PAUSE, PERCUS/SEEK commands; expose play(), pause(), seek() on the controller |
| High | Progress heartbeat | Player + SDK | Emit PERCUS/PROGRESS every ~500 ms; surface via onProgress callback |
| High | Error reporting | Player + SDK | Emit PERCUS/ERROR on any failure; surface via onError callback |
| High | Iframe injection | SDK | Create, configure, and append the <iframe> to the target element |
| High | PERCUS/INIT dispatch | SDK | Send template, manifest, and data URLs to the player after iframe load |
| High | Origin allowlist enforcement | Player | Reject postMessage commands from origins not in the configured allowlist |
| High | Pluggable module architecture | Player | Allow TemplateLoader, ManifestLoader, DataProvider, BindingEngine, and Renderer to be swapped via constructor options |
Enhancements (identified from competitive analysis)
| Priority | Feature | Component(s) | Notes |
|---|---|---|---|
| High | Analytics / Smart Tracking | SDK + Player | Per-session tracking key, event capture, analytics backend integration |
| High | Consent management | SDK | Gate all tracking behind user consent; onConsentAccepted / onConsentDeclined callbacks |
| High | CTA events | SDK + Player | Surface in-animation call-to-action triggers to the host page |
| High | onPlayComplete / onPlayIncomplete | SDK + Player | Distinguish full watches from drop-offs for engagement scoring |
| Medium | Autoplay + mute fallback | SDK + Player | Detect browser autoplay blocks; onAutoplayFailure event + mute-on-start option |
| Medium | Closed captions / transcript | Player | Subtitle track rendering for accessibility and regulatory compliance |
| Medium | Modal / lightbox mode | SDK | Open player as overlay; optional auto-open-time delay |
| Medium | Aspect ratio & responsive sizing | SDK | Single config param drives all responsive CSS |
| Low | Chapter navigation events | SDK + Player | onChapterEnter / onChapterExit for longer-form content |
| Low | Multiple player instances | SDK | Registry API to manage several players on the same page |
| Low | Theming / color schemes | SDK | Per-client branding without a new build |
See Percus Player and SmartEmbed SDK for full API references.