Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/coah80/yoink/llms.txt

Use this file to discover all available pages before exploring further.

Playlist downloads run entirely in the background. You start a job with POST /api/playlist/start, receive a jobId, and then poll GET /api/playlist/status/{jobId} until status is complete. At that point a downloadToken is available that you can use to fetch the finished ZIP archive from GET /api/playlist/download/{token}. Individual video failures within a playlist do not abort the entire job. Failed videos are tracked in the failedVideos array in the status response — the job completes as long as at least one video was downloaded successfully.
Playlist download tokens expire after 12 hours (PlaylistDownloadExp). Download the ZIP before then. The server enforces a maximum of 1000 videos per playlist run (MaxPlaylistVideos); use resumeFrom to process large playlists in batches.

POST /api/playlist/start

Validates the playlist URL, enqueues the download job, and returns a jobId immediately. The actual download begins asynchronously.
POST /api/playlist/start
Content-Type: application/json

Body Fields

url
string
required
URL of the playlist (YouTube, SoundCloud, etc.). Must be fully-qualified (http:// or https://).
format
string
default:"video"
Output mode. video downloads the video stream; audio extracts audio only.
quality
string
default:"1080p"
Target video resolution. One of 2160p, 1440p, 1080p, 720p, 480p, 360p. Ignored when format=audio.
container
string
default:"mp4"
Video container format. One of mp4, webm, mkv, mov. Ignored when format=audio.
audioFormat
string
default:"mp3"
Audio codec/container when format=audio. One of mp3, m4a, opus, wav, flac.
audioBitrate
string
default:"320"
Audio bitrate in kbps. One of 64, 96, 128, 192, 256, 320.
clientId
string
Session identifier for per-client job limiting (max 3 concurrent per client).
resumeFrom
integer
default:"1"
1-based index of the playlist video to start from. Use this to process large playlists in chunks — e.g. set resumeFrom=51 to process videos 51–1050 in the next run. Must not exceed the total number of videos in the playlist.

Response

{ "jobId": "550e8400-e29b-41d4-a716-446655440000" }

Errors

StatusMeaning
400Invalid URL or body
429Too many concurrent jobs for this client
503Server is at playlist job capacity

GET /api/playlist/status/

Returns the current state of a playlist download job.
GET /api/playlist/status/{jobId}

Response Fields

status
string
Current job state. One of:
  • starting — fetching playlist info
  • downloading — actively downloading videos
  • zipping — assembling the ZIP archive
  • complete — ZIP is ready to download
  • error — job failed
message
string
Human-readable status message describing current activity.
progress
number
Overall completion percentage, 0–100.
playlistTitle
string
Title of the playlist as reported by yt-dlp.
totalVideos
number
Total number of videos in the playlist (may differ from the number attempted if resumeFrom was set).
startVideo
number
1-based index of the first video that was (or will be) downloaded in this run. Reflects the resumeFrom value.
currentVideo
number
1-based index of the video currently being downloaded.
currentVideoTitle
string
Title of the video currently being downloaded.
videosCompleted
number
Number of videos successfully downloaded so far.
failedVideos
array
Array of objects describing videos that failed to download. Each object contains:
  • num (number) — 1-based index in the playlist
  • title (string) — video title
  • reason (string) — user-friendly error description
failedCount
number
Total number of failed videos.
downloadToken
string
Present only when status is complete. Pass this to GET /api/playlist/download/{token}.
fileName
string
Present only when status is complete. The ZIP filename (e.g. My Playlist.zip).
fileSize
number
Present only when status is complete. ZIP file size in bytes.
speed
string
Current download speed (e.g. "5.2MiB/s"). Present during active video downloads.
eta
string
Estimated time remaining for the current video (e.g. "00:01:23"). Present during active video downloads.

curl Example

curl https://yoink.example.com/api/playlist/status/550e8400-e29b-41d4-a716-446655440000

GET /api/playlist/download/

Streams the completed ZIP archive. The token is obtained from the downloadToken field in the status response.
GET /api/playlist/download/{token}
Download tokens expire 12 hours after the job completes. After expiry the file is deleted from disk and the token returns 404.

Response

Streams a ZIP archive (application/zip) with Content-Disposition: attachment; filename="<playlist title>.zip". The ZIP contains one file per successfully downloaded video, named 001 - Video Title.mp4 (zero-padded three-digit index).

curl Example

curl -L -o playlist.zip \
  https://yoink.example.com/api/playlist/download/your_token_here

Complete Workflow Example

The following shell script starts a playlist download, polls until complete, and saves the ZIP:
#!/usr/bin/env bash
set -euo pipefail

BASE="https://yoink.example.com"

# 1. Start the job
JOB_ID=$(curl -s -X POST "${BASE}/api/playlist/start" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://www.youtube.com/playlist?list=PLbpi6ZahtOH6Ar_3GPy3workXXXXXXXX",
    "format": "audio",
    "audioFormat": "mp3",
    "audioBitrate": "320"
  }' | jq -r .jobId)

echo "Job started: ${JOB_ID}"

# 2. Poll until complete or error
while true; do
  RESP=$(curl -s "${BASE}/api/playlist/status/${JOB_ID}")
  STATUS=$(echo "$RESP" | jq -r .status)
  MSG=$(echo "$RESP" | jq -r .message)
  PROGRESS=$(echo "$RESP" | jq -r .progress)
  COMPLETED=$(echo "$RESP" | jq -r .videosCompleted)
  TOTAL=$(echo "$RESP" | jq -r .totalVideos)
  FAILED=$(echo "$RESP" | jq -r .failedCount)

  echo "[${STATUS}] ${PROGRESS}% | ${COMPLETED}/${TOTAL} videos | ${FAILED} failed | ${MSG}"

  if [ "$STATUS" = "complete" ]; then
    TOKEN=$(echo "$RESP" | jq -r .downloadToken)
    FILENAME=$(echo "$RESP" | jq -r .fileName)
    echo "Download ready. Token: ${TOKEN}"
    break
  fi

  if [ "$STATUS" = "error" ]; then
    echo "Job failed: ${MSG}"
    exit 1
  fi

  sleep 5
done

# 3. Download the ZIP
curl -L -o "${FILENAME}" "${BASE}/api/playlist/download/${TOKEN}"
echo "Saved: ${FILENAME}"

Build docs developers (and LLMs) love