Answers

How do I get a YouTube transcript with timestamps as JSON or SRT?

Short answer

The YouTube transcript endpoint returns every caption line as a segment with start and end in seconds, plus the full text, for $0.004 per video. Keep the JSON as it is, or write the segments out as SRT with a dozen lines of Python; timestamps cost nothing extra.

A podcast clip editor wants every place a guest mentions a product, with a link that opens the video at that second. A plain transcript is not enough; you need when each line was said. YouTube video transcript returns that in the same call as the text.

What the JSON looks like

The transcript sits in data.item of the response:

{
  "video_id": "dQw4w9WgXcQ",
  "lang": "en",
  "text": "We're no strangers to love ...",
  "segments": [
    { "start": 18.64, "end": 21.88, "text": "We're no strangers to love" },
    { "start": 22.64, "end": 26.92, "text": "You know the rules and so do I" }
  ]
}

Times are seconds from the start of the video. Libraries that report duration instead: it is end - start.

From segments to SRT

import os, requests

body = requests.get(
    "https://api.okdata.online/v1/youtube/videos/transcript/get",
    headers={"Authorization": f"Bearer {os.environ['OKDATA_API_KEY']}"},
    params={"id": "dQw4w9WgXcQ", "lang": "en"}, timeout=60,
).json()
segments = body["data"]["item"]["segments"]

def srt_time(sec):
    ms = int(round(sec * 1000))
    return f"{ms // 3_600_000:02}:{ms // 60_000 % 60:02}:{ms // 1000 % 60:02},{ms % 1000:03}"

with open("dQw4w9WgXcQ.srt", "w", encoding="utf-8") as f:
    for n, s in enumerate(segments, 1):
        f.write(f"{n}\n{srt_time(s['start'])} --> {srt_time(s['end'])}\n{s['text']}\n\n")

For WebVTT, start the file with WEBVTT and use a dot instead of the comma before the milliseconds.

https://www.youtube.com/watch?v=dQw4w9WgXcQ&t=18s opens the video at second 18. Round start down and you can put a clickable source next to every quote an AI pulls from the transcript, which makes summaries easy to check.

Price

Job Cost
One video, text plus timings $0.004
A 100-episode back catalogue $0.40
1,000 videos $4.00

Timings come with every transcript. Videos without captions return not_found and are not charged.

Things to know before you ship the file

  • Automatic captions often overlap: a line can end after the next one starts. If a player complains, clip each end to the next start.
  • Lines follow how YouTube split the captions, so they are short and not sentence-aligned. Join segments before quoting a full sentence.
  • The endpoint takes the 11-character ID, not a URL.
  • No styling, positions or speaker labels come back; only text and time.

Other ways to get timed captions

  • yt-dlp with --write-subs --convert-subs srt writes the file directly when it is not blocked on your network.
  • On your own channel, the official Data API downloads captions in SRT through tfmt.
  • Without captions, Whisper produces timestamps from audio you are allowed to use.

Batch work and costs for whole channels are on the video transcript solution page.

Updated