REST API for YouTube, TikTok and Twitter / X media downloads.
https://vortexdl.online/api/v1
Rate limits: 5 req/min fast + 20 unique downloads / 30 min per IP.
Cached downloads do not count against the slow limit.
/api/v1/info?url=<media_url>
Returns metadata about the link without downloading.
curl "https://vortexdl.online/api/v1/info?url=https://youtu.be/w62uvni7dGo"
Response (200):
{
"service": "youtube",
"title": "Eulenlieder",
"duration": 126,
"uploader": "Release - Topic",
"thumbnail": "https://i.ytimg.com/vi/w62uvni7dGo/maxresdefault.jpg",
"view_count": 136587,
"upload_date": "20230830",
"webpage_url": "https://www.youtube.com/watch?v=w62uvni7dGo"
}
/api/v1/download
Starts a download. Returns a task_id and a flag
indicating whether the file came from cache (instant) or is being downloaded.
curl -X POST https://vortexdl.online/api/v1/download \
-H "Content-Type: application/json" \
-d '{"url": "https://youtu.be/w62uvni7dGo", "format": "mp4"}'
Body parameters:
url - YouTube / TikTok / Twitter URL (required)format - mp4 or mp3 (required)Response (200):
{ "task_id": "a1b2c3...", "cached": false }
Errors:
400 - invalid URL / format / playlist / video >= 3h429 - rate limit exceeded/api/v1/status/<task_id>
Returns the current status of the task. Poll every ~0.7 s.
{
"status": "downloading", // queued | downloading | processing | finished | error
"progress": 42.5,
"speed": 8388608, // bytes per second
"eta": 15, // seconds
"title": "...", // when finished
"filename": "...", // when finished
"service": "youtube",
"from_cache": false,
"error": "..." // when status == error
}
/api/v1/file/<task_id>
Streams the finished file as an attachment. Returns 404 until status is finished.
import requests, time
BASE = "https://vortexdl.online/api/v1"
r = requests.post(BASE + "/download",
json={"url": "https://youtu.be/w62uvni7dGo", "format": "mp4"})
task = r.json()["task_id"]
while True:
s = requests.get(f"{BASE}/status/{task}").json()
if s["status"] == "finished":
break
if s["status"] == "error":
raise SystemExit(s["error"])
time.sleep(1)
with requests.get(f"{BASE}/file/{task}", stream=True) as resp:
with open("output.mp4", "wb") as f:
for chunk in resp.iter_content(1024 * 1024):
f.write(chunk)