# My Playlist — Video Library Full API Reference TikTok, X, and YouTube are trademarks of their respective owners. My Playlist is an independent tool and is not affiliated with, endorsed by, or sponsored by any platform referenced here. Base URL: https://my-playlist.app ## Authentication Two methods: 1. **Anonymous**: No auth header. Limited to 2 downloads/day, 720p, 25MB. 2. **Bearer token**: `Authorization: Bearer `, issued when signing in on the site (email/password or Google). No separate CLI is available for this site. Plans: - Free (anonymous or registered): 2 downloads/day, 720p, 25MB, 24h file retention, 1GB/month library storage. - Pro ($9.98/mo): 10 downloads/day, best available quality, custom filenames/formats, 20GB/month library storage. - Pro+ ($19.98/mo): 50 downloads/day, best available quality, custom filenames/formats, 100GB/month library storage. - Lifetime ($398 one-time): unlimited downloads, best available quality, custom filenames/formats, unlimited library storage. Saving a video to your library (`POST /api/library`) copies it to permanent storage and counts against the monthly storage quota. Downloads that are not saved to the library are deleted after 24h regardless of plan. ## Endpoints ### POST /api/download Create a download task. Request body (JSON): - `url` (string, required): Any public video URL we can process (TikTok, X, YouTube, and many more — not limited to a single platform) - `filename` (string, optional): Custom output filename (paid plans only) - `format` (string, optional): Custom yt-dlp format (paid plans only) Response 200: ```json { "ok": true, "cached": false, "message": "download queued", "download": { "id": "uuid" }, "video": { "id": "uuid", "status": "queued", "requestId": "uuid" }, "remaining": 1 } ``` Response 429 (rate limited): ```json { "ok": false, "error": "RATE_LIMIT", "plan": "free", "limit": 2, "remaining": 0 } ``` Response 400: ```json { "ok": false, "error": "EMPTY_URL" | "INVALID_URL_FORMAT" } ``` ### GET /api/downloads/{id} Get download task details. Response 200: ```json { "ok": true, "task": { "id": "uuid", "url": "https://www.tiktok.com/@user/video/7520123456789012345", "filename": "video.mp4", "status": "queued" | "running" | "done" | "failed", "created_at": "2026-01-01T00:00:00Z", "finished_at": "2026-01-01T00:01:00Z", "error": null, "error_code": null, "file_size": 12345678, "duration": 120.5, "width": 1920, "height": 1080, "stage": "downloading" | "uploading" | null, "playlist_index": 0, "playlist_total": 1 } } ``` Status flow: `queued` → `running` → `done` | `failed` ### GET /api/file/{id}?dl=1 Get the video file. Returns 302 redirect to the file URL. Response 302: Redirects to R2 signed URL. Response 410: `{"ok": false, "error": "expired"}` — file retention period ended. Response 409: `{"ok": false, "error": "not_ready"}` — still processing. ### GET /api/downloads List user's downloads (requires auth). Query params: - `limit` (number, optional, default 50, max 200) Response 200: ```json { "ok": true, "items": [ { "id": "uuid", "url": "https://www.tiktok.com/@user/video/7520123456789012345", "status": "done", "created_at": "2026-01-01T00:00:00Z" } ] } ``` ### DELETE /api/downloads/{id} Delete a download record. Cannot delete running tasks. Response 200: `{"ok": true, "message": "deleted"}` Response 409: `{"ok": false, "error": "cannot delete running task"}` ### GET /api/user/usage Get today's usage (requires auth). Response 200: ```json { "ok": true, "used": 1, "limit": 2, "remaining": 1, "plan": "free" } ``` For the Lifetime plan, `limit` and `remaining` are -1 (unlimited). Pro and Pro+ have finite daily limits (10 and 50 respectively). ### GET /api/user/subscription Get subscription info. Response 200: ```json { "ok": true, "plan": "free" | "svip", "tier": "free" | "pro" | "pro_plus" | "lifetime", "subscription": { "status": "active", "cancelAtPeriodEnd": false, "currentPeriodEnd": 1735689600 } } ``` `plan` is a legacy free/svip field kept for backward compatibility (`svip` means "any paid plan"). Use `tier` for the actual plan. ## Typical AI Agent Workflow 1. `POST /api/download` with the video URL 2. Poll `GET /api/downloads/{id}` every 5 seconds until `status === "done"` 3. `GET /api/file/{id}?dl=1` to get the download URL (302 redirect) 4. Download the file from the redirect URL ## Error Codes - `EMPTY_URL`: No URL provided - `INVALID_URL_FORMAT`: URL doesn't start with http(s) - `RATE_LIMIT`: Daily download limit reached - `FILE_SIZE_LIMIT`: Video exceeds the plan's file size limit ## MCP Server No MCP server is available for this site yet. Call the REST API above directly, using a bearer token or session cookie obtained by signing in on the website.