Skip to content

2026-08-23 · ytapi team

Five ways to get a YouTube transcript in 2026 (Python & JS)

From yt-dlp to the official Data API to a hosted transcript API — working Python and JavaScript for each, plus the trade-offs.

Need YouTube transcripts in your app, agent, or dataset? Here are the five approaches people actually use in 2026, with runnable Python and JavaScript and honest trade-offs.

1. yt-dlp (CLI, free)

The workhorse. Downloads subtitles without downloading the video:

shell
yt-dlp --skip-download --write-auto-subs --sub-langs "en.*" \
  --sub-format vtt "https://youtu.be/VIDEO_ID"

Wrap it from Python or Node with subprocess. You own the binary, the proxy, and the parser.

Trade-offs: you run and update the tool yourself; YouTube blocks datacenter IPs aggressively, so you'll need proxies at any scale; and you're parsing VTT/json3 yourself.

2. youtube-transcript-api (Python) / youtube-transcript (JS)

Python:

python
from youtube_transcript_api import YouTubeTranscriptApi

segments = YouTubeTranscriptApi.fetch("VIDEO_ID", languages=["en"])
for s in segments:
    print(s.start, s.text)

JavaScript (the community youtube-transcript package):

javascript
import { YoutubeTranscript } from "youtube-transcript";

const segments = await YoutubeTranscript.fetchTranscript("VIDEO_ID", {
  lang: "en",
});
for (const s of segments) {
  console.log(s.offset, s.text);
}

Trade-offs: great for prototypes; from a server IP you will hit bot checks ("Sign in to confirm you're not a bot") fast. No SLA, no proxies built in.

3. The official YouTube Data API

The official API gives you metadata (titles, views, channels) — but no transcripts. Useful to pair with any transcript source:

python
import requests
resp = requests.get(
    "https://www.googleapis.com/youtube/v3/videos",
    params={"id": "VIDEO_ID", "part": "snippet,statistics", "key": API_KEY},
).json()
javascript
const url = new URL("https://www.googleapis.com/youtube/v3/videos");
url.searchParams.set("id", VIDEO_ID);
url.searchParams.set("part", "snippet,statistics");
url.searchParams.set("key", API_KEY);
const resp = await fetch(url).then((r) => r.json());

Trade-offs: quota-limited; captions.list only tells you which tracks exist, not their content (and only for your own uploads).

4. Roll your own InnerTube client

YouTube's internal API is well-documented by the open-source community (Invidious, NewPipe). You POST to /youtubei/v1/player and /youtubei/v1/get_transcript with the right client context and parse the JSON.

Trade-offs: this is what we do at ytapi, so we can tell you firsthand: the maintenance cost is the real cost. Clients get deprecated, response shapes change, and IPs get flagged. Budget ongoing engineering, not a one-weekend build.

5. A hosted transcript API (ytapi)

Python:

python
import requests

resp = requests.get(
    "https://api.ytapi.dev/v1/transcripts/VIDEO_ID",
    headers={"Authorization": "Bearer yta_YOUR_KEY"},
    params={"lang": "en"},
)
resp.raise_for_status()
segments = resp.json()["segments"]  # [{start, duration, text}, ...]

JavaScript:

javascript
const res = await fetch(
  "https://api.ytapi.dev/v1/transcripts/VIDEO_ID?lang=en",
  { headers: { Authorization: "Bearer yta_YOUR_KEY" } }
);
if (!res.ok) throw new Error(await res.text());
const { segments } = await res.json();

List languages first (0 credits) if you don't know what the video has:

shell
curl "https://api.ytapi.dev/v1/transcripts/VIDEO_ID/languages" \
  -H "Authorization: Bearer yta_YOUR_KEY"

Trade-offs: it's a paid service (100 free credits to start; you pay only for successful HTTP 200 calls — failures are free). In exchange you get JSON/SRT/VTT output, batch (≤50, billed per success), and an MCP server for AI agents, without owning the scraping problem.

Which one should you pick?

  • One-off, local, free: yt-dlp.
  • Prototype: youtube-transcript-api / youtube-transcript.
  • Production app or agent: a hosted API — the moment transcripts matter to your product, owning IP rotation and YouTube's moving target stops being fun.

If you just want to try one video in the browser, the free extractor does that without an account.

← All posts