# How do I get a YouTube transcript in a specific language?

> Ask for a YouTube transcript in your preferred language, check which language actually came back, and translate the rest yourself. Price per video and Python code.

Canonical page: https://okdata.online/answers/youtube-transcript-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](/apis/youtube/videos/transcript/get/) 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

```python
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-US` and `en` are the same language for most work).
- On videos with several caption tracks, the `lang` label 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_found` at no charge. There is no speech-to-text step.
- If you come from youtube-transcript-api: its `find_transcript` expects 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](/solutions/transcripts/).

## Endpoints used

- [YouTube video transcript](https://okdata.online/apis/youtube/videos/transcript/get/) `youtube.videos.transcript.get`: $0.004 per call

Updated 2026-11-12
