Getting Started
Popcorn integrates with your existing streaming infrastructure — no re-encoding, no new player required. Your content enters the Popcorn network at encoding, our AI reads every scene, and contextually matched ads are served at playback. You earn more per impression because the ads belong there.
Six steps to first revenue
Create your account
Sign up at app.popcorn.stream and select Publisher. Your account enters review. You’ll be notified within 48 hours when you’re approved and active.
Connect your stream
In your dashboard, go to Streams → Connect Stream. Enter your stream endpoint and select your encoding format (HLS or DASH). Popcorn connects to your origin — no changes to your encoder or CDN configuration required.
Enable AI content analysis
Once your stream is connected, toggle Enable Content Analysis in your stream settings. Popcorn’s AI begins reading your content at encoding — topic, mood, narrative, setting. You’ll see scene metadata populating in your dashboard within minutes of your first stream.
Create an ad placement
Go to Placements → New Placement. Select your ad format (Video, Overlay, or Display), set your frequency preferences, and assign the placement to your stream. You’ll receive a placement key.
Distribute via the Popcorn network (optional)
If you want to reduce CDN costs, toggle Distributed Delivery in your stream settings. Your stream will begin routing through Popcorn’s node network. You can monitor delivery quality and cost savings in real time from your dashboard.
Go live
Push your first stream. Ad requests begin automatically. Revenue accrues per impression in your publisher dashboard.
Stream Integration
Popcorn connects to your stream at the origin level. No SDK required for basic integration — a single endpoint connection is sufficient to enable both content analysis and distributed delivery.
Supported formats
| Format | Protocol | Notes |
|---|---|---|
| HLS | HTTPS | Recommended. Supports live and VOD. |
| DASH | HTTPS | Supported. Contact support for CMAF. |
| RTMP | — | Ingest only. Transcoded to HLS before analysis. |
Connecting your stream
# Your stream endpoint format
https://your-origin.com/live/stream.m3u8
# Popcorn will connect to this endpoint and handle:
# — Scene-level AI content analysis at encoding
# — Distributed delivery routing (if enabled)
# — Ad insertion at contextually matched momentsDRM
Popcorn supports Widevine and PlayReady DRM natively. Enable DRM in your stream settings and provide your licence server URL. Popcorn’s delivery network passes DRM tokens through transparently — your content protection is maintained end to end.
Ad Formats
Popcorn supports three ad formats. Each is matched to contextually relevant moments in your content — never triggered by timers alone.
Video (Pre-roll / Mid-roll)
Full-screen video ads served before or during content. Mid-rolls are triggered by scene boundaries, not fixed timestamps — the ad fires at a natural pause in the narrative rather than interrupting a tense moment.
| Parameter | Value |
|---|---|
| Format | VAST 4.2 |
| Max duration | 30 seconds |
| Skippable | Configurable per placement |
| Trigger | Scene boundary or pre-roll |
Overlay
Compact non-linear ads that appear in the lower portion of the player during content playback. Dismissible by the viewer. Contextually matched to the current scene.
| Parameter | Value |
|---|---|
| Format | VAST non-linear |
| Position | Lower-right (default), configurable |
| Dismissible | Yes — close button always visible |
| Trigger | Contextual scene signal |
Display
Banner ads served within the streaming interface — in browse and discovery surfaces, between content rows. Matched to the content the viewer is browsing.
| Size | Notes |
|---|---|
| 728×90 | Leaderboard — browse headers |
| 300×250 | Medium rectangle — content rows |
| 320×50 | Mobile banner |
Creator Attribution
If your platform hosts content from multiple creators, Popcorn can attribute ad revenue per creator and route payouts accordingly. Pass a creator identifier at stream connection time and Popcorn tracks impressions and revenue per creator ID automatically.
Passing creator IDs
# In your stream settings, add:
creator_id: "creator-uuid-or-slug"
# Or pass via the API at stream connection:
POST /api/publisher/v1/streams
{
"streamUrl": "https://your-origin.com/live/stream.m3u8",
"creatorId": "creator-42",
"creatorDisplayName": "Channel Name"
}Querying creator revenue
GET /api/publisher/v1/creators/{creatorId}
Response:
{
"creatorId": "creator-42",
"impressions": { "lifetime": 4821, "last30d": 1204 },
"revenue": { "lifetimeUsdc": 48.21, "last30dUsdc": 12.04 },
"payouts": { "paidUsdc": 20.00, "claimableUsdc": 28.21 }
}API Reference
All publisher API endpoints live under /api/publisher/v1/. Authenticate with a Bearer token issued from your dashboard under API Access.
Authentication
curl -H "Authorization: Bearer $POPCORN_API_KEY" \
https://app.popcorn.stream/api/publisher/v1/statsGET /v1/stats
Account overview — pending balance, lifetime impressions, revenue rollups, delivery stats.
{
"publisher": {
"id": "7f4f9f8d-…",
"displayName": "Your Platform",
"revenueSharePct": 70
},
"balance": {
"pendingUsdc": 142.37,
"paidUsdc": 50.00,
"lifetimeRevenueUsdc": 192.37
},
"impressions": { "lifetime": 18234, "last30d": 4521 },
"delivery": {
"streamHoursLast30d": 12480,
"cdnSavingsPct": 38
},
"asOf": "2026-04-26T15:55:23Z"
}GET /v1/streams
List all connected streams with status and scene analysis state.
GET /v1/placements
List all placements with impression counts and revenue per placement.
GET /v1/creators
All creators ranked by lifetime revenue. Paginated.
Webhooks
Popcorn POSTs events to a URL you register in your dashboard. Bodies are JSON, signed with HMAC-SHA256.
Setup
Dashboard → API Access → Webhooks → enter your https:// endpoint → Save. Copy the signing secret — it’s shown once.
Events
| Event | When |
|---|---|
impression.recorded | After an ad impression is confirmed |
revenue.updated | After your pending balance changes |
stream.connected | When a new stream connects successfully |
stream.disconnected | When a stream goes offline |
Verifying signatures
import express from 'express'
import crypto from 'crypto'
app.post('/popcorn-webhook', express.raw({ type: 'application/json' }), (req, res) => {
const rawBody = req.body.toString('utf8')
const expected = 'sha256=' + crypto
.createHmac('sha256', process.env.POPCORN_WEBHOOK_SECRET)
.update(rawBody)
.digest('hex')
if (req.header('x-popcorn-signature') !== expected) {
return res.status(401).end()
}
const event = JSON.parse(rawBody)
// handle event
res.status(200).end()
})Need help
Whether you’re partway through an integration or scoping out what’s possible, our team is here to help you ship.
Support channels
Email: within 24 hours · Calls: available Mon–Fri, 9am–6pm GMT

