voiddl API
Extract metadata and download media from 10+ platforms with two simple endpoints. No polling, no callbacks — one request gets you the data, another streams the file.
The API is hosted at https://voiddl.app. All requests require a Bearer token. Tokens start with vd_ and are issued from your dashboard.
Authentication
Pass your API key in the Authorization header on every request.
Authorization: Bearer vd_xxxxxxxxxxxxxxxxxxxx
Quickstart
Two steps to download any video: extract to get the format ID, then proxy to stream the bytes.
# Step 1 — extract metadata + best format
curl -X POST https://voiddl.app/api/extract \
-H "Authorization: Bearer vd_xxxxxxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{"url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ"}'
# Step 2 — download using format_id from step 1
curl -L -o video.mp4 \
-H "Authorization: Bearer vd_xxxxxxxxxxxxxxxxxxxx" \
"https://voiddl.app/api/proxy?url=https%3A%2F%2Fyoutu.be%2FdQw4w9WgXcQ&format_id=137%2B140"/api/proxy directly — it picks the best available quality automatically. Passing format_id just locks in a specific stream.POST /api/extract
Returns title, thumbnail, duration, and every available format for a URL. No bytes downloaded — metadata only.
Request body
Example
curl -X POST https://voiddl.app/api/extract \
-H "Authorization: Bearer vd_xxxxxxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{"url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ"}'Response 200
{
"status": "success",
"platform": "youtube",
"title": "Rick Astley - Never Gonna Give You Up",
"thumbnail": "https://i.ytimg.com/vi/dQw4w9WgXcQ/maxresdefault.jpg",
"duration": 213,
"author": "RickAstleyVEVO",
"views": 1400000000,
"best": {
"format_id": "137+140",
"ext": "mp4",
"height": 1080,
"resolution": "1080p",
"filesize_human": "47.2 MB",
"type": "combined"
},
"formats": [
{ "type": "combined", "ext": "mp4", "height": 1080, "format_id": "137+140", "filesize_human": "47.2 MB" },
{ "type": "combined", "ext": "mp4", "height": 720, "format_id": "136+140", "filesize_human": "22.1 MB" },
{ "type": "audio", "ext": "m4a", "height": 0, "format_id": "140", "filesize_human": "3.1 MB" }
]
}GET /api/proxy
Streams the media file directly. Returns raw bytes with correct Content-Type and Content-Disposition headers. Supports Range requests for seeking.
Query parameters
/api/extract. Skips re-extraction, faster start.Example
# Download best quality (auto-selected) curl -L -o video.mp4 \ -H "Authorization: Bearer vd_xxxxxxxxxxxxxxxxxxxx" \ "https://voiddl.app/api/proxy?url=https%3A%2F%2Fyoutu.be%2FdQw4w9WgXcQ" # Download specific format (fast — no re-extraction) curl -L -o video.mp4 \ -H "Authorization: Bearer vd_xxxxxxxxxxxxxxxxxxxx" \ "https://voiddl.app/api/proxy?url=https%3A%2F%2Fyoutu.be%2FdQw4w9WgXcQ&format_id=137%2B140" # Audio only curl -L -o audio.m4a \ -H "Authorization: Bearer vd_xxxxxxxxxxxxxxxxxxxx" \ "https://voiddl.app/api/proxy?url=https%3A%2F%2Fyoutu.be%2FdQw4w9WgXcQ&audio=1"
Response headers
Content-Type: video/mp4 Content-Disposition: attachment; filename="video.mp4" Accept-Ranges: bytes
POST /api/v1/extract
Legacy alias for /api/extract. Identical request and response. Kept for backwards compatibility — use /api/extract for new integrations.
Python
import os, requests
KEY = os.environ["VOIDDL_KEY"]
URL = "https://www.youtube.com/watch?v=dQw4w9WgXcQ"
# Extract metadata
meta = requests.post(
"https://voiddl.app/api/extract",
headers={"Authorization": f"Bearer {KEY}"},
json={"url": URL},
).json()
print(meta["title"]) # Rick Astley - Never Gonna Give You Up
print(meta["best"]["height"]) # 1080
# Download using format_id (fast path)
params = {
"url": URL,
"format_id": meta["best"]["format_id"],
"filename": "video.mp4",
}
with requests.get(
"https://voiddl.app/api/proxy",
params=params,
headers={"Authorization": f"Bearer {KEY}"},
stream=True,
) as r:
r.raise_for_status()
with open("video.mp4", "wb") as f:
for chunk in r.iter_content(1 << 20):
f.write(chunk)Node.js
import { writeFile } from "node:fs/promises";
const KEY = process.env.VOIDDL_KEY;
const URL = "https://www.youtube.com/watch?v=dQw4w9WgXcQ";
const meta = await fetch("https://voiddl.app/api/extract", {
method: "POST",
headers: {
Authorization: `Bearer ${KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({ url: URL }),
}).then((r) => r.json());
const proxy = new URL("https://voiddl.app/api/proxy");
proxy.searchParams.set("url", URL);
proxy.searchParams.set("format_id", meta.best.format_id);
const file = await fetch(proxy, {
headers: { Authorization: `Bearer ${KEY}` },
});
await writeFile("video.mp4", Buffer.from(await file.arrayBuffer()));
console.log("done →", meta.title);cURL
# Extract and parse with jq
FORMAT_ID=$(curl -s -X POST https://voiddl.app/api/extract \
-H "Authorization: Bearer vd_xxxxxxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{"url":"https://youtu.be/dQw4w9WgXcQ"}' | jq -r '.best.format_id')
# Download that format
curl -L -o video.mp4 \
-H "Authorization: Bearer vd_xxxxxxxxxxxxxxxxxxxx" \
"https://voiddl.app/api/proxy?url=https%3A%2F%2Fyoutu.be%2FdQw4w9WgXcQ&format_id=$FORMAT_ID"Supported platforms
Any URL yt-dlp supports. Common ones:
Rate limits
Per API key, rolling 60-second window:
Rate limit headers on every response:
X-RateLimit-Limit: 30 X-RateLimit-Remaining: 28 X-RateLimit-Reset: 1710000000