Get real-time YouTube upload notifications using PubSubHubbub (PuSH) — the only webhook mechanism YouTube offers, and it costs zero quota units. POST to https://pubsubhubbub.appspot.com/subscribe with your callback URL and channel ID. Your server receives Atom XML on uploads and title/description changes. Subscriptions expire (~10 days) and must be renewed. Use videos.list (1 quota unit) to enrich the notification with full metadata before cross-posting to Discord, Slack, or email.
API Quick Reference
None (PuSH) / API Key (videos.list enrichment)
PuSH: no quota cost; videos.list: 1 unit per request
Atom XML (PuSH payload); JSON (videos.list response)
REST only
YouTube PubSubHubbub Webhooks for Upload Notifications
YouTube Data API v3 (https://www.googleapis.com/youtube/v3) is primarily a pull-based REST API, but it does support one push mechanism: PubSubHubbub (PuSH), a webhook protocol based on the W3C WebSub specification. PuSH costs zero quota units — it's completely separate from the 10,000 units/day quota. When a channel uploads a video or changes a video's title/description, the PuSH hub pushes an Atom XML payload to your callback URL.
To receive push notifications, POST a subscription request to https://pubsubhubbub.appspot.com/subscribe with your callback URL and the topic URL for the channel you want to monitor. The hub immediately sends a GET verification request to your callback with a hub.challenge parameter — your server must respond with 200 OK and the challenge value as the raw response body within the verification timeout, or the subscription is rejected.
Subscriptions have a finite lease (~10 days, though Google does not document a fixed number). You must re-subscribe periodically — implement a scheduler that re-POSTs subscriptions before they expire. PuSH only fires on uploads and title/description changes — it does NOT notify on deletes, view count changes, comments, likes, or live stream state changes. The official documentation is at https://developers.google.com/youtube/v3/guides/push_notifications.
https://pubsubhubbub.appspot.comSetting Up YouTube PubSubHubbub Authentication
PubSubHubbub subscriptions require no authentication — they are publicly accessible. You only need a public HTTPS URL as your callback. For videos.list enrichment calls, use an API key (not OAuth) since you are only reading public video metadata. If you want to monitor private videos or analytics, you would need OAuth, but for public upload notifications an API key is sufficient.
- 1Go to console.cloud.google.com and create a project
- 2Enable YouTube Data API v3: APIs & Services > Library > YouTube Data API v3 > Enable
- 3Create an API key: APIs & Services > Credentials > Create Credentials > API key
- 4Optionally restrict the key to YouTube Data API v3 only under Key restrictions
- 5Get your callback URL ready — it must be a public HTTPS endpoint (e.g., https://yourapp.com/youtube/callback)
- 6For local development, use ngrok or a similar tunneling tool to expose localhost with HTTPS
- 7Find the channel ID you want to monitor — it looks like UCxxxxxxxxxxxxxxxxxxxxxxxx and can be found in the channel's About page URL
1# Store your API key in environment variable2import os3API_KEY = os.environ['YOUTUBE_API_KEY'] # for videos.list enrichment45# No authentication needed for PuSH subscription itself6# Callback URL must be public HTTPS7CALLBACK_URL = os.environ['PUSH_CALLBACK_URL'] # e.g. https://yourapp.com/yt/callbackSecurity notes
- •Store API keys in environment variables — never hardcode in source files
- •Use hub.secret (a shared secret) when subscribing to validate push notification authenticity via HMAC-SHA1 signature
- •Your callback URL must use HTTPS — HTTP callbacks are rejected by the PuSH hub
- •Validate the hub.challenge response carefully — returning anything other than the exact challenge string rejects the subscription
- •Implement idempotency in your callback handler — the PuSH hub may retry delivery on 5xx responses
Key endpoints
https://pubsubhubbub.appspot.com/subscribeSubscribe to upload notifications for a YouTube channel. Sends an application/x-www-form-urlencoded body. The hub immediately sends a GET to your callback for verification.
| Parameter | Type | Required | Description |
|---|---|---|---|
hub.callback | string | required | Your public HTTPS callback URL |
hub.mode | string | required | subscribe or unsubscribe |
hub.topic | string | required | https://www.youtube.com/xml/feeds/videos.xml?channel_id=CHANNEL_ID |
hub.verify | string | optional | sync or async (async is recommended) |
hub.lease_seconds | number | optional | Requested lease duration in seconds (hub may override; ~10 days max) |
hub.secret | string | optional | Shared secret for HMAC-SHA1 signature validation of push payloads |
Request
1hub.callback=https://yourapp.com/yt/callback&hub.mode=subscribe&hub.topic=https://www.youtube.com/xml/feeds/videos.xml?channel_id=UCxxxxxxxxxxxxxxxxxxxxxxxx&hub.verify=async&hub.lease_seconds=864000Response
1HTTP 202 Accepted (empty body) — verification handshake happens asynchronously via GET to callback{your_callback_url}?hub.mode=subscribe&hub.topic=...&hub.challenge=...&hub.lease_seconds=...Verification handshake sent by the PuSH hub to your callback immediately after subscription. Your server must respond 200 OK with the hub.challenge value as the raw body.
| Parameter | Type | Required | Description |
|---|---|---|---|
hub.mode | string | required | subscribe or unsubscribe |
hub.challenge | string | required | Random string your server must echo back as the response body |
hub.lease_seconds | number | optional | Actual lease duration granted by the hub |
Response
1HTTP 200 OK2Content-Type: text/plain34{hub.challenge_value}{your_callback_url} (Atom XML payload from hub)Push notification sent to your callback when a channel uploads a video or changes title/description. Body is Atom XML containing videoId and channelId.
| Parameter | Type | Required | Description |
|---|---|---|---|
yt:videoId | string | required | The uploaded video ID — use this to call videos.list for full metadata |
yt:channelId | string | required | The channel that uploaded the video |
Request
1<?xml version='1.0' encoding='UTF-8'?><feed xmlns:yt="http://www.youtube.com/xml/schemas/2015" xmlns="http://www.w3.org/2005/Atom"><link rel="hub" href="https://pubsubhubbub.appspot.com"/><entry><yt:videoId>dQw4w9WgXcQ</yt:videoId><yt:channelId>UCxxxxxxxxxxxxxxxxxxxxxxxx</yt:channelId><title>Video Title</title><published>2026-01-15T10:00:00+00:00</published></entry></feed>Response
1Your server must return 2xx to acknowledge. Non-2xx triggers hub retries.https://www.googleapis.com/youtube/v3/videos?part=snippet,statistics&id={videoId}&key={apiKey}Fetches full video metadata after receiving a PuSH notification. The Atom payload only contains videoId, title, and channelId — use this endpoint to get description, tags, thumbnail, view count, and more. Costs 1 quota unit.
| Parameter | Type | Required | Description |
|---|---|---|---|
id | string | required | Video ID from the PuSH notification |
part | string | required | snippet,statistics for full metadata |
key | string | required | Your YouTube Data API v3 API key |
Response
1{"items": [{"id": "dQw4w9WgXcQ", "snippet": {"title": "Video Title", "description": "...", "thumbnails": {"high": {"url": "https://..."}}, "tags": ["tutorial"]}, "statistics": {"viewCount": "0"}}]}Step-by-step automation
Subscribe to YouTube Channel Upload Notifications
Why: Without subscribing, the PuSH hub will not send any notifications — you must register your callback for each channel you want to monitor.
POST to https://pubsubhubbub.appspot.com/subscribe with form-encoded parameters. The hub responds with 202 Accepted and then sends a verification GET to your callback. Store the subscription topic and renewal time so you can re-subscribe before expiry (~10 days).
1curl -X POST https://pubsubhubbub.appspot.com/subscribe \2 -d 'hub.callback=https://yourapp.com/yt/callback' \3 -d 'hub.mode=subscribe' \4 -d 'hub.topic=https://www.youtube.com/xml/feeds/videos.xml?channel_id=UCxxxxxxxxxxxxxxxxxxxxxxxx' \5 -d 'hub.verify=async' \6 -d 'hub.lease_seconds=864000' \7 -d 'hub.secret=YOUR_SHARED_SECRET'Pro tip: Store the subscription expiry time (current time + lease_seconds) in a database. Run a daily job to check and renew any subscriptions expiring within 24 hours.
Expected result: HTTP 202 Accepted from the hub. Shortly after, your callback receives a GET with hub.challenge — your server must echo it back to complete subscription.
Handle the Verification Handshake
Why: The PuSH hub will not send any notifications until your callback successfully echoes the hub.challenge — verification is mandatory.
When the hub sends a GET to your callback URL, parse the hub.challenge query parameter and return it as the raw response body with HTTP 200. Any other response rejects the subscription. This must happen within the verification timeout (typically a few seconds).
1# This is what the hub sends to your callback (you handle this in your web framework)2# GET /yt/callback?hub.mode=subscribe&hub.topic=https%3A%2F%2F...&hub.challenge=RANDOM_STRING&hub.lease_seconds=8640003# Your server MUST return 200 OK with body = RANDOM_STRINGPro tip: Always use hub.secret and validate HMAC-SHA1 signatures on incoming POSTs — without this, anyone who knows your callback URL can send fake notifications.
Expected result: The hub confirms the subscription and starts sending POST notifications to your callback when videos are uploaded.
Parse the Atom XML Upload Notification
Why: The PuSH payload is Atom XML, not JSON — you must parse it to extract the videoId and channelId for enrichment.
When a channel uploads a video, the hub POSTs Atom XML to your callback. Parse the yt:videoId and yt:channelId elements. Then call videos.list with the videoId to get the full metadata (title, description, thumbnail, tags) needed for cross-channel alerts.
1# Example of what the hub POSTs to your callback (Atom XML):2# POST /yt/callback3# Content-Type: application/atom+xml4#5# <?xml version='1.0' encoding='UTF-8'?>6# <feed xmlns:yt="http://www.youtube.com/xml/schemas/2015" xmlns="http://www.w3.org/2005/Atom">7# <entry>8# <yt:videoId>dQw4w9WgXcQ</yt:videoId>9# <yt:channelId>UCxxxxxxxxxxxxxxxxxxxxxxxx</yt:channelId>10# <title>Video Title</title>11# <published>2026-01-15T10:00:00+00:00</published>12# </entry>13# </feed>Pro tip: The PuSH notification fires on BOTH new uploads AND title/description changes. Check snippet.publishedAt vs snippet.updatedAt in the videos.list response to distinguish new uploads from edits.
Expected result: Parsed videoId and channelId from Atom XML, plus enriched metadata from videos.list including thumbnail URL, description, and tags.
Send Cross-Channel Alerts (Slack, Discord, Email)
Why: The whole point of upload detection is to cross-post alerts — format the video metadata and post to whichever channels your audience uses.
After parsing the notification and enriching with videos.list, format a message with the video title, thumbnail, URL, and channel name, then POST to your notification destination. For Discord, POST JSON to a webhook URL. For Slack, use chat.postMessage or an Incoming Webhook. For email, use SendGrid or similar.
1# Discord webhook alert2curl -X POST "https://discord.com/api/webhooks/WEBHOOK_ID/WEBHOOK_TOKEN" \3 -H "Content-Type: application/json" \4 -d '{5 "embeds": [{6 "title": "New Video: My Video Title",7 "url": "https://youtu.be/VIDEO_ID",8 "description": "Video description here...",9 "image": {"url": "https://img.youtube.com/vi/VIDEO_ID/hqdefault.jpg"},10 "color": 1671168011 }]12 }'Pro tip: For Discord, use embeds with image thumbnails for much better visual presentation. Avoid plain text links — they generate poor previews.
Expected result: A formatted message appears in your Discord server, Slack channel, or email with the video title, thumbnail, and direct YouTube link.
Renew Subscriptions Before They Expire
Why: PuSH subscriptions expire (~10 days) — without renewal, you silently stop receiving notifications.
When you subscribe, store the channel ID and expiry timestamp. Run a daily cron job that checks for subscriptions expiring within 48 hours and re-subscribes them. Re-subscribing sends a new verification GET to your callback, which you handle the same way as the initial subscription.
1# Re-subscribe is identical to initial subscribe — just POST again2curl -X POST https://pubsubhubbub.appspot.com/subscribe \3 -d 'hub.callback=https://yourapp.com/yt/callback' \4 -d 'hub.mode=subscribe' \5 -d 'hub.topic=https://www.youtube.com/xml/feeds/videos.xml?channel_id=UCxxxxxxxxxxxxxxxxxxxxxxxx' \6 -d 'hub.verify=async' \7 -d 'hub.lease_seconds=864000'Pro tip: Use a cron job running every 24 hours with a 48-hour renewal window — this gives you a full day of buffer if the renewal cron fails once.
Expected result: All subscriptions are renewed before expiry and continue delivering upload notifications without interruption.
Complete working code
Complete webhook server that subscribes to multiple YouTube channels, handles PuSH verification, validates signatures, parses Atom XML upload notifications, enriches with videos.list metadata, and sends cross-channel alerts to Discord and Slack. Includes subscription renewal logic.
1from flask import Flask, request, Response2import requests, hmac, hashlib, xml.etree.ElementTree as ET3import os, json, time, logging4from datetime import datetime, timedelta56app = Flask(__name__)7logging.basicConfig(level=logging.INFO)89PUSH_SECRET = os.environ.get('PUSH_SECRET', '')10YT_API_KEY = os.environ['YOUTUBE_API_KEY']11DISCORD_WEBHOOK = os.environ.get('DISCORD_WEBHOOK_URL')12CALLBACK_URL = os.environ['PUSH_CALLBACK_URL']13YT_NS = 'http://www.youtube.com/xml/schemas/2015'14ATOM_NS = 'http://www.w3.org/2005/Atom'1516@app.route('/yt/callback', methods=['GET', 'POST'])17def youtube_callback():18 if request.method == 'GET':19 challenge = request.args.get('hub.challenge')20 if challenge:21 return Response(challenge, status=200, mimetype='text/plain')22 return Response('Bad request', status=400)23 24 if PUSH_SECRET:25 sig = request.headers.get('X-Hub-Signature', '')26 expected = 'sha1=' + hmac.new(PUSH_SECRET.encode(), request.data, hashlib.sha1).hexdigest()27 if not hmac.compare_digest(sig, expected):28 return Response('Forbidden', status=403)29 30 try:31 root = ET.fromstring(request.data.decode())32 entry = root.find(f'{{{ATOM_NS}}}entry')33 if not entry:34 return Response('OK', status=200)35 video_id = entry.find(f'{{{YT_NS}}}videoId').text36 channel_id = entry.find(f'{{{YT_NS}}}channelId').text37 logging.info(f'Upload notification: videoId={video_id} channelId={channel_id}')38 process_upload_notification(video_id, channel_id)39 except Exception as e:40 logging.error(f'Error processing notification: {e}')41 42 return Response('OK', status=200)4344def process_upload_notification(video_id, channel_id):45 r = requests.get('https://www.googleapis.com/youtube/v3/videos',46 params={'part': 'snippet', 'id': video_id, 'key': YT_API_KEY})47 items = r.json().get('items', [])48 if not items:49 return50 snippet = items[0]['snippet']51 title = snippet.get('title', 'Untitled')52 description = snippet.get('description', '')[:200]53 thumbnail = snippet.get('thumbnails', {}).get('high', {}).get('url', '')54 channel_name = snippet.get('channelTitle', channel_id)55 if DISCORD_WEBHOOK:56 requests.post(DISCORD_WEBHOOK, json={'embeds': [{57 'title': title, 'url': f'https://youtu.be/{video_id}',58 'description': description, 'image': {'url': thumbnail}, 'color': 1671168059 }]})60 logging.info(f'Discord alert sent for {title}')6162def subscribe(channel_id):63 requests.post('https://pubsubhubbub.appspot.com/subscribe', data={64 'hub.callback': CALLBACK_URL, 'hub.mode': 'subscribe',65 'hub.topic': f'https://www.youtube.com/xml/feeds/videos.xml?channel_id={channel_id}',66 'hub.verify': 'async', 'hub.lease_seconds': '864000',67 **({'hub.secret': PUSH_SECRET} if PUSH_SECRET else {})68 })6970if __name__ == '__main__':71 CHANNELS = os.environ.get('YOUTUBE_CHANNEL_IDS', '').split(',')72 for ch in CHANNELS:73 if ch.strip():74 subscribe(ch.strip())75 app.run(port=int(os.environ.get('PORT', 3000)))Error handling
Subscription verification failed / hub rejected the subscriptionYour callback did not return 200 with the exact hub.challenge value during verification. The hub sends a GET immediately after your subscribe POST — if your server is down or returns wrong content, the subscription is rejected.
Ensure your callback server is running and publicly accessible before subscribing. Test it manually: GET /yt/callback?hub.mode=subscribe&hub.challenge=TEST should return 200 with body 'TEST'.
Fix the callback and re-POST the subscription request. There is no grace period — the subscription simply does not activate.
Notifications stopped arriving (silent subscription expiry)PuSH subscriptions expire after ~10 days. There is no expiry notification — they just silently stop.
Implement subscription renewal: store the expiry timestamp when subscribing and run a daily job that re-subscribes any subscriptions within 48 hours of expiry.
Re-POST the subscription request. Treat all subscriptions as expired if you haven't renewed in 10+ days.
YouTube Data API: quotaExceededThe 10,000 daily quota units for videos.list enrichment have been exhausted. Each notification triggers one videos.list call (1 unit). This only happens if you're monitoring many high-volume channels.
Reduce channels monitored, or request a quota increase via Google's API Compliance Audit. For 100+ channels, consider processing notifications in batches using videos.list with multiple IDs per call.
Queue notifications and process them after midnight Pacific Time when quota resets.
Invalid signature on push notificationThe HMAC-SHA1 signature in X-Hub-Signature does not match the expected value. Either the hub.secret is wrong or you are parsing the request body before reading it for signature validation (parsed body != raw bytes).
Use raw body middleware (express.raw() in Node.js, request.data in Flask) before validating HMAC. Never parse the body as JSON before signature validation.
Return 403 to the hub. The hub will retry delivery — fix the signature validation and allow retries to succeed.
Rate Limits for YouTube PuSH + Data API
| Scope | Limit | Window |
|---|---|---|
| PuSH notifications | No quota cost | Zero YouTube Data API quota units consumed |
| videos.list enrichment | 1 quota unit per call | From 10,000 units/day project quota; resets midnight Pacific Time |
| Subscribe requests to hub | No documented limit | Re-subscribe periodically (~every 9 days) per channel |
1import time2import requests34def videos_list_with_retry(video_id, api_key, max_retries=3):5 for attempt in range(max_retries):6 r = requests.get('https://www.googleapis.com/youtube/v3/videos',7 params={'part': 'snippet', 'id': video_id, 'key': api_key})8 if r.status_code == 200:9 return r.json()10 if r.status_code == 403 and 'quotaExceeded' in r.text:11 raise Exception('Daily quota exhausted')12 if attempt < max_retries - 1:13 time.sleep(2 ** attempt)14 return None- Monitor 100 channels at 5 uploads/day each = 500 quota units/day — well within the free 10,000 limit
- For high-volume monitoring (1,000+ channels), batch multiple video IDs in a single videos.list call (max 50 IDs)
- Use hub.secret for all subscriptions to validate notification authenticity and avoid processing spoofed requests
- Set hub.lease_seconds to 864000 (10 days) even though the hub may override it — this is the maximum value Google reliably honors
- Implement a deduplication check using videoId+publishedAt before sending alerts — PuSH fires on both uploads AND title/description edits
Security checklist
- Always set hub.secret and validate HMAC-SHA1 signatures on all incoming POST notifications
- Use express.raw() or equivalent to preserve raw request body for HMAC validation — parsed bodies break signature verification
- Store API keys and webhook secrets in environment variables, never hardcoded
- Your callback URL must use HTTPS — HTTP callbacks are rejected by the PuSH hub
- Implement request deduplication to prevent processing the same videoId twice if the hub retries delivery
- Return 2xx responses quickly from your callback (under 5 seconds) — long-running processing should be async
- Log all incoming notifications with timestamps for debugging subscription issues and missed alerts
Automation use cases
Cross-Post New Videos to Discord Community
intermediateWhen a channel uploads a video, automatically post a formatted embed to a Discord server with thumbnail, description, and direct YouTube link.
Multi-Channel Upload Aggregator
intermediateSubscribe to 50+ YouTube channels in your niche and aggregate all uploads into a single Slack channel for easy monitoring.
Content Calendar Sync
beginnerWhen a new video is uploaded, automatically log it to a Google Sheet or Notion database with title, URL, and publish time for content tracking.
Competitor Upload Monitor
advancedSubscribe to competitor channels and receive immediate Slack alerts when they publish new content, triggering a competitive analysis workflow.
No-code alternatives
Don't want to write code? These platforms can automate the same workflows visually.
Zapier
Free tier (100 tasks/month); paid from $20/monthZapier has a native YouTube trigger 'New Video in Channel' that polls for uploads every 15 minutes (not real-time) and connects to Discord, Slack, Gmail, and 7,000+ other apps.
- + No code required
- + Connects to all major platforms
- + Simple visual setup
- - 15-minute polling delay (not instant like PuSH)
- - Costs $20+/month for multi-step Zaps
- - Limited to YouTube channels you can monitor
Make (formerly Integromat)
Free tier (1,000 operations/month); paid from $9/monthMake's YouTube 'Watch Videos' trigger polls for new uploads and can trigger cross-posting workflows to multiple platforms with better data transformation than Zapier.
- + More flexible than Zapier
- + Lower cost for complex flows
- + Visual scenario builder
- - Polling-based (5-15 min delay), not webhook real-time
- - Learning curve for complex scenarios
n8n
Free self-hosted; Cloud from $20/monthn8n's YouTube trigger node can monitor channels for new uploads and trigger multi-step workflows including Discord, Slack, and custom HTTP requests — supports self-hosting for zero cost.
- + Self-hosted = free
- + Supports multiple output channels in one workflow
- + Highly customizable
- - Polling-based in most configurations
- - Requires self-hosting setup
- - Less YouTube-specific features
Best practices
- Use PuSH instead of polling videos.list for new uploads — it costs zero quota and is near-real-time
- Implement HMAC-SHA1 signature validation using hub.secret — it is the only way to verify notifications are genuine
- Schedule subscription renewals at 9-day intervals to stay ahead of the ~10-day expiry
- Parse yt:videoId from the Atom payload and call videos.list separately — the Atom payload has minimal metadata
- Handle both new uploads and title/description edits gracefully — the PuSH hub sends both
- Return HTTP 200 from your callback within 5 seconds — defer heavy processing to an async queue
- Test your callback server locally with ngrok before deploying to catch verification failures early
Ask AI to help
Copy one of these prompts to get a personalized, working implementation.
I'm building a YouTube PubSubHubbub notification server in Python (Flask) to cross-post new video uploads to Discord. My callback is receiving the verification GET but the hub.challenge echo is failing. Here is my current Flask route: [paste code]. The hub returns 422 when I try to subscribe. How should I correctly handle both GET verification and POST notification routing in the same endpoint?
Build a YouTube Upload Monitor dashboard using PubSubHubbub webhooks. The dashboard should show a list of subscribed YouTube channels, allow adding new channel IDs to monitor, display a real-time log of upload notifications received with video title, thumbnail, and timestamp, and have a Discord/Slack alert toggle per channel. Use Supabase to persist subscriptions and notification history, and implement the PuSH callback server as a Supabase Edge Function.
Frequently asked questions
Is YouTube PubSubHubbub free?
Yes. PuSH subscriptions and notifications are completely free and do not consume any YouTube Data API quota units. The only quota cost is if you use videos.list to enrich notifications with metadata (1 unit per call), which is within the free 10,000 units/day limit.
How real-time are PuSH notifications?
Very fast — typically within seconds to a few minutes of a channel uploading. This is far faster than polling videos.list on a schedule. However, YouTube does not guarantee a maximum delivery time, and occasional delays of 5-10 minutes have been reported in practice.
Does PuSH notify me when a video is deleted?
No. PuSH only fires on uploads and title/description changes. Deletions, view count changes, comment activity, and live stream state changes do not trigger PuSH notifications. For these events, you must poll the relevant YouTube Data API endpoints.
What happens when I hit the rate limit?
PuSH itself has no rate limit — it is push-based and the hub controls delivery. If you hit the YouTube Data API 403 quotaExceeded error on videos.list enrichment, queue unprocessed notifications and retry after midnight Pacific Time when quota resets.
How do I monitor private videos?
PuSH does not support private video notifications — it only works for public channel uploads. To monitor your own channel's uploads including private videos, poll videos.list with OAuth 2.0 authentication and the youtube.readonly scope.
Can I subscribe to multiple channels at once?
Yes, but you must POST a separate subscription request to the hub for each channel_id. There is no batch subscription endpoint. Store each subscription's expiry time and renew them individually on a schedule.
Can RapidDev help build a cross-channel YouTube alert system?
Yes — RapidDev has built 600+ integrations including YouTube monitoring pipelines that cross-post to Discord, Slack, Telegram, and email. We can build a complete multi-channel monitoring dashboard with subscription management and alert routing. Book a free consultation at rapidevelopers.com.
What is the difference between PuSH and polling videos.list?
PuSH is push-based (YouTube notifies you within seconds), costs zero quota units, and requires a public HTTPS callback URL. Polling videos.list costs 1 quota unit per call and has up to 15-minute delays depending on your polling interval. Use PuSH for real-time alerts; use polling only if you cannot expose a public URL.
Need this automated?
Our team has built 600+ apps with API automations. We can build this for you.
Book a free consultation