Vortex

Back

API v1

REST API for YouTube, TikTok and Twitter / X media downloads.

Base URL

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.

GET /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"
}
POST /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:

Response (200):

{ "task_id": "a1b2c3...", "cached": false }

Errors:

GET /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
}
GET /api/v1/file/<task_id>

Streams the finished file as an attachment. Returns 404 until status is finished.

Python example

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)