Four steps.No SDK rewrite.
Get your publisher slug
Apply for the partner program. The storyflo team issues a slug like acme-corp and links it to your payout account (Stripe or USDC on Base).
Drop the script tag
Paste one line into your CMS template — header, footer, or article layout. The widget lazy-mounts after DOMContentLoaded so it never blocks your render.
Customize via data-* attributes
Set the accent color, choose an initial voice, or pin the player to an exact spot with [data-storyflo-player]. No build step. No npm install.
Watch the dashboard
Plays, listen-seconds, voice mix, top articles, and net revenue — refreshed daily. Monthly payout in fiat or stablecoin.
Copy. Paste.Ship.
The script is vanilla JavaScript. No React, no npm, no build step. Modern browsers only — your publisher audience is desktop + mobile-class.
<script
src="https://storyflo.com/embed/v1.js"
data-publisher="acme-corp"
data-color="#ec4899"
async
></script><article>
<h1>How curated audio became the next blue ocean</h1>
<p>...</p>
<!-- optional: pin the player to an exact spot -->
<div data-storyflo-player></div>
</article>All data-* options
| Attribute | Default | What it does |
|---|---|---|
| data-publisherrequired | — | Your publisher slug, issued by the storyflo team. Every play, listen-second, and rev-share dollar rolls up to this slug. |
| data-color | #ec4899 | Accent color for the play button and progress bar. Any valid CSS color. |
| data-target | [data-storyflo-player] → article → body | CSS selector for where to mount the player. If unset, the widget tries [data-storyflo-player], then the first <article>, then the body. |
| data-voice | atlas | Initial narrator voice. One of atlas, vox, kira, rune. Listeners can switch from the voice picker once the widget is live. |
| data-inference | https://api.storyflo.com | Override the inference host. Only useful in staging — leave the default in production. |
Every play, attributed.Every dollar, ledgered.
Unique starts and completes per article, broken out by voice and geography.
Median listen length per piece. Quick way to tell which articles your audience finishes.
50% rev-share on Tier 2, paid monthly. Stripe in fiat or USDC / PYUSD on Base.
Same article.New surface.
The widget mounts at the bottom of your existing layout. Your ads, your subscription wall, your reading-time estimate — all untouched. Listeners are an additive audience pool, not a reshuffle.
CSP-friendly.Zero third-party trackers.
- No eval, no Function(), no document.write.
- All DOM insertion uses createElement and textContent — host-page content is never reflected via innerHTML.
- No cookies. No host-page localStorage outside the storyflo:embed:* namespace.
- One connect-src to the inference host, one media-src to the audio CDN. That's it.
- Inline CSS is injected via a single <style> element. If your CSP forbids inline styles, allow style-src 'unsafe-inline' or scope the embed under a strict subdomain.
A new revenue line, in one paste.Apply as a publisher.
Tell us about your titles. We'll issue a slug, walk you through the snippet, and turn audio on for your audience this week.