Automatically sync your Instagram Reels to YouTube Shorts. Fork the repo, add your credentials, and let GitHub Actions handle the rest -effortlessly.
Pulls latest reels from any public Instagram profile with smart filtering.
Pushes videos to YouTube as Shorts with captions, tags, and metadata.
Runs every 6 hours on GitHub Actions. Zero maintenance after setup.
Clone, configure, deploy. Built for the simplest possible onboarding.
Fork the repo, configure your credentials, and sync automatically.
Click the Fork button on GitHub to create your own copy of instoob.
Set your Instagram username and adjust YouTube upload preferences.
Create a Google Cloud project, enable YouTube Data API v3, and get OAuth credentials.
Run python setup_youtube.py locally to authorize your YouTube channel.
Add your YouTube and Instagram credentials as repository secrets.
Go to the Actions tab and enable workflows. Trigger manually or wait for the schedule.
One-time setup to connect your YouTube channel.
Go to Google Cloud Console, create a new project (e.g., "Instoob"), then navigate to APIs & Services > Library. Search for "YouTube Data API v3" and enable it.
In APIs & Services > Credentials, click Create Credentials > OAuth client ID. Configure the consent screen as External, add your email as a test user. Choose "Desktop app" type, then download the JSON file as client_secrets.json.
Place client_secrets.json in the project root and run the setup script.
pip install -r requirements.txt
python setup_youtube.py
The script opens a browser for consent, then prints your YOUTUBE_CLIENT_ID, YOUTUBE_CLIENT_SECRET, and YOUTUBE_REFRESH_TOKEN. Save these as GitHub Secrets.
No password needed. Just one cookie from your browser.
No password needed. Just grab your sessionid cookie from the browser. Works with any account, including 2FA.
# 1. Open instagram.com in your browser
# 2. DevTools (F12) > Application > Cookies
# 3. Copy the 'sessionid' value
Add the value as IG_SESSION_ID in GitHub Secrets. That's it.
Edit config.yml to control what gets synced and how.
instagram:
username: "your_username"
max_reels_per_run: 3
max_duration: 0
# since_date: "2025-01-01"
youtube:
category_id: "22"
privacy_status: "public"
default_language: "en"
title_prefix: ""
title_suffix: ""
description_suffix: "\n\n#Shorts"
made_for_kids: false
sync:
data_dir: "data"
download_dir: "downloads"
Add these in your fork under Settings > Secrets and variables > Actions.
| Secret | Required | Description |
|---|---|---|
YOUTUBE_CLIENT_ID |
Yes | Google OAuth client ID from setup script |
YOUTUBE_CLIENT_SECRET |
Yes | Google OAuth client secret from setup script |
YOUTUBE_REFRESH_TOKEN |
Yes | YouTube refresh token from setup script |
IG_SESSION_ID |
Yes | Instagram sessionid cookie from your browser |
sessionid cookie from your browser's DevTools.
Perfect for testing or one-off syncs.
# Clone and install
git clone https://github.com/YOUR_USER/instoob.git
cd instoob
pip install -r requirements.txt
# Configure
cp config.example.yml config.yml
cp .env.example .env
# Edit config.yml and .env with your details
# Run sync
python main.py sync
# Verbose output
python main.py sync --verbose
The GitHub Actions workflow runs every 6 hours by default. Customize the cron schedule in the workflow file.
schedule:
- cron: "0 */6 * * *" # Every 6 hours
# "0 */12 * * *" Every 12 hours
# "0 9 * * *" Daily at 9 AM UTC
# "0 9 * * 1" Weekly on Monday
max_reels_per_run: 3 and 4 runs/day, you may approach the limit. Adjust as needed.
IG_SESSION_ID secret. Session cookies expire after a few months. To refresh, open Instagram in your browser, go to DevTools (F12) > Application > Cookies, copy the new sessionid value, and update the GitHub Secret.
python setup_youtube.py again to get a new token, or publish your Google Cloud app to get permanent tokens.
max_reels_per_run in config.yml or change the cron schedule to run less frequently.
config.yml is correct and the profile has public video posts. If using since_date, ensure the date isn't set in the future.
data/synced.json is being committed back to your repo. The GitHub Actions workflow handles this automatically. If running locally, the state file is saved after each run.