# How to Get YouTube Transcripts in Java

Source: https://transcript-yt.com/blog/youtube-transcript-api-java · Updated 2026-11-09 · TranscriptYT

> Fetch YouTube transcripts in Java with the built-in HttpClient and Jackson: records for the JSON response, SRT and VTT downloads, translation, and error handling.

Java has no maintained library for reading YouTube captions, and scraping YouTube from a server gets blocked. The JDK's HttpClient and one GET request to the TranscriptYT [YouTube Transcript API](https://transcript-yt.com/api) return any public video's transcript with timestamps, from plain Java or Spring.

## Fetch and map a transcript

Create a free key in the [dashboard](https://transcript-yt.com/dashboard/keys) (100 transcripts, no card) and export it as TRANSCRIPTYT_KEY. Add com.fasterxml.jackson.core:jackson-databind to your build.

```
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.net.URI;
import java.net.URLEncoder;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.util.List;

public class Transcripts {
    record Segment(double start, double duration, String text) {}
    record Transcript(String videoId, String title, String language, String source, List<Segment> segments) {}

    static final HttpClient HTTP = HttpClient.newHttpClient();
    static final ObjectMapper JSON = new ObjectMapper()
        .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);

    static Transcript getTranscript(String video) throws Exception {
        String url = "https://transcript-yt.com/v1/transcript?url="
            + URLEncoder.encode(video, StandardCharsets.UTF_8);
        HttpRequest req = HttpRequest.newBuilder(URI.create(url))
            .header("Authorization", "Bearer " + System.getenv("TRANSCRIPTYT_KEY"))
            .timeout(Duration.ofSeconds(120))
            .build();
        HttpResponse<String> res = HTTP.send(req, HttpResponse.BodyHandlers.ofString());
        if (res.statusCode() != 200) {
            var error = JSON.readTree(res.body()).path("error");
            throw new RuntimeException(error.path("code").asText() + ": " + error.path("message").asText());
        }
        return JSON.readValue(res.body(), Transcript.class);
    }

    public static void main(String[] args) throws Exception {
        Transcript t = getTranscript("https://youtu.be/5f3Pn-N6yLc");
        System.out.println(t.title() + " " + t.language() + " " + t.source());
        for (Segment s : t.segments().subList(0, 3)) {
            System.out.printf("%7.1fs  %s%n", s.start(), s.text());
        }
    }
}
```

## Subtitle files and translation

Add format=srt (or vtt, text, csv, md) and the response body is the file itself. Add translate_to with a language code to translate into one of 150+ languages with the timings kept.

```
String url = "https://transcript-yt.com/v1/transcript?url=5f3Pn-N6yLc&format=srt&translate_to=es";
HttpRequest req = HttpRequest.newBuilder(URI.create(url))
    .header("Authorization", "Bearer " + System.getenv("TRANSCRIPTYT_KEY"))
    .build();
HTTP.send(req, HttpResponse.BodyHandlers.ofFile(Path.of("captions.es.srt")));
```

## Errors and retries

BLOCKED, RATE_LIMITED, and UPSTREAM_ERROR are temporary; retry them with exponential backoff. VIDEO_UNAVAILABLE, NO_CAPTIONS, and LANGUAGE_NOT_AVAILABLE are final for that video, and a 402 means you're out of credits. Failed requests are never billed. Every code is in the [docs](https://transcript-yt.com/docs).

## FAQ

### How do I get a YouTube transcript in Java?

Send a GET request to https://transcript-yt.com/v1/transcript with the video URL as the url parameter and your API key in the Authorization header, then map the JSON to a record with Jackson.

### Which Java version do I need?

Java 11+ for java.net.http.HttpClient; the records in this guide need Java 16+. Jackson 2.12+ maps records directly.

### Does it work in Spring Boot?

Yes. Use the same request with RestClient or WebClient, or keep HttpClient in a service class. The key belongs in your application properties or an environment variable.
