API Documentation

YouTube and Direct Download APIs

YouTube and Direct Download APIs

Authentication Requirements (As Implemented)

  • All /ytapi/* routes require cookie session auth or API key auth and return 403 when missing.
  • Global secondary-session middleware allowlists /ytapi, so secondary sessions can call these endpoints.
  • POST routes below also enforce Content-Type: application/json via requireJson.
  • requestDownload and confirmDirectDownload accept optional folderId; 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 removed and excluded from listJobs.

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 exceeded
  • 500: preview execution failure

Implementation note:

  • Preview tries HEAD first.
  • If upstream does not support/allow HEAD, preview falls back to GET with Range: bytes=0-0 and parses Content-Range for 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:

  • queued
  • downloading
  • uploading
  • finished
  • error

On success, status payload contains final hname and path.