YouTube and Direct Download APIs
Authentication Requirements (As Implemented)
- All
/ytapi/*routes require cookie session auth or API key auth and return403when missing. - Global secondary-session middleware allowlists
/ytapi, so secondary sessions can call these endpoints. POSTroutes below also enforceContent-Type: application/jsonviarequireJson.requestDownloadandconfirmDirectDownloadaccept optionalfolderId; when secondary scope is configured, this is validated against that subtree.
| Endpoint | Auth Required (as implemented) |
|---|---|
POST /ytapi/requestDownload |
Cookie session or API key auth + application/json |
GET /ytapi/downloadStatus |
Cookie session or API key auth + job owner match |
GET /ytapi/listJobs |
Cookie session or API key auth + job owner match |
POST /ytapi/ackJob |
Cookie session or API key auth + application/json + job owner match |
POST /ytapi/removeJob |
Cookie session or API key auth + application/json + job owner match |
POST /ytapi/previewDirectDownload |
Cookie session or API key auth + application/json |
POST /ytapi/confirmDirectDownload |
Cookie session or API key auth + application/json |
Allowed URL hosts are validated against allowedYTDLP config where applicable.
Request and Response Examples
POST /ytapi/requestDownload
Request headers:
Content-Type: application/json(required)
Request body:
{
"url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
"format": "mp3",
"expiry": "7d",
"hqAudio": true,
"folderId": 123
}
Success response (200):
{ "jobId": "c1a2b3d4e5f67890" }
GET /ytapi/downloadStatus
Request query:
jobId=c1a2b3d4e5f67890
Success response (200):
{
"jobId": "c1a2b3d4e5f67890",
"url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
"type": "ytdlp",
"format": "mp3",
"status": "uploading",
"progress": "Uploading to file.ax...",
"progressPercent": null,
"progressBytes": 0,
"progressTotalBytes": 0,
"hname": null,
"path": null,
"updatedAt": "2026-03-10T00:00:00.000Z"
}
Completion response example:
{
"jobId": "c1a2b3d4e5f67890",
"status": "finished",
"progress": "Finished: https://file.yt/abcde",
"hname": "file.yt",
"path": "abcde"
}
Common failures:
404:{ "error": "Job not found" }403:{ "error": "Unauthorized" }403:{ "error": "Selected folder is outside your allowed scope" }(secondary scope violation)
GET /ytapi/listJobs
Success response (200):
{
"jobs": [
{
"jobId": "f09e8d7c6b5a4321",
"type": "direct",
"url": "https://example.com/bigfile.zip",
"filename": "bigfile.zip",
"status": "downloading",
"progress": "Downloading: 17.1% (1749.47MB / 10240.00MB)",
"progressPercent": 17.1,
"progressBytes": 1834446848,
"progressTotalBytes": 10737418240,
"updatedAt": "2026-03-13T20:00:00.000Z"
}
]
}
Notes:
- Returns jobs persisted for the current owner token where
removed = false. - Active in-memory jobs for the same owner are merged in and returned too.
POST /ytapi/ackJob
Use when client auto-opened a finished file and wants to clear it from history.
Request body:
{ "jobId": "f09e8d7c6b5a4321" }
Success response (200):
{ "ok": true }
POST /ytapi/removeJob
Use when user manually dismisses an entry (X button in UI).
Request body:
{ "jobId": "f09e8d7c6b5a4321" }
Success response (200):
{ "ok": true }
Behavior:
- If the job is still active (
queued/downloading/uploading), server cancels it, stops in-flight work, and deletes tracked temporary files. - Job is then marked
removedand excluded fromlistJobs.
POST /ytapi/previewDirectDownload
Request headers:
Content-Type: application/json(required)
Request body:
{ "url": "https://example.com/bigfile.zip" }
Success response (200):
{
"filename": "bigfile.zip",
"size": 10485760,
"sizeGB": "0.01",
"sizeMB": "10.00",
"sizeKnown": true,
"contentType": "application/zip",
"url": "https://example.com/bigfile.zip",
"userQuotaRemaining": 53687091200,
"userQuotaRemainingGB": "50.00"
}
Common failures:
400: missing URL / upstream HTTP error / file too large / quota exceeded500: preview execution failure
Implementation note:
- Preview tries
HEADfirst. - If upstream does not support/allow
HEAD, preview falls back toGETwithRange: bytes=0-0and parsesContent-Rangefor total file size.
POST /ytapi/confirmDirectDownload
Request headers:
Content-Type: application/json(required)
Request body:
{
"url": "https://example.com/bigfile.zip",
"filename": "bigfile.zip",
"expiry": "7d",
"folderId": 123
}
Success response (200):
{ "jobId": "f09e8d7c6b5a4321" }
Job Lifecycle
Typical status values observed in responses:
queueddownloadinguploadingfinishederror
On success, status payload contains final hname and path.