Answers
How do I get a YouTube transcript in a specific language?
Short answer
Pass lang (for example en or es) to the YouTube transcript endpoint; it returns that track when the video has one, and the response carries a lang field you can check before storing the text. Each transcript costs $0.004, so check lang before asking again, and translate the segments yourself when the video only has another language.
Say you track 50 Spanish-language cooking channels for a US food brand, and your team reads English. Some of those videos carry an English caption track, most only have Spanish. You want English wherever YouTube has it and a clean signal for the rest, without paying twice per video.
Asking for a language
YouTube video transcript takes id (the 11-character video ID) and an optional lang with a language code such as en, es or ja. Treat lang as a preference, not a promise. Which tracks a video offers is up to the creator and YouTube, so the transcript you get back carries its own lang. Read it every time before you store the text under a language.
A pattern that pays once per video
import os, requests
API = "https://api.okdata.online/v1/youtube/videos/transcript/get"
H = {"Authorization": f"Bearer {os.environ['OKDATA_API_KEY']}"}
def transcript(video_id, want="en"):
body = requests.get(API, headers=H, params={"id": video_id, "lang": want}, timeout=60).json()
if body["code"] == "not_found":
return None # no captions at all; not charged
if body["code"] != "ok":
raise RuntimeError(f"{body['code']}: {body['message']}")
t = body["data"]["item"]
t["needs_translation"] = t["lang"].split("-")[0] != want
return t
t = transcript("VIDEO_ID", want="en")
if t and t["needs_translation"]:
print("Got", t["lang"], "- translate", len(t["segments"]), "segments")
Translate segment by segment, not the whole text, and the start and end timings stay valid for quotes and subtitles.
Cost
| Plan | Calls | Cost |
|---|---|---|
| 50 videos, one language request each | 50 | $0.20 |
| Same 50 videos, a second language asked for every video | 100 | $0.40 |
| 1,000 videos | 1000 | $4.00 |
Every returned transcript is a charged call, even when it came back in a different language than you asked for. That is why the code above asks once and translates locally instead of looping through codes.
Gotchas
- Use the language part of the code when you compare (
en-USandenare the same language for most work). - On videos with several caption tracks, the
langlabel can name the video's first listed track rather than the one you got. When the language decides what happens next, run a language detector on a few segments as a cross-check. - The response does not mark whether a track was uploaded or generated automatically.
- Videos with no captions return
not_foundat no charge. There is no speech-to-text step. - If you come from youtube-transcript-api: its
find_transcriptexpects a list of codes, and translated tracks fail for some videos. Here you send one code and compare.
Other routes
- On your own channel, YouTube Studio and the official Data API can add or download caption tracks in any language you upload.
- For a handful of videos, YouTube's player can show auto-translated captions to a human reader for free.
- When quality matters, a professional translation of the transcript beats any automatic track.
More on batch transcript work is on the video transcript solution page.
Updated