YouTube Live Stream Real-Time Monitor
Pricing
from $2.50 / 1,000 live stream rows
YouTube Live Stream Real-Time Monitor
Monitor any YouTube livestream's concurrent viewers in real time. List currently-live & recent streams for any channel. Bulk poll 100s of stream IDs. For esports analytics, live-commerce, news-event tracking and brand-safety teams.
Pricing
from $2.50 / 1,000 live stream rows
Rating
0.0
(0)
Developer
SIÁN OÜ
Maintained by CommunityActor stats
1
Bookmarked
2
Total users
1
Monthly active users
2 days ago
Last modified
Categories
Share
YouTube Live Stream Real-Time Monitor — Concurrent Viewers API 📡🚀
🎉 The ONLY actor returning real-time concurrentViewers for ANY YouTube livestream — poll every minute
Perfect for esports analytics, live-commerce intel, news monitoring, brand-safety teams & creator-management agencies.
📋 Overview
Track concurrent viewers on any YouTube livestream — the real-time signal that actually matters. Every other YouTube scraper returns cumulative views; this actor returns concurrentViewers — the live audience count that drives ad-buy timing, peak-detection, and brand-safety alerts. Two operations: list a channel's currently-live and recently-ended streams, or bulk-poll a list of stream IDs for real-time viewer-count snapshots.
Why analytics teams & creator agencies choose us:
- ✅ Only
concurrentViewersfeed on Apify: every other YouTube scraper returns cumulative views — we return the real-time integer. - ⚡ Bulk-poll 500 streams per run: feed an entire tournament bracket, news roster, or talent agency in one snapshot call.
- 🎯 Derived
streamStatefield:live/ended/scheduled/not_live— no manual parsing of YouTube's inconsistent live markers. - 💰 Real-time-friendly pricing: $0.005 per live-stream row at BRONZE, $0.008 per viewer snapshot — built for sub-minute polling loops without quota burn.
- 💎 Auto-resolves channel handles: paste
https://www.youtube.com/@LofiGirlor any handle URL — the actor converts it to the canonical channel ID for you. - ✨ NEW: scheduled premieres tagged
streamState: scheduledwith null viewer count — never confuse upcoming with live.
✨ Features
- 👁 Real-Time Concurrent Viewers:
concurrentViewersinteger for any currently-live YouTube stream — the only one of its kind on Apify. - 📺 Channel Live Streams Listing: paginated list of a channel's currently-live and recently-ended streams, with viewer counts per row.
- 🏷 Derived
streamStateField:live/ended/scheduled/not_live— filter dataset rows by state without writing parsing logic. - 📦 Bulk Snapshot Mode: up to 500 video IDs per run for
viewerSnapshot— bracket-wide tournament polling in one call. - 🔗 Handle & Custom URL Auto-Resolve: paste any YouTube channel URL format — the actor finds the canonical
UC…ID for free. - ⏱ Schedule-Friendly Output: each run is a fresh snapshot row with
_fetchedAttimestamp — combine with Apify Scheduler to build a viewer-count time series. - 🌍 Geo + Language Localization: pass
geo(e.g.US,GB,JP) andlangto control region/locale of the response. - 📦 Schema-Stable Output: every row matches a published dataset schema — predictable for downstream ETL.
- 🛡️ No Account, No API Key, No Proxies: just an Apify token and you're scraping.
🎬 Quick Start
Pick an operation — channel listing or viewer snapshot — pass a channel ID or video IDs, and run. Each run produces one clean dataset row per livestream.
curl -X POST "https://api.apify.com/v2/acts/sian.agency~youtube-live-stream-monitor/runs?token=YOUR_TOKEN" \-H "Content-Type: application/json" \-d '{"operation":"viewerSnapshot","videoIds":"JD-kMIpDfnY"}'
🚀 Getting Started (3 Simple Steps)
Step 1: Choose your operation
channelLiveStreams— pass a channel ID → get the paginated list of currently-live and recently-ended livestreams.viewerSnapshot— pass one or more video IDs → get real-time concurrent viewer counts.
Step 2: Provide your input
- For
channelLiveStreams: a canonical channel ID (UCSJ4gkVC6NrvII8umztf0Ow), a channel URL, or a handle URL (https://www.youtube.com/@LofiGirl). - For
viewerSnapshot: one or more 11-character video IDs (one per line, comma-separated, or full URLs — up to 500).
Step 3: Run it
Optionally tune maxPages (1–25 for channelLiveStreams), geo (country code), and lang (language code). Hit run.
That's it! In seconds, you'll have:
- A dataset of livestreams with
streamStateandconcurrentViewersper row - HTML report summarising peak concurrent viewers and stream-state breakdown
- Time-series-ready rows stamped with
_fetchedAtISO timestamps
📥 Input Configuration
| Field | Type | Required | Description |
|---|---|---|---|
operation | string | Yes | channelLiveStreams (channel listing) or viewerSnapshot (real-time poll) |
channelId | string | Conditional | Required for channelLiveStreams. Canonical channel ID, channel URL, or handle URL |
videoIds | string | Conditional | Required for viewerSnapshot. One per line, comma-separated, or full URLs. Max 500 |
maxPages | integer | No | Pagination cap for channelLiveStreams (default 3, max 25). Ignored for viewerSnapshot |
geo | string | No | ISO 3166-1 alpha-2 country code (e.g. US, GB, IN). Defaults to US |
lang | string | No | ISO 639-1 language code (e.g. en, es, ja). Defaults to en |
Example — list currently-live streams for a channel:
{"operation": "channelLiveStreams","channelId": "UCSJ4gkVC6NrvII8umztf0Ow","maxPages": 1}
Example — bulk viewer-count snapshot:
{"operation": "viewerSnapshot","videoIds": "JD-kMIpDfnY\nEWrX250Zhko"}
📤 Output
Results are saved to the Apify dataset with 20+ fields including:
| Field | Type | Description |
|---|---|---|
streamState | string | live, ended, scheduled, or not_live |
videoId | string | 11-character YouTube video ID |
videoPageUrl | string | Canonical watch URL |
videoTitle | string | Livestream title |
channelId | string | Canonical channel ID (UC…) |
channelTitle | string | Channel display name |
channelPageUrl | string | Canonical channel URL |
isLive | boolean | True iff stream is currently live |
concurrentViewers | integer | Real-time concurrent viewer count |
concurrentViewersText | string | Raw text e.g. 486 watching / 19K watching |
viewCount | integer | Cumulative views (for ended streams) |
likeCount | integer | Like count (real-time for live, cumulative otherwise) |
lengthText | string | LIVE for currently-live, HH:MM:SS for ended |
publishedAt | string | ISO 8601 published / first-streamed timestamp |
thumbnailUrl | string | Best-resolution thumbnail URL |
status | string | success or error |
Example row (channelLiveStreams):
{"_operation": "channelLiveStreams","_fetchedAt": "2026-05-22T00:30:42.013Z","streamState": "live","isLive": true,"videoId": "JD-kMIpDfnY","videoPageUrl": "https://www.youtube.com/watch?v=JD-kMIpDfnY","videoTitle": "lofi hip hop radio 💤 beats to sleep/chill to","channelId": "UCSJ4gkVC6NrvII8umztf0Ow","channelTitle": "Lofi Girl","channelPageUrl": "https://www.youtube.com/channel/UCSJ4gkVC6NrvII8umztf0Ow","concurrentViewers": 486,"concurrentViewersText": "486 watching","lengthText": "LIVE","thumbnailUrl": "https://i.ytimg.com/vi/JD-kMIpDfnY/hqdefault.jpg","status": "success"}
💼 Use Cases & Examples
1. Esports Analytics — Tournament Viewership Curves
Esports analytics teams use this to build live-vs-vod retention dashboards across tournament weekends.
Input: League channel ID, polled every hour during the bracket. Output: Viewer-count snapshots for every active stream + cumulative views for ended. Use: Build peak-concurrent retention dashboards without writing a custom scraper.
2. Live-Commerce Intel — Shopping Event Peak Detection
Live-commerce analytics teams use this to time ad buys and merchandise pushes to peak attention.
Input: A creator's livestream ID, polled every 5 minutes during a product drop.
Output: Sub-minute-fresh concurrentViewers + likeCount + streamState rows.
Use: Plot drop-off curves and trigger ad spend at organic peak-viewer windows.
3. News Outlets — Breaking-Event Livestream Discovery
News organisations use this to catch breaking-news livestreams as they go viral, not after.
Input: News org channel ID, polled every minute.
Output: Real-time channelLiveStreams rows with concurrent viewer counts.
Use: Trigger downstream alerts when concurrent viewers cross a threshold — newsroom-ready.
4. Brand-Safety Teams — Real-Time Creator Live Tracking
Brand-safety teams use this to identify off-brand live behavior on their creator rosters in minutes.
Input: Roster of creator channel IDs, polled hourly. Output: Live-feed of currently-live content with viewer counts and titles. Use: Flag off-brand or unsafe live behavior fast, before screenshots circulate.
5. Creator-Management Agencies — Talent Performance Reports
Talent agencies use this to automate weekly performance reports across the roster.
Input: Talent roster channel IDs, polled nightly via Apify Scheduler. Output: Peak-concurrent and average-concurrent viewer aggregates per stream. Use: Benchmark performance across the roster automatically — no manual logging.
6. Live-Stream Trend Researchers — Viral Moment Detection
Trend research teams use this to surface viral livestream moments before they trend on Twitter.
Input: A watchlist of channel IDs across niches. Output: Snapshot rows showing which streams cross 10K / 100K / 1M concurrent viewers. Use: Build "what's hot right now" feeds for media intelligence dashboards.
7. Creator-Tools Platforms — Premiere & Scheduled Tracking
Creator-tools platforms use this to detect scheduled premieres and notify their users.
Input: Subscribed channels' IDs, polled hourly.
Output: Rows tagged streamState: scheduled with null concurrentViewers.
Use: Power "your subscriptions are going live in N minutes" notifications.
🔗 Integration Examples
JavaScript / Node.js
import { ApifyClient } from 'apify-client';const client = new ApifyClient({ token: 'YOUR_TOKEN' });const run = await client.actor('sian.agency/youtube-live-stream-monitor').call({operation: 'viewerSnapshot',videoIds: 'JD-kMIpDfnY\nEWrX250Zhko',});const { items } = await client.dataset(run.defaultDatasetId).listItems();for (const row of items) {console.log(`${row.videoTitle}: ${row.concurrentViewers} watching now (${row.streamState})`);}
Python
from apify_client import ApifyClientclient = ApifyClient('YOUR_TOKEN')run = client.actor('sian.agency/youtube-live-stream-monitor').call(run_input={'operation': 'channelLiveStreams','channelId': 'UCSJ4gkVC6NrvII8umztf0Ow','maxPages': 1,})for item in client.dataset(run['defaultDatasetId']).iterate_items():print(item['streamState'], item.get('concurrentViewers'), '—', item.get('videoTitle'))
cURL
curl -X POST "https://api.apify.com/v2/acts/sian.agency~youtube-live-stream-monitor/runs?token=YOUR_TOKEN" \-H "Content-Type: application/json" \-d '{"operation":"channelLiveStreams","channelId":"UCSJ4gkVC6NrvII8umztf0Ow","maxPages":1}'
Automation Workflows (N8N / Zapier / Make)
- Trigger: Apify Scheduler (
*/5 * * * *for 5-minute polling) or webhook - HTTP Request: Call this actor's run API with seed channel ID or video IDs
- Process: Iterate the dataset rows in your workflow — each is one snapshot
- Action: Push to Google Sheets, Slack, BigQuery, Notion, or your alerting stack
📊 Performance & Pricing
FREE Tier (Try It Now)
- Generous free credit covers initial channel listings or single viewer snapshots — full feature access, same data quality.
- No credit card required.
- Perfect for testing the real-time feed against your favorite livestream.
PAID Tier (Production-Ready)
- Unlimited livestream rows and viewer snapshots per run.
- Pay-per-event: only charged for successful rows (errors don't burn your credit).
- Pricing ladder scales from BRONZE to DIAMOND as your volume grows.
Pricing Highlights — live-stream-row (headline):
- BRONZE:
$0.005per channel-live-stream row - GOLD / PLATINUM / DIAMOND:
$0.0025per row
Real-time mode — viewer-count-snapshot:
- BRONZE:
$0.008per snapshot - GOLD / PLATINUM / DIAMOND:
$0.004per snapshot
Run start — apify-actor-start:
- BRONZE+ (paying tiers):
$0.002per run
💰 Designed for sub-minute polling loops — pricing is built to make real-time monitoring viable at scale.
❓ Frequently Asked Questions
Q: Does this work for any YouTube channel?
A: Yes — any public channel. Private / membership-gated streams return as not_live or an error row.
Q: How fresh is the concurrent viewer count? A: It's pulled live from YouTube's player metadata endpoint at the moment the run executes. Expect <30 seconds freshness.
Q: Can I poll the same stream every minute?
A: Yes — combine with Apify Scheduler. Each run is a fresh snapshot row with _fetchedAt timestamp; no in-actor cooldowns.
Q: What if the stream ends mid-run?
A: For viewerSnapshot: the row returns streamState: not_live (no concurrentViewers). For channelLiveStreams: the row will be streamState: ended with cumulative viewCount.
Q: Does it handle scheduled premieres?
A: Yes — they're tagged streamState: scheduled. concurrentViewers is null until the stream actually starts.
Q: How many video IDs can I poll per run?
A: Up to 500 per viewerSnapshot run. Esports orgs can poll a whole tournament bracket in a single call.
Q: What output formats are available? A: JSON, CSV, Excel, RSS, HTML — export directly from the Apify dataset.
Q: Is this legal? A: Yes — we only extract publicly available data that YouTube already exposes to every viewer. See our legal section below.
YouTube is a trademark of Google LLC. This actor is an independent tool and is not affiliated with, endorsed by, or sponsored by Google LLC.
🐛 Troubleshooting
Channel ID not resolving
- Paste the canonical
UC…ID, or any channel/handle URL. If using a handle URL, ensure the channel exists by opening it in a browser first.
streamState: not_live for what I thought was a live stream
- The stream may have just ended, or the video isn't actually a livestream. Check the URL in a browser to confirm. Membership-gated streams also surface as
not_live.
concurrentViewers is null on a streamState: live row
- Rare upstream timing edge — the stream went live within the last few seconds. Re-poll after 30s to get a populated count.
Pagination stops earlier than maxPages
- That's expected — the run stops when YouTube returns no more results for that channel.
Geo / language not returning local results
- Most livestreams surface globally;
geoandlangadjust localized labels but don't filter the underlying stream set.
⚖️ Is it legal to scrape data?
Our actors are ethical and do not extract any private user data, such as email addresses, gender, or location. They only extract what the user has chosen to share publicly. We therefore believe that our actors, when used for ethical purposes by Apify users, are safe.
However, you should be aware that your results could contain personal data. Personal data is protected by the GDPR in the European Union and by other regulations around the world. You should not scrape personal data unless you have a legitimate reason to do so. If you're unsure whether your reason is legitimate, consult your lawyers.
You can also read Apify's blog post on the legality of web scraping.
🤝 Support
Join our active support community
- For issues or questions, open an issue in the actor's repository
- Check SIÁN Agency Store for more automation tools
- ✉️ apify@sian-agency.online
Built by SIÁN Agency | More Tools