Developer API
Use AIOVideoDL from your own website, app or script: one request returns the download links of a video.
Getting started
Send the address of a video, get back its title, its picture and a download link for every format. 62 sites are supported; the same request works for all of them.
Base address: https://www.aiovideodl.com/api/v1. Every answer is JSON and carries "ok": true or "ok": false.
Get your API key Create a free account, then open Account → API.
Your key
Send your key with every request, in one of three ways. The header is the safest: a key in an address ends up in logs.
| Where | How |
|---|---|
| Header | X-API-Key: YOUR_KEY |
| Header | Authorization: Bearer YOUR_KEY |
| Parameter | ?api_key=YOUR_KEY |
Keep the key on your server. A key in the code of a web page or an app can be read by everybody who opens it.
Requests and answers
GET /info?url=address
One video, picture or sound file with every format the site offers. POST with the same parameter works too.
| Parameter | Needed | Meaning |
|---|---|---|
url | yes | The address of the page, URL-encoded. |
track | no | The id of a sound track (YouTube videos with dubbed sound): the formats then carry that language. |
{
"ok": true,
"url": "https://www.youtube.com/watch?v=aqz-KE-bpKQ",
"platform": "youtube",
"title": "Big Buck Bunny 60fps 4K - Official Blender Foundation Short Film",
"thumbnail": "https://i.ytimg.com/vi/aqz-KE-bpKQ/maxresdefault.jpg",
"duration": 635,
"author": "Blender",
"results_page": "https://www.aiovideodl.com/en/results/0f3a…",
"medias": [
{
"type": "video",
"quality": "1080p60",
"ext": "mp4",
"codec": "avc1",
"size": 162518391,
"size_human": "154.99 MB",
"has_audio": true,
"is_hls": false,
"merged": true,
"url": "https://…",
"download": "https://www.aiovideodl.com/download?sid=0f3a…&m=4&a=17",
"language": null
},
{
"type": "audio",
"quality": "128 kbps",
"ext": "m4a",
"codec": "mp4a",
"size": 10279552,
"size_human": "9.8 MB",
"has_audio": true,
"is_hls": false,
"merged": false,
"url": "https://…",
"download": "https://www.aiovideodl.com/download?sid=0f3a…&m=17",
"language": null
}
]
}
| Field | Meaning |
|---|---|
download | The link to give to your user: the file comes through this site, with a proper file name, and can be resumed. It works for about an hour. |
url | The address at the source. Many sources only answer the server that asked, or need special headers, so prefer download. |
type | video (with sound), audio, video_only or image. |
merged | true: the source keeps picture and sound apart and this site joins them while the file is downloaded. |
size | Bytes, or null when the source does not say. |
results_page | The page of this site that shows the same formats to a person. |
GET /playlist?url=address&limit=number
The entries of a YouTube playlist. Ask /info for each entry you want; the field info of an entry is that request, ready to send.
{
"ok": true,
"platform": "youtube",
"id": "PLBCF2DAC6FFB574DE",
"url": "https://www.youtube.com/playlist?list=PLBCF2DAC6FFB574DE",
"title": "Google Search Stories",
"author": "Google Search Stories",
"count": 1,
"has_more": true,
"items": [
{
"position": 1,
"id": "GvgqDSnpRQM",
"url": "https://www.youtube.com/watch?v=GvgqDSnpRQM",
"title": "Andrew Willis, Skatepark Engineer",
"author": "Google Search Stories",
"duration": 90,
"thumbnail": "https://i.ytimg.com/vi/GvgqDSnpRQM/mqdefault.jpg",
"info": "https://www.aiovideodl.com/api/v1/info?url=https%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3DGvgqDSnpRQM"
}
]
}
GET /platforms
The supported sites with their domains. No key is needed, and the request is not counted.
{
"ok": true,
"count": 62,
"platforms": [
{
"slug": "youtube",
"name": "YouTube",
"type": "video",
"domains": [
"youtube.com",
"youtu.be"
],
"color": "#d82624",
"icon": "https://…/icon.svg",
"page": "https://…/youtube-video-downloader"
}
]
}
GET /me
The key that asks: its limits and what is left of today. Not counted either.
{
"ok": true,
"key": {
"name": "My app",
"prefix": "aio_4f1c2a",
"created_at": "2026-10-10 08:00:00",
"last_used_at": "2026-10-10 09:12:44",
"requests_total": 57
},
"limits": {
"per_minute": 20,
"per_day": 200
},
"today": {
"used": 12,
"remaining": 188
}
}
Errors
An answer that is not a success has a status of 4xx or 5xx, "ok": false, a short error code and a message for people.
{
"ok": false,
"error": "unsupported_site",
"message": "This site is not supported."
}
| Status | error | Meaning |
|---|---|---|
| 401 | unauthorized | No key, or a key that does not exist. |
| 403 | forbidden, api_disabled | The key may not be used from this address, its owner may not use the API, or the API is switched off. |
| 422 | invalid_url, unsupported_site, no_media, not_found, playlist_link | The address is not one the site can read, or nothing downloadable is behind it. |
| 429 | rate_limited, quota_exceeded | Too many requests in a minute, or the day's number is used up. |
| 502 | blocked | The source turned this server away. Try again later. |
| 500 | failed | Something went wrong on this side. |
Limits
| Requests per minute | 20 |
| Requests per day (the day turns at midnight, UTC) | 200 |
Every counted answer carries X-RateLimit-Limit and X-RateLimit-Remaining (per day). After a 429, wait for the number of seconds in Retry-After. The same address asked twice within an hour is answered from memory and is quick.
Examples
cURL
curl -H "X-API-Key: YOUR_KEY" \ "https://www.aiovideodl.com/api/v1/info?url=https://www.youtube.com/watch?v=aqz-KE-bpKQ"
PHP
$ch = curl_init('https://www.aiovideodl.com/api/v1/info?url=' . urlencode('https://www.youtube.com/watch?v=aqz-KE-bpKQ'));
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ['X-API-Key: YOUR_KEY'],
CURLOPT_TIMEOUT => 60,
]);
$data = json_decode(curl_exec($ch), true);
curl_close($ch);
if (!empty($data['ok'])) {
foreach ($data['medias'] as $m) {
echo $m['quality'], ' ', $m['ext'], ': ', $m['download'], PHP_EOL;
}
} else {
echo 'Error: ', $data['message'] ?? 'no answer', PHP_EOL;
}
JavaScript (Node.js 18 or newer)
const api = 'https://www.aiovideodl.com/api/v1/info?url=' + encodeURIComponent('https://www.youtube.com/watch?v=aqz-KE-bpKQ');
const res = await fetch(api, { headers: { 'X-API-Key': process.env.AIO_KEY } });
const data = await res.json();
if (data.ok) {
const best = data.medias.find((m) => m.type === 'video');
console.log(data.title, best.quality, best.download);
} else {
console.error(res.status, data.error, data.message);
}
Python
import requests
r = requests.get(
"https://www.aiovideodl.com/api/v1/info",
params={"url": "https://www.youtube.com/watch?v=aqz-KE-bpKQ"},
headers={"X-API-Key": "YOUR_KEY"},
timeout=60,
)
data = r.json()
if data.get("ok"):
for m in data["medias"]:
print(m["quality"], m["ext"], m["download"])
else:
print(r.status_code, data.get("error"), data.get("message"))