YouTube Download API: Pick a Format, Get a Stream

YouTube is the one platform where "give me the video" isn't enough. A single watch URL hides a stack of renditions — 144p up to 4K, plus an audio-only track — and no API can pick one for you without guessing wrong. So the FastSaver API splits YouTube into two honest calls: list the formats, then resolve the one you picked. This post walks the whole flow, including the part most docs skip: what the URL you get back actually is.

step 1 — list formats

curl "https://api.fastsaver.io/v1/youtube/info?url=https://www.youtube.com/watch?v=xyz" \
  -H "X-Api-Key: YOUR_KEY"
{
  "ok": true,
  "title": "desk setup tour",
  "duration": 734,
  "formats": [
    { "type": "video", "format": "2160p", "filesize": 812449102 },
    { "type": "video", "format": "1080p", "filesize": 133956977 },
    { "type": "video", "format": "720p",  "filesize": 61531585 },
    { "type": "audio", "format": "audio", "filesize": 3968982 }
  ]
}

Only formats the upload actually has appear here — an old 480p video lists no 4K, and that's correct behaviour, not a bug. Show the list to your user (the filesizes make an honest UI), or pick programmatically: highest video for archiving, audio for an MP3 feature.

step 2 — resolve your pick

curl -X POST "https://api.fastsaver.io/v1/youtube/download" \
  -H "X-Api-Key: YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "url": "https://www.youtube.com/watch?v=xyz", "format": "720p" }'
{
  "ok": true,
  "filename": "desk-setup-tour-720p.mp4",
  "download_url": "https://api.fastsaver.io/v1/tunnel?id=aXk29fQ7…&fmt=720p"
}

The format string must be one of a fixed set: 144p, 240p, 360p, 480p, 720p, 1080p, 1440p, 2160p (alias 4k) or audio. Anything else is rejected with a 400 before any work happens — so is a format the set allows but this particular video doesn't have, which is why you list first.

what the download_url actually is

It is not a direct CDN file link. It's a tunnel URL on api.fastsaver.io/v1/tunnel, and a GET on it answers with a 307 redirect to the real stream host. Most HTTP clients follow that hop automatically; on the command line you need the flag:

curl -L "https://api.fastsaver.io/v1/tunnel?id=aXk29fQ7…&fmt=720p" -o video.mp4

Two practical consequences. First, resolve just-in-time: call step 2 when the user actually clicks download, use the tunnel URL promptly, and don't store it in a database for tomorrow — treat it as short-lived. Second, the tunnel means you never touch YouTube's CDN yourself: hand the URL to your user's browser, or pipe the redirected response straight through your server. No temp files on your side either way.

audio and mp3

Pass format: "audio" and step 2 resolves the audio track instead of a video rendition — that's the whole MP3 feature, no separate endpoint, no re-encoding on your side. If you're after the non-API version of this, the YouTube to MP3 guide covers it with buttons instead of curl.

shorts and short links

Every YouTube URL shape goes through the same two calls: watch?v= links, youtu.be short links, /shorts/ URLs, even youtube-nocookie.com embeds. A Short is just a regular video with a vertical aspect ratio, so it lists formats like anything else — more on the format in the Shorts guide. Non-YouTube links get a 422 from this endpoint; use the platform's own endpoint instead.

timeouts and large files

A 4K download of a long video is measured in gigabytes, and default HTTP client timeouts are not built for that. Three rules from production:

  • Raise the read timeout on whatever fetches the tunnel URL — the transfer takes as long as the file is big.
  • Stream, never buffer. Write to disk or pipe to the user as bytes arrive. Holding a 2160p file in memory is how workers die.
  • Resolve lazily. Step 1 is cheap; step 2 costs quota. Call it per user click, not for every quality up front.

errors you'll actually see

Failures come back as JSON with a stable machine code and a human message:

{ "error": true, "code": "invalid", "message": "pick a valid format" }
  • invalid (400) — missing or malformed body, a link over 2048 characters, or a format outside the allowed set.
  • unsupported (422) — the URL isn't a YouTube link.
  • unreachable — the video itself couldn't be fetched: deleted, private, or otherwise gone.
  • rate_limited (429) — you hit your limit. The response carries a retry-after header; honour it instead of hammering.
  • server_error (500) — our side. Safe to retry once with backoff.

One more: the download endpoint is POST-only — a GET returns 405. Switch on code in your handler and show message to humans; the codes are stable, the messages aren't a contract.

Auth and key setup live in the getting started guide, ideas for what to ship in what to build with a download API · keys at api.fastsaver.io. One-off download? The web downloader is the same two-step engine with the quality picker as buttons.

Frequently asked questions

Why does YouTube need two API calls when other platforms need one?
Because one watch URL maps to many renditions. /v1/youtube/info lists what exists with filesizes; /v1/youtube/download resolves the one you picked. A TikTok has one canonical file, so it is one call.
What is the tunnel URL the download endpoint returns?
A link on api.fastsaver.io/v1/tunnel that 307-redirects to the actual stream host. Follow the redirect (curl -L; most libraries do it automatically) and use it promptly rather than storing it — it is meant to be resolved just-in-time.
Which format values does the download endpoint accept?
144p, 240p, 360p, 480p, 720p, 1080p, 1440p, 2160p (or its alias 4k) and audio. Anything else is a 400 — and a listed value still fails if that particular video never had the quality, so check the info response first.
How do I get just the audio as MP3?
Pass format: "audio" to the download endpoint. It resolves the audio track through the same tunnel mechanism — no separate endpoint and no re-encoding on your side.
Do YouTube Shorts and youtu.be links work?
Yes. Shorts URLs, youtu.be short links and youtube-nocookie.com embeds all go through the same info-then-download flow as a regular watch URL.