ytdlp.org

Practical yt-dlp docs: install, commands, fixes, cookies, and workflows.

Current section

Workflow guide

How to automate yt-dlp: cron, n8n, Zapier, and beyond

Once a download job repeats on a schedule — a channel every night, a playlist every week — running it by hand stops making sense. This guide covers the automation ladder from a cron line to no-code platforms, including the step most tutorials skip: which platforms can't run yt-dlp at all.

Quick answer: a safe cron job

0 3 * * * flock -n /tmp/ytdlp.lock yt-dlp -a /home/me/urls.txt \
  --download-archive /home/me/archive.txt \
  -o "/media/%(uploader)s/%(title)s.%(ext)s" \
  >> /var/log/yt-dlp-cron.log 2>&1
  • flock -n stops overlapping runs when last night's job is still going
  • --download-archive makes reruns skip what you already have
  • • logging to a file is your only visibility — cron fails silently otherwise

Watching channels and playlists on a schedule

Point the cron job at a channel or playlist URL instead of individual videos, and the archive file turns it into a "grab whatever is new" poller:

yt-dlp "https://www.youtube.com/@channel/videos" \
  --download-archive archive.txt \
  --playlist-end 10 \
  --dateafter now-7days

--playlist-end 10 keeps the nightly check cheap instead of re-scanning a 2,000-video back catalog, and --dateafter bounds it by upload date.

n8n and other self-hosted automation tools

Self-hosted n8n can run yt-dlp with the Execute Command node, because the workflow runs on your machine where the binary lives. Install yt-dlp in the n8n container (or mount it in), then wire Schedule Trigger → Execute Command → error branch to Slack/email. The same logic applies to Node-RED, Huginn, or a plain systemd timer: self-hosted runner, full power.

The gotchas are the server ones, not the n8n ones: the container needs ffmpeg, an updated yt-dlp, disk space, and a tolerable IP — see running yt-dlp on a server.

Why Zapier and Make can't run yt-dlp

Zapier, Make, and cloud-hosted n8n execute steps on theirservers, and they don't let you run arbitrary binaries. There is no "yt-dlp step" and there can't be one. Your two options from a no-code platform:

  • Bridge to your own machine: have the Zap call a webhook on a server you run, which executes yt-dlp — now you're maintaining a server anyway
  • Call a media-import API: an HTTP step to a service like Importly (which has native Zapier, Make, and n8n integrations) — URL in, file to S3 or webhook out, no server to babysit

Make failures loud

Every scheduled yt-dlp setup eventually breaks — extractor changes, expired cookies, full disk, blocked IP. The difference between a hobby setup and a reliable one is whether you find out from an alert or from noticing weeks of missing files:

yt-dlp -a urls.txt --download-archive archive.txt \
  || curl -s -X POST "$SLACK_WEBHOOK" -d '{"text":"yt-dlp nightly failed"}'

Common automation mistakes

  • • no archive file — every run redownloads everything
  • • no lock — overlapping runs corrupt each other's partial files
  • • no failure alerting — silence is indistinguishable from success
  • • hammering a source every 5 minutes and getting the IP rate-limited
  • • expecting Zapier/Make to execute a binary they will never execute

Automation

Running this on a schedule? See the API version.

Paste a link and watch one API call do what your batch script does — extraction, retries, and site breakage handled.

Straightforward yt-dlp help for installs, commands, fixes, cookies, and repeatable workflows.

ytdlp.org is an independent, community-maintained documentation site. It is not affiliated with the yt-dlp project — the official source code lives at github.com/yt-dlp/yt-dlp.