You can rotate a YouTube playlist on a recurring schedule with GitHub Actions and the YouTube Data API: store the desired video IDs in your repository, run a scheduled workflow, compare that list with the playlist’s current items, then insert, remove, or reposition entries as needed. Playlist changes require OAuth authorization—not an API key alone—and scheduled runs are best-effort, so make the workflow safe to rerun and provide a manual recovery path.
What the workflow does
A reliable rotation has three parts: a configuration describing the target playlist and desired order, a GitHub Actions workflow that runs on a schedule, and an OAuth-authorized script that reconciles the YouTube playlist with that configuration. The YouTube API represents each playlist entry as a playlistItem. Its item ID is different from the video ID inside it—a distinction that matters when deleting entries. See Google’s playlist item resource.
As an Amazon Associate I earn from qualifying purchases.
Keep the configuration in the repository, for example a playlist ID, an ordered array of video IDs, and a policy for how many entries to retain. The exact rotation policy is yours to define: a fixed ordered set, a rolling window, or another rule. The API provides the operations; it does not prescribe the rotation algorithm.
Free tools Windows power users keep installed
One-click scans. No signup required.
Choose a schedule that matches your rotation
GitHub Actions schedules use POSIX cron. The shortest documented interval is five minutes, but that is a syntax limit, not a guarantee that a run starts exactly on time. Scheduled workflows run against the default branch’s latest commit, so changes to the workflow or its configuration must be merged there to affect scheduled runs. See GitHub’s schedule event documentation and workflow syntax reference.
#1 Best Overall
- Includes Raspberry Pi 5 with 2.4Ghz 64-bit quad-core CPU (8GB RAM)
- Includes 128GB Micro SD Card pre-loaded with 64-bit Raspberry Pi OS, USB MicroSD Card Reader
- CanaKit Turbine Black Case for the Raspberry Pi 5
- CanaKit Low Noise Bearing System Fan
- Mega Heat Sink - Black Anodized
UTC or local wall-clock time
- UTC: Leave the timezone unspecified and write the cron expression in UTC when you want a stable machine-oriented time.
- Named timezone: Set an IANA timezone when the schedule should follow local wall-clock time. During a spring-forward skipped hour, GitHub advances the run to the next valid time.
Run at a less busy minute
Choose a minute other than the top of the hour when practical. GitHub warns that scheduled events can be delayed during high load, particularly around the start of an hour, and queued scheduled jobs may be dropped. Public repositories’ scheduled workflows are automatically disabled after 60 days without repository activity. Treat a schedule as a trigger, not a precision timer; expose a clear run result and keep a manual dispatch option for recovery. See GitHub’s scheduling guidance.
Set up OAuth credentials safely
Playlist writes require OAuth authorization with a supported YouTube scope. The API references for insert and delete list scopes including https://www.googleapis.com/auth/youtube and https://www.googleapis.com/auth/youtube.force-ssl. The YouTube API authentication overview explains that write requests must carry an authorization token. An API key by itself is not sufficient to change a playlist.
Rank #2
- Includes Raspberry Pi 4 4GB Model B with 1.5GHz 64-bit quad-core CPU (4GB RAM)
- Includes Pre-Loaded 32GB EVO+ Micro SD Card (Class 10), USB MicroSD Card Reader
- CanaKit Premium High-Gloss Raspberry Pi 4 Case with Integrated Fan Mount, CanaKit Low Noise Bearing System Fan
- CanaKit 3.5A USB-C Raspberry Pi 4 Power Supply (US Plug) with Noise Filter, Set of Heat Sinks, Display Cable - 6 foot (Supports up to 4K60p)
- CanaKit USB-C PiSwitch (On/Off Power Switch for Raspberry Pi 4)
Create an OAuth client and a refresh-token strategy for the channel owner using Google’s developer tools. The setup and maintenance of unattended credentials depend on that OAuth configuration; do not assume a refresh token is available without creating and testing the appropriate flow.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
Store credentials as Actions secrets
- Store OAuth credentials in GitHub Actions secrets, not in the workflow file or repository.
- Map a secret into only the step that needs it, and do not print credentials or derived tokens in logs.
- Use the narrowest practical access. GitHub recommends least privilege and a read-only default for
GITHUB_TOKENwhere feasible; that repository token is separate from the OAuth credential used for YouTube. - For a higher-risk workflow, consider an environment secret with required reviewer approval rather than a broadly available repository secret.
GitHub’s guidance covers using secrets in Actions and security hardening. Secret masking is not a substitute for preventing credentials from entering logs.
Reconcile the playlist instead of blindly replacing it
First list the current playlist entries and retain both identifiers for each one: id is the playlist-item ID, while snippet.resourceId.videoId is the underlying video ID. Compare those entries with the desired ordered video IDs from your configuration.
- Read current state: Call
playlistItems.listfor the target playlist and collect the playlist-item ID and video ID for each entry. - Compute the difference: Determine which desired videos are missing, which current entries are no longer wanted, and whether the remaining order differs from the configured order.
- Insert missing entries: Call
playlistItems.insertwithsnippet.playlistIdandsnippet.resourceIdset appropriately. Google describes the method as adding a resource to a playlist. - Delete unwanted entries: Call
playlistItems.deleteusing the playlist-itemid, not the underlying video ID. - Set order if needed: Use
playlistItems.updatewhen the position of an entry must change. - Verify and report: Re-read the playlist after destructive changes, then print a concise summary of additions, removals, ordering changes, and errors.
See the API references for list, insert, delete, and update. Make the operation idempotent: running it twice with unchanged configuration should converge on the same playlist, not create duplicates or delete entries based on stale assumptions. Re-list or otherwise confirm state before destructive changes.
Rank #4
- Broadcom BCM2711, quad-core Cortex-A72 (ARM v8) 64-bit SoC @ 1. 5GHz
- 2. 4 GHz and 5. 0 GHz IEEE 802. 11b/g/n/ac wireless LAN, Bluetooth 5. 0, BLE
- 2 × USB 3. 0 ports, 2 x USB 2. 0 Ports
- 2 × micro HDMI ports supproting up to 4Kp60 video resolution
- Micro SD card slot for loading operating system and data storage
Build the scheduled workflow
Place a YAML workflow in .github/workflows/. This example shows the schedule and manual trigger shape; replace the script path, secret names, and cron time to match your project. It assumes your script handles OAuth and performs the list-and-reconcile steps above.
name: Rotate YouTube playlist
on:
schedule:
- cron: '17 6 * * *'
workflow_dispatch:
permissions:
contents: read
jobs:
rotate:
runs-on: ubuntu-latest
steps:
- name: Check out default-branch workflow revision
uses: actions/checkout@v4
- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: '22'
- name: Install dependencies
run: npm ci
- name: Reconcile playlist
run: node scripts/rotate-playlist.js
env:
YOUTUBE_CLIENT_ID: ${{ secrets.YOUTUBE_CLIENT_ID }}
YOUTUBE_CLIENT_SECRET: ${{ secrets.YOUTUBE_CLIENT_SECRET }}
YOUTUBE_REFRESH_TOKEN: ${{ secrets.YOUTUBE_REFRESH_TOKEN }}
YOUTUBE_PLAYLIST_ID: ${{ secrets.YOUTUBE_PLAYLIST_ID }}
The cron value above is an example of a daily UTC schedule at 06:17, selected away from the top of the hour; it is not a delivery-time guarantee. Add or change workflow configuration on the default branch. Use a manual run to test after configuration changes, and make sure the script reports failures with a nonzero exit status so a failed API operation is visible in the Actions run.
Best Value
- Includes Raspberry Pi 5 16GB with 2.4Ghz 64-bit quad-core CPU (16GB RAM)
- Includes 128GB Micro SD Card pre-loaded with 64-bit Raspberry Pi OS, USB MicroSD Card Reader
- CanaKit Turbine Black Case for the Raspberry Pi 5
- CanaKit Low Noise Bearing System Fan
- Mega Heat Sink - Black Anodized
Account for quota and API edge cases
Google documents these quota impacts in the YouTube Data API method references; the pages do not state a publication year. Check your project’s current quota allocation and usage in Google’s project console rather than assuming an unlimited allowance.
| Operation | Documented quota cost per call | Why it matters |
|---|---|---|
playlistItems.list |
1 unit | Read-and-compare uses inexpensive reads to avoid unnecessary writes. |
playlistItems.insert |
50 units | Insert only entries that are genuinely missing. |
playlistItems.delete |
50 units | Delete only confirmed unwanted playlist-item IDs. |
Sources: Google’s list, insert, and delete references.
API requests can fail if the credential is unauthorized, a video cannot be added, the playlist has reached its maximum item count, an item is already present, or the playlist does not support the requested operation. Some special or system playlists may not support ordinary modifications. Handle API errors per item where appropriate, preserve a useful error summary, and avoid continuing destructive changes after an unexpected read or authorization failure.
Quick wins for a faster PC:
Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →Clear out junk files and repair common Windows errorsFree Scan →Troubleshoot missed or incorrect rotations
- No scheduled run appears: Check that the workflow is on the default branch, the cron expression is valid, and a public repository has had activity within the past 60 days. Use
workflow_dispatchto run it manually. - The run starts late or not at all: GitHub schedules are best-effort and can be delayed or dropped under load. Avoid top-of-hour schedules and use the run history plus a manual recovery run rather than assuming minute-level delivery.
- OAuth returns an authorization error: Confirm that the credential belongs to the channel owner, the requested OAuth scope permits the operation, and the refresh-token setup is valid. An API key cannot authorize playlist writes.
- Deletion fails or targets the wrong entry: Confirm the request uses the playlist-item
id, notsnippet.resourceId.videoId. Re-list before retrying destructive work. - Insertion is rejected: Check that the playlist is writable, the video is accessible and eligible, the item is not already present, and the playlist has not hit its item limit.
- The playlist order is wrong: Check whether the script applies positions through
playlistItems.update; inserting and deleting alone may not produce the intended final order. - Actions logs expose sensitive material: Remove any token-printing or debug output, rotate exposed credentials, and scope secret access to the step that needs it.
When scheduled playlist edits are not the goal
GitHub Actions automates edits to a playlist; it does not itself keep a live broadcast running. If your actual goal is a 24/7 YouTube stream of uploaded recordings, StreamNeo is a separate cloud option: upload videos, add your YouTube stream key, and go live. It loops uploaded videos from the cloud, so your computer and home connection do not need to stay on.
Or let it run in the cloud
StreamNeo is for YouTube streams from uploaded videos, not camera broadcasts. It keeps the stream running with your computer off, streams your uploaded file as made up to 4K 60fps at one flat price per slot, and automatically recovers if YouTube drops the stream. The first day is free with no card. Monthly pricing is $9.99 per month. See StreamNeo, or start the free first day.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.




