The Problem

Adult creators today face a frustrating reality: centralized platforms take massive revenue cuts, impose unpredictable content policies, and offer no real infrastructure for cross-site syndication. If you run an independent adult site, you're an island. Your content lives and dies on your domain alone, with no standardized way to share it with partner sites while keeping your ad revenue.
We set out to change that. Secreto Mio is launching a decentralized feed-sharing network — an open standard that lets creators publish a JSON feed manifest on their own infrastructure. Any participating site can pull that feed and display the content, complete with the creator's own ad tags. Revenue flows directly to the creator. No middleman. No platform cuts on syndicated content.
At a higher level, you can think of it as the ultimate parasite killer. The user flow is conceptually the same as uploading your content to a massive tube platform, with one critical difference: it physically strips middlemen of the ability to dictate your revenue split. By locking the raw video segments behind a cryptographic token that only unlocks after your own ad tags have fired, the power dynamic is inverted. Tube sites are reduced back to what they should have been all along: discoverability engines. They still benefit from displaying thousands of high-quality clips to attract traffic to their domain, but they are mathematically forced to route 100% of the in-video ad revenue directly to the creator.
AVN covered the announcement, calling it a step toward meaningful creator independence in the adult industry.
| Feature | Tube Sites (Pornhub, XVideos, xHamster) | Decentralized Network |
|---|---|---|
| Ad Revenue | Platform keeps the majority, pays creators a fraction | You keep 100% — ads are embedded in your feed and travel with your content |
| Revenue Rate | Platform-dictated CPM, no negotiation | Your ad network, your CPM, your terms |
| Content Ownership | Lives on their servers, removable without notice | You host on your own infrastructure — nobody can touch it |
| Platform Risk | One ban or algorithm change wipes your income overnight | No single point of failure — feed lives on your own storage |
| Rules & Moderation | Spam flags, rank penalties, quality flags throttling your reach | No arbitrary platform rules suppressing your content |
| Discovery | Algorithm favours big studios and platform-preferred channels | Cross-creator discovery — audiences find you through other creators' sites organically |
| Traffic Diversity | 100% dependent on one platform | Distributed across multiple independent sites naturally |
| Piracy | Content ripped and rehosted with no compensation, endless DMCA | Gives pirates a legitimate syndication path — converts theft into compensated distribution |
| Infrastructure Cost | Platform extracts revenue to cover costs they control | You only pay for your own storage regardless of how many sites embed your feed |
| Reliability | Content still goes down, gets corrupted, performs slowly — no tools given to creators to monitor it | Same real-world risks exist, but health monitoring is built in from day one — availability, speed, broken links, and security threats scanned automatically, so you're always ahead of the problem |
| New Site Launch | Requires massive content budget and infrastructure investment | Any new site can launch with a full content library from day one by aggregating existing feeds |
| Long-Term Independence | Always one policy change away from losing everything | Your audience and revenue are yours — no platform can revoke them |
The Problem with iFrame Embeds
A common question is: Why build a robust JSON feed API with token-gated streams instead of just letting people copy-paste <iframe> embeds like traditional tube sites?
While iframe embeds are straightforward to copy-paste, they come with massive compromises that make them unsuitable for a professional, decentralized ecosystem:
- Complete White-Labeling & UX Control: An
iframeforces the origin's video player, branding, watermark, and custom controls onto the host's website. With our JSON feed, consumers get the underlying.m3u8playlist. The video plays natively inside their player (like Video.js or FluidPlayer). The end-user never realizes the video is hosted externally, allowing partner sites to build a seamless, premium Netflix-like experience. - Automated SEO & Headless Metadata: If a partner site embeds thousands of iframes, they must manually type out their metadata or build fragile DOM scrapers to steal it. With the JSON API, partners automatically ingest the
title,duration,tags, andthumbnaildirectly into their database. The feed acts exactly like a Headless CMS. - Performance & Page Speed: iFrames are incredibly heavy. Loading an iframe forces the browser to resolve a complete secondary HTML document, download disjointed CSS payloads, and execute redundant tracking scripts. Passing a raw stream to the host's native player keeps the consumer's web application lightning fast.
- Advanced Analytics & Event Tracking: When a video is trapped inside a cross-origin iframe, the host site has absolutely no idea if the user paused the video, skipped to the middle, or dropped off after 5 seconds. By binding the video natively to their own DOM, consumers can hook into precise analytics to measure player engagement.
In short: if you just want to share a clip on a forum, an iframe is fine. But we are building a true Decentralized Syndication Network. By supplying independent sites with raw foundational data blocks, they can build massively performant video platforms on top of standard infrastructure, while the network mathematically guarantees you get paid for your native impressions.
How It Works
The system is built on three simple ideas:
- You host your own feed. A JSON file on your CDN or server, following a standardized schema.
- You register with the network. Visit secretomio.com/creators and submit your site. Your feed URL is stored, not your content.
- Consuming sites pull your feed and serve your ads. When another site displays your videos, they use your ExoClick zone IDs. You earn the ad revenue.
There's no central database of video metadata. No approval queue. No moderation gate. Each creator is the single source of truth for their own content. Secreto Mio stores only your registration record (name, domain, feed URL, contact info). This is truly decentralized — like how Google indexes the web without hosting it.
The Feed Specification
The feed is a standard JSON document with three required top-level fields: version, producer, and items. Here's a minimal example:
{
"version": "1.0",
"producer": {
"name": "My Studio",
"website": "https://mystudio.com",
"2257": "https://mystudio.com/legal/2257",
"logo": "https://mystudio.com/logo.png"
},
"items": [
{
"id": "video-001",
"title": "My First Video",
"thumbnail": "https://cdn.mystudio.com/thumb-001.jpg",
"video": {
"hls": "https://cdn.mystudio.com/video-001/master.m3u8"
},
"duration": 420,
"categories": ["Amateur"],
"models": ["Jane Doe"],
"date": "2026-03-01"
}
]
}Each item represents a video with its metadata, thumbnail, and HLS streaming URL. All URLs must be absolute HTTPS and publicly accessible.
Required Fields
- version: String. Must be "1.0" to match current spec.
- producer.name: String. The creator or studio display name.
- producer.website: String. The full website URL of the creator.
- producer.2257: String. Complete URL to the publisher's 2257 compliance and record-keeping document.
- items: Array. List of content item objects.
- item.id: String. Unique content identifier.
- item.title: String. Display title of the content.
- item.thumbnail: String. Absolute HTTPS URL to the full thumbnail image.
- item.video: Object. Required for video content.
- item.video.hls: String. Absolute HTTPS URL to the HLS master playlist (.m3u8).
- item.image: Object. Required for image content.
- item.image.src: String. Absolute HTTPS URL to the high-res image.
Optional Fields
- producer.logo: String. URL to the logo image (1:1 ratio recommended).
- item.description: String. Brief description or alternative title.
- item.duration: Number. Duration of the video in seconds (0 or omitted for images).
- item.external_url: String. Optional URL routing to a third-party site if the content cannot be hosted natively.
- item.categories: Array. List of category strings (e.g., ["Amateur", "POV"]).
- item.tags: Array. List of tag strings.
- item.models: Array. List of model/performer names.
- item.date: String. Release date in ISO format (YYYY-MM-DD).
Ad Revenue Integration

This is where it gets interesting. The feed includes an optional ads block where you specify your ExoClick zone IDs. When a consuming site plays your video, it loads your VAST preroll and your banner zones. The impressions are tracked in your ExoClick account. You keep 100% of the syndicated ad revenue.
"ads": {
"exoclick": {
"preroll_vast": "https://s.magsrv.com/v1/vast.php?idzone=YOUR_ZONE",
"banner_zone": "YOUR_BANNER_ZONE",
"overrides": {
"partnersite.com": {
"preroll_vast": "https://s.magsrv.com/v1/vast.php?idzone=PARTNER_ZONE"
}
}
}
}The overrides key is for creators who provision per-domain zones in ExoClick (recommended for best fill rates). If a consuming site isn't in your overrides, the global zone IDs are used as fallback. ExoClick's Sub ID feature (&sub=consumer-domain) enables tracking which partner site generated each impression.
Per-Model Revenue Tracking
Secreto Mio takes this further with per-model feeds. Instead of one monolithic feed, each contracted model gets their own feed endpoint with their own dedicated ExoClick ad zones:
GET /api/creators/secretomio.com/feeds/charlot-silver
GET /api/creators/secretomio.com/feeds/isabela-quintero
GET /api/creators/secretomio.com/feeds/cristina-collThis means revenue can be attributed to each individual model, enabling exact payment based on what their content actually earned. No more splitting a global ad revenue pool — each model's earnings are tracked independently via their dedicated ad zones.
Player Integrations (Implementing the VAST Preroll)
Once you have the VAST tag (item.ads.exoclick.preroll_vast), you need to instruct your video player to load it. Open-source players are highly recommended because they parse the XML natively:
- Video.js: Use the
videojs-contrib-adsandvideojs-vast-vpaidplugins to pass the tag directly into the setup options. - Fluid Player: VAST is built directly into Fluid Player's core. Simply pass
{ vastOptions: { adList: [{ roll: 'pre', vastTag: feedItem.ads.exoclick.preroll_vast }] } }. - JW Player: Use the built-in advertising client:
{ advertising: { client: 'vast', schedule: { adbreak: { offset: 'pre', tag: feedItem.ads.exoclick.preroll_vast } } } }.
Vanilla HTML5 <video> (Quickstart UI)
If you are strictly using vanilla HTML5 <video> tags with HLS.js (like the native Secreto Mio player does for maximum performance), incorporating VAST requires fetching and parsing the XML manually, as well as looping through the feed API to draw the video cards. Best of all, because the API sets Access-Control-Allow-Origin: *, you do not have to worry about CORS! Any frontend code from any domain can fetch the feeds natively.
Here is a complete skeleton layout for drawing the video grid and preparing the player modal:
<!-- The Player Overlay -->
<div id="player-modal" style="display:none; position:fixed; top:0; left:0; width:100%; height:100%; background:black; z-index:100">
<button onclick="document.getElementById('player-modal').style.display='none'">Close</button>
<video id="main-video" controls playsinline style="width:100%; height:80vh"></video>
<!-- The Ad Player goes ON TOP of the main video -->
<video id="ad-overlay" playsinline muted style="display:none; position:absolute; top:0; left:0; width:100%; height:80vh"></video>
</div>
<!-- The Feed Grid -->
<div id="feed-grid"></div>And the Javascript to pull the feed payloads into cards. We iterate over data.items and append them to the UI, applying event listeners to invoke the ad wrapper:
fetch('https://public.secretomio.com/api/creators/secretomio.com/feeds/abraham-bach')
.then(res => res.json())
.then(data => {
const grid = document.getElementById('feed-grid');
// 1. Loop through the items array
data.items.forEach(item => {
const card = document.createElement('div');
card.className = 'video-card';
card.innerHTML = `
<img src="${item.thumbnail}" alt="Thumbnail" style="width:100%">
<h3>${item.title}</h3>
<p>${item.description || ''}</p>
<small>${item.date || ''}</small>
`;
// 2. Play video click handler
card.onclick = () => {
const hlsUrl = item.video?.hls;
let vastUrl = null;
// Inherit ad zones natively from the payload
if (item.ads?.exoclick?.preroll_vast) vastUrl = item.ads.exoclick.preroll_vast;
else if (data.ads?.exoclick?.preroll_vast) vastUrl = data.ads.exoclick.preroll_vast;
openPlayer(hlsUrl, vastUrl);
};
grid.appendChild(card);
});
});When a video is clicked, we pass the VAST tag to the pre-roll invocation wrapper:
function openPlayer(hlsUrl, vastUrl) {
document.getElementById('player-modal').style.display = 'block';
if (vastUrl) playPreRoll(vastUrl, hlsUrl);
else authorizeAndPlay(hlsUrl);
}
function playPreRoll(vastUrl, targetHlsUrl) {
const adVideo = document.getElementById('ad-overlay');
fetch(vastUrl)
.then(r => r.text())
.then(xmlString => {
const doc = new DOMParser().parseFromString(xmlString, 'text/xml');
// Follow any VAST wrappers if Exoclick proxies the tag
const wrapper = doc.querySelector('VASTAdTagURI');
if (wrapper) return playPreRoll(wrapper.textContent.trim(), targetHlsUrl);
// Find the MP4 MediaFile
const mediaFiles = Array.from(doc.querySelectorAll('MediaFile'));
const targetFile = mediaFiles.find(tag => tag.getAttribute('type') === 'video/mp4');
if (!targetFile) return authorizeAndPlay(targetHlsUrl);
// Show ad overlay over the main video
adVideo.src = targetFile.textContent.trim();
adVideo.style.display = 'block';
// Resume main video authorization when ad ends!
adVideo.onended = () => {
adVideo.style.display = 'none';
authorizeAndPlay(targetHlsUrl);
};
adVideo.play();
});
}For production, your custom parser should also collect <TrackingEvents> (like start, firstQuartile, complete) and fire them by triggering background fetch() requests so ExoClick effectively registers the completion rates to calculate the CPM. If you don't parse the tracking events you will lose out on fill rate!
VAST Proof-of-Play & Token Gating
A major challenge with decentralized video syndication is ensuring that third-party tube sites actually show your ads before playing your content. A malicious consumer could easily strip the VAST tag and serve your raw .m3u8 feed ad-free, depriving creators of revenue.
To solve this, Secreto Mio has pioneered a rigorous Token-Gated Stream Architecture mechanism that strictly forces downstream consumers to prove VAST compliance before HLS video chunks are unlocked:
- Restricted Master Playlist: The raw
master.m3u8URLs generated in the feed cannot be hotlinked. Fetching them directly will result in an immediate403 Forbiddenfrom the media CDN edge worker. - Ad-Completion API Handshake: Downstream consumers must fully render the VAST preroll overlay on their frontend. ONLY once the
onendedVAST tracking completes does their web client negotiate with the central API endpoint (POST /api/tokens/stream), signaling proof of ad completion. - Time-Limited Cryptographic Signatures: Upon receiving the completion signal, the API issues an
HMAC-SHA256signed, 4-hour temporal token strictly bound to that specific video path. - Session Cookie Hand-off: The video player makes the authorized request via query parameter
?token=XYZ. The edge media proxy mathematically verifies the signature. Rather than returning the file naked—which would cause subsequent nested.tschunk requests to fail since native HTML5 players strip query parameters during sub-manifest execution—the proxy transparently issues anHttpOnlystream session cookie to gracefully authorize all child resources seamlessly.
This guarantees a zero-trust model where third-party integrators cannot siphon decentralized video bandwidth without engaging in the ad protocol. Below is the authorizeAndPlay() snippet that invokes the token exchange and connects the stream to video.js or hls.js:
function authorizeAndPlay(hlsUrl) {
const urlObj = new URL(hlsUrl);
fetch('https://public.secretomio.com/api/tokens/stream', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ videoPath: urlObj.pathname, action: 'ad_complete' })
})
.then(res => res.json())
.then(data => {
const authorizedUrl = hlsUrl + '?token=' + data.token;
const mainVideo = document.getElementById('main-video');
// Render using standard HLS engine
if (Hls.isSupported()) {
const hls = new Hls();
hls.loadSource(authorizedUrl);
hls.attachMedia(mainVideo);
hls.on(Hls.Events.MANIFEST_PARSED, () => mainVideo.play());
} else if (mainVideo.canPlayType('application/vnd.apple.mpegurl')) {
mainVideo.src = authorizedUrl;
mainVideo.play();
}
});
}Best Practices for Integrating Feeds
When building a consumer application or tube site that integrates third-party feeds, you will encounter significant reliability and SEO challenges if you fetch remote feeds on-the-fly. To maintain a professional user experience, consider the following architecture:
- The Aggregation Pattern (Cron Engine): Do not fetch JSON URLs live when a user loads a page. Instead, build a background worker that periodically polls your registered feeds and stores the active ones in your own local database. Serve your frontend entirely from your fast local cache.
- Handle Degraded Feeds Gracefully: Track consecutive fetch failures. If a creator's server goes offline, quarantine their feed dynamically so your application's UX does not suffer from 404s or infinite loading spinners.
- Feed Health Synchronization: Before displaying thumbnails or constructing links to a model's videos, verify their feed's structural integrity using the
GET /api/creators/{domain}/healthendpoint. If a feed reports poor health due to validation failures or broken media, do not attempt to play its videos or render its cards in your user interface. - SEO & The
noindexRule: Because decentralized content is hosted independently and can disappear, you must not index third-party feed items on Google. Apply<meta name="robots" content="noindex, nofollow">to dynamic watch pages to prevent search engines from hitting dead links and penalizing your site's overall discoverability.
Security & Validation
Before any creator registration is persisted, submitted feed URLs are fetched and validated server-side:
- Valid JSON parsing and schema compliance via strict Zod typing
- SQL injection payload escaping via the sqlstring library and heuristics
- XSS vector destruction via DOM payload testing utilizing the xss engine
- URL scheme validation (HTTPS only, no data: or javascript: schemes)
- 10MB size cap to prevent abuse
- Captcha on the registration form to prevent automated submissions
How to Join
Visit secretomio.com/creators to register. You'll need your site name, domain, contact email, your feed URL (which must contain your publisher's 2257 compliance link inside the producer block), and optionally a logo. Registration is instant — there's no approval queue. Once registered, your listing appears on the network and other sites can discover your feed.
The technical specification and full payload structure is detailed above. If you're a developer integrating consuming sites, you can also browse the unified API directly:
GET /api/creators List all creators
GET /api/creators/{domain} Get a specific creator
GET /api/creators/{domain}/health Get the current health status of a creator feed
GET /api/creators/{domain}/feeds List available feeds
GET /api/creators/{domain}/feeds/{handle} Get a specific feedRead the AVN article for more background on the vision behind this project.
Comments
Loading comments...